aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 427991741cf3..5a14b73cf3a1 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -612,30 +612,51 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
612} 612}
613 613
614/** 614/**
615 * pci_enable_device - Initialize device before it's used by a driver. 615 * __pci_enable_device - Initialize device before it's used by a driver.
616 * @dev: PCI device to be initialized 616 * @dev: PCI device to be initialized
617 * 617 *
618 * Initialize device before it's used by a driver. Ask low-level code 618 * Initialize device before it's used by a driver. Ask low-level code
619 * to enable I/O and memory. Wake up the device if it was suspended. 619 * to enable I/O and memory. Wake up the device if it was suspended.
620 * Beware, this function can fail. 620 * Beware, this function can fail.
621 *
622 * Note this function is a backend and is not supposed to be called by
623 * normal code, use pci_enable_device() instead.
621 */ 624 */
622int 625int
623pci_enable_device(struct pci_dev *dev) 626__pci_enable_device(struct pci_dev *dev)
624{ 627{
625 int err; 628 int err;
626 629
627 if (dev->is_enabled)
628 return 0;
629
630 err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); 630 err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
631 if (err) 631 if (err)
632 return err; 632 return err;
633 pci_fixup_device(pci_fixup_enable, dev); 633 pci_fixup_device(pci_fixup_enable, dev);
634 dev->is_enabled = 1;
635 return 0; 634 return 0;
636} 635}
637 636
638/** 637/**
638 * pci_enable_device - Initialize device before it's used by a driver.
639 * @dev: PCI device to be initialized
640 *
641 * Initialize device before it's used by a driver. Ask low-level code
642 * to enable I/O and memory. Wake up the device if it was suspended.
643 * Beware, this function can fail.
644 *
645 * Note we don't actually enable the device many times if we call
646 * this function repeatedly (we just increment the count).
647 */
648int pci_enable_device(struct pci_dev *dev)
649{
650 int result;
651 if (atomic_add_return(1, &dev->enable_cnt) > 1)
652 return 0; /* already enabled */
653 result = __pci_enable_device(dev);
654 if (result < 0)
655 atomic_dec(&dev->enable_cnt);
656 return result;
657}
658
659/**
639 * pcibios_disable_device - disable arch specific PCI resources for device dev 660 * pcibios_disable_device - disable arch specific PCI resources for device dev
640 * @dev: the PCI device to disable 661 * @dev: the PCI device to disable
641 * 662 *
@@ -651,12 +672,18 @@ void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {}
651 * 672 *
652 * Signal to the system that the PCI device is not in use by the system 673 * Signal to the system that the PCI device is not in use by the system
653 * anymore. This only involves disabling PCI bus-mastering, if active. 674 * anymore. This only involves disabling PCI bus-mastering, if active.
675 *
676 * Note we don't actually disable the device until all callers of
677 * pci_device_enable() have called pci_device_disable().
654 */ 678 */
655void 679void
656pci_disable_device(struct pci_dev *dev) 680pci_disable_device(struct pci_dev *dev)
657{ 681{
658 u16 pci_command; 682 u16 pci_command;
659 683
684 if (atomic_sub_return(1, &dev->enable_cnt) != 0)
685 return;
686
660 if (dev->msi_enabled) 687 if (dev->msi_enabled)
661 disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), 688 disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
662 PCI_CAP_ID_MSI); 689 PCI_CAP_ID_MSI);
@@ -672,7 +699,6 @@ pci_disable_device(struct pci_dev *dev)
672 dev->is_busmaster = 0; 699 dev->is_busmaster = 0;
673 700
674 pcibios_disable_device(dev); 701 pcibios_disable_device(dev);
675 dev->is_enabled = 0;
676} 702}
677 703
678/** 704/**