#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/pcieport_if.h>
#include "portdrv.h"
"%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n",
__FUNCTION__, dev->device, dev->vendor);
}
- if (pcie_port_device_register(dev))
+ if (pcie_port_device_register(dev)) {
+ pci_disable_device(dev);
return -ENOMEM;
+ }
return 0;
}
static void pcie_portdrv_remove (struct pci_dev *dev)
{
pcie_port_device_remove(dev);
+ kfree(pci_get_drvdata(dev));
}
#ifdef CONFIG_PM
-static int pcie_portdrv_suspend (struct pci_dev *dev, u32 state)
+static int pcie_portdrv_save_config(struct pci_dev *dev)
+{
+ return pci_save_state(dev);
+}
+
+static int pcie_portdrv_restore_config(struct pci_dev *dev)
+{
+ int retval;
+
+ pci_restore_state(dev);
+ retval = pci_enable_device(dev);
+ if (retval)
+ return retval;
+ pci_set_master(dev);
+ return 0;
+}
+
+static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state)
{
- return pcie_port_device_suspend(dev, state);
+ int ret = pcie_port_device_suspend(dev, state);
+
+ if (!ret)
+ ret = pcie_portdrv_save_config(dev);
+ return ret;
}
static int pcie_portdrv_resume (struct pci_dev *dev)
{
+ pcie_portdrv_restore_config(dev);
return pcie_port_device_resume(dev);
}
#endif