PCI : add extremely specialized __pci_reenable_device for default resume
authorHidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Mon, 18 Dec 2006 01:30:00 +0000 (10:30 +0900)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 7 Feb 2007 23:50:03 +0000 (15:50 -0800)
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>
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/pci.h

index 1ec546d3d53c08c2f8c3179d8b3db740ed0a0371..dd2da9b6b11950eff56604aace119d8216d6789d 100644 (file)
@@ -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);
index 212acd2e1a842c16c82d937db66e2768886cd686..287b685aaa5c5e4015d6643a091af85fb810ca4a 100644 (file)
@@ -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;
 }
 
index 6bf327db5c5e70fd39d62f060ca8d5cbd95da1de..783e81f81f58a849b31dc3003e90b18a35c6936a 100644 (file)
@@ -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);