diff options
author | Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> | 2006-12-18 10:30:00 +0900 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-07 15:50:03 -0800 |
commit | 38cc13022ed3cea949722d5a6f49025da82c9fd0 (patch) | |
tree | 5d6051a294f70dca2fdb86b1966cb3a5945fdfb8 | |
parent | 9fb625c3cc3731097a142ecae79a0369fb854c2d (diff) | |
download | linux-38cc13022ed3cea949722d5a6f49025da82c9fd0.tar.bz2 |
PCI : add extremely specialized __pci_reenable_device for default resume
Original patch was posted as "PCI : Move pci_fixup_device and is_enabled".
This 3 of 3 patches does:
- add __pci_reenable_device
(recover former change of 1st patch)
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Cc: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/pci/pci-driver.c | 3 | ||||
-rw-r--r-- | drivers/pci/pci.c | 41 | ||||
-rw-r--r-- | drivers/pci/pci.h | 1 |
3 files changed, 34 insertions, 11 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 1ec546d3d53c..dd2da9b6b119 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -324,8 +324,7 @@ static int pci_default_resume(struct pci_dev *pci_dev) /* restore the PCI config space */ pci_restore_state(pci_dev); /* if the device was enabled before suspend, reenable */ - if (atomic_read(&pci_dev->enable_cnt)) - retval = pci_enable_device(pci_dev); + retval = __pci_reenable_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); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 212acd2e1a84..287b685aaa5c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -676,6 +676,36 @@ pci_restore_state(struct pci_dev *dev) return 0; } +static int do_pci_enable_device(struct pci_dev *dev, int bars) +{ + int err; + + err = pci_set_power_state(dev, PCI_D0); + if (err < 0 && err != -EIO) + return err; + err = pcibios_enable_device(dev, bars); + if (err < 0) + return err; + pci_fixup_device(pci_fixup_enable, dev); + + return 0; +} + +/** + * __pci_reenable_device - Resume abandoned device + * @dev: PCI device to be resumed + * + * Note this function is a backend of pci_default_resume and is not supposed + * to be called by normal code, write proper resume handler and use it instead. + */ +int +__pci_reenable_device(struct pci_dev *dev) +{ + if (atomic_read(&dev->enable_cnt)) + return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1); + return 0; +} + /** * pci_enable_device_bars - Initialize some of a device for use * @dev: PCI device to be initialized @@ -693,16 +723,9 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) if (atomic_add_return(1, &dev->enable_cnt) > 1) return 0; /* already enabled */ - err = pci_set_power_state(dev, PCI_D0); - if (err < 0 && err != -EIO) - goto err_out; - err = pcibios_enable_device(dev, bars); + err = do_pci_enable_device(dev, bars); if (err < 0) - goto err_out; - pci_fixup_device(pci_fixup_enable, dev); - -err_out: - atomic_dec(&dev->enable_cnt); + atomic_dec(&dev->enable_cnt); return err; } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 6bf327db5c5e..783e81f81f58 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -1,5 +1,6 @@ /* Functions internal to the PCI core code */ +extern int __must_check __pci_reenable_device(struct pci_dev *); extern int pci_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); |