{
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
+ u32 dev_state;
+ int i = 0;
+
+ /* Translate PM_SUSPEND_xx states to PCI device states */
+ static u32 state_conversion[] = {
+ [PM_SUSPEND_ON] = 0,
+ [PM_SUSPEND_STANDBY] = 1,
+ [PM_SUSPEND_MEM] = 3,
+ [PM_SUSPEND_DISK] = 3,
+ };
+
+ if (state >= sizeof(state_conversion) / sizeof(state_conversion[1]))
+ return -EINVAL;
+ dev_state = state_conversion[state];
if (drv && drv->suspend)
- return drv->suspend(pci_dev,state);
- return 0;
+ i = drv->suspend(pci_dev, dev_state);
+
+ pci_save_state(pci_dev, pci_dev->saved_config_space);
+ return i;
+}
+
+
+/*
+ * Default resume method for devices that have no driver provided resume,
+ * or not even a driver at all.
+ */
+static void pci_default_resume(struct pci_dev *pci_dev)
+{
+ /* restore the PCI config space */
+ pci_restore_state(pci_dev, pci_dev->saved_config_space);
+ /* if the device was enabled before suspend, reenable */
+ if (pci_dev->is_enabled)
+ pci_enable_device(pci_dev);
+ /* if the device was busmaster before the suspend, make it busmaster again */
+ if (pci_dev->is_busmaster)
+ pci_set_master(pci_dev);
}
static int pci_device_resume(struct device * dev)
if (drv && drv->resume)
drv->resume(pci_dev);
+ else
+ pci_default_resume(pci_dev);
return 0;
}
* pci_register_driver - register a new pci driver
* @drv: the driver structure to register
*
- * Adds the driver structure to the list of registered drivers
- * Returns the number of pci devices which were claimed by the driver
- * during registration. The driver remains registered even if the
- * return value is zero.
+ * Adds the driver structure to the list of registered drivers.
+ * Returns a negative value on error. The driver remains registered
+ * even if no device was claimed during registration.
*/
int
pci_register_driver(struct pci_driver *drv)
.hotplug = pci_hotplug,
.suspend = pci_device_suspend,
.resume = pci_device_resume,
+ .dev_attrs = pci_dev_attrs,
};
static int __init pci_driver_init(void)