X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fpci%2Fpci-driver.c;h=64195d6d6828f44a4e68086c66bd20c7edb7a1d2;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=4c7e1695d2111032f5cfee8740b74fac7e1168f8;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 4c7e1695d..64195d6d6 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -299,10 +299,43 @@ static int pci_device_suspend(struct device * dev, u32 state) { 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) @@ -312,6 +345,8 @@ static int pci_device_resume(struct device * dev) if (drv && drv->resume) drv->resume(pci_dev); + else + pci_default_resume(pci_dev); return 0; } @@ -368,10 +403,9 @@ pci_populate_driver_dir(struct pci_driver *drv) * 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) @@ -517,6 +551,7 @@ struct bus_type pci_bus_type = { .hotplug = pci_hotplug, .suspend = pci_device_suspend, .resume = pci_device_resume, + .dev_attrs = pci_dev_attrs, }; static int __init pci_driver_init(void)