aboutsummaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorHidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>2006-12-18 10:30:00 +0900
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 15:50:03 -0800
commit38cc13022ed3cea949722d5a6f49025da82c9fd0 (patch)
tree5d6051a294f70dca2fdb86b1966cb3a5945fdfb8 /drivers/pci
parent9fb625c3cc3731097a142ecae79a0369fb854c2d (diff)
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>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-driver.c3
-rw-r--r--drivers/pci/pci.c41
-rw-r--r--drivers/pci/pci.h1
3 files changed, 34 insertions, 11 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 1ec546d3d53..dd2da9b6b11 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 212acd2e1a8..287b685aaa5 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 6bf327db5c5..783e81f81f5 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);