aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 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)
324 /* restore the PCI config space */ 324 /* restore the PCI config space */
325 pci_restore_state(pci_dev); 325 pci_restore_state(pci_dev);
326 /* if the device was enabled before suspend, reenable */ 326 /* if the device was enabled before suspend, reenable */
327 if (atomic_read(&pci_dev->enable_cnt)) 327 retval = __pci_reenable_device(pci_dev);
328 retval = pci_enable_device(pci_dev);
329 /* if the device was busmaster before the suspend, make it busmaster again */ 328 /* if the device was busmaster before the suspend, make it busmaster again */
330 if (pci_dev->is_busmaster) 329 if (pci_dev->is_busmaster)
331 pci_set_master(pci_dev); 330 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)
676 return 0; 676 return 0;
677} 677}
678 678
679static int do_pci_enable_device(struct pci_dev *dev, int bars)
680{
681 int err;
682
683 err = pci_set_power_state(dev, PCI_D0);
684 if (err < 0 && err != -EIO)
685 return err;
686 err = pcibios_enable_device(dev, bars);
687 if (err < 0)
688 return err;
689 pci_fixup_device(pci_fixup_enable, dev);
690
691 return 0;
692}
693
694/**
695 * __pci_reenable_device - Resume abandoned device
696 * @dev: PCI device to be resumed
697 *
698 * Note this function is a backend of pci_default_resume and is not supposed
699 * to be called by normal code, write proper resume handler and use it instead.
700 */
701int
702__pci_reenable_device(struct pci_dev *dev)
703{
704 if (atomic_read(&dev->enable_cnt))
705 return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
706 return 0;
707}
708
679/** 709/**
680 * pci_enable_device_bars - Initialize some of a device for use 710 * pci_enable_device_bars - Initialize some of a device for use
681 * @dev: PCI device to be initialized 711 * @dev: PCI device to be initialized
@@ -693,16 +723,9 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
693 if (atomic_add_return(1, &dev->enable_cnt) > 1) 723 if (atomic_add_return(1, &dev->enable_cnt) > 1)
694 return 0; /* already enabled */ 724 return 0; /* already enabled */
695 725
696 err = pci_set_power_state(dev, PCI_D0); 726 err = do_pci_enable_device(dev, bars);
697 if (err < 0 && err != -EIO)
698 goto err_out;
699 err = pcibios_enable_device(dev, bars);
700 if (err < 0) 727 if (err < 0)
701 goto err_out; 728 atomic_dec(&dev->enable_cnt);
702 pci_fixup_device(pci_fixup_enable, dev);
703
704err_out:
705 atomic_dec(&dev->enable_cnt);
706 return err; 729 return err;
707} 730}
708 731
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 @@
1/* Functions internal to the PCI core code */ 1/* Functions internal to the PCI core code */
2 2
3extern int __must_check __pci_reenable_device(struct pci_dev *);
3extern int pci_uevent(struct device *dev, char **envp, int num_envp, 4extern int pci_uevent(struct device *dev, char **envp, int num_envp,
4 char *buffer, int buffer_size); 5 char *buffer, int buffer_size);
5extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); 6extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);