aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-03-01 13:10:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-03-01 13:10:16 -0500
commitb286cedd473006b33d5ae076afac509e6b2c3bf4 (patch)
treef45cbb0337238771d6ebe2220f9d5b4f02771903 /drivers/pci
parent522214d9be9c9f00f34ed89cb95e901b7ac31c59 (diff)
parent9f3768e02335ddd6ebe1d85d5cb3a68ee6264004 (diff)
Merge tag 'powerpc-4.11-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull more powerpc updates from Michael Ellerman: "Highlights include: - an update of the disassembly code used by xmon to the latest versions in binutils. We've received permission from all the authors of the relevant binutils changes to relicense their changes to the relevant files from GPLv3 to GPLv2, for inclusion in Linux. Thanks to Peter Bergner for doing the leg work to get permission from everyone. - addition of the "architected" Power9 CPU table entry, allowing us to boot in Power9 architected mode under a hypervisor. - updates to the Power9 PMU code. - implementation of clear_bit_unlock_is_negative_byte() to optimise unlock_page(). - Freescale updates from Scott: "Highlights include 8xx breakpoints and perf, t1042rdb display support, and board updates." Thanks to: Al Viro, Andrew Donnellan, Aneesh Kumar K.V, Balbir Singh, Douglas Miller, Frédéric Weisbecker, Gavin Shan, Madhavan Srinivasan, Michael Roth, Nathan Fontenot, Naveen N. Rao, Nicholas Piggin, Peter Bergner, Paul E. McKenney, Rashmica Gupta, Russell Currey, Sahil Mehta, Stewart Smith" * tag 'powerpc-4.11-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (48 commits) powerpc: Remove leftover cputime_to_nsecs call causing build error powerpc/mm/hash: Always clear UPRT and Host Radix bits when setting up CPU powerpc/optprobes: Fix TOC handling in optprobes trampoline powerpc/pseries: Advertise Hot Plug Event support to firmware cxl: fix nested locking hang during EEH hotplug powerpc/xmon: Dump memory in CPU endian format powerpc/pseries: Revert 'Auto-online hotplugged memory' powerpc/powernv: Make PCI non-optional powerpc/64: Implement clear_bit_unlock_is_negative_byte() powerpc/powernv: Remove unused variable in pnv_pci_sriov_disable() powerpc/kernel: Remove error message in pcibios_setup_phb_resources() powerpc/mm: Fix typo in set_pte_at() pci/hotplug/pnv-php: Disable MSI and PCI device properly pci/hotplug/pnv-php: Disable surprise hotplug capability on conflicts pci/hotplug/pnv-php: Remove WARN_ON() in pnv_php_put_slot() powerpc: Add POWER9 architected mode to cputable powerpc/perf: use is_kernel_addr macro in perf_get_misc_flags() powerpc/perf: Avoid FAB_*_MATCH checks for power9 powerpc/perf: Add restrictions to PMC5 in power9 DD1 powerpc/perf: Use Instruction Counter value ...
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/pnv_php.c81
1 files changed, 64 insertions, 17 deletions
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
index d2961ef39a3a..7c203198b582 100644
--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -35,9 +35,11 @@ static void pnv_php_register(struct device_node *dn);
35static void pnv_php_unregister_one(struct device_node *dn); 35static void pnv_php_unregister_one(struct device_node *dn);
36static void pnv_php_unregister(struct device_node *dn); 36static void pnv_php_unregister(struct device_node *dn);
37 37
38static void pnv_php_disable_irq(struct pnv_php_slot *php_slot) 38static void pnv_php_disable_irq(struct pnv_php_slot *php_slot,
39 bool disable_device)
39{ 40{
40 struct pci_dev *pdev = php_slot->pdev; 41 struct pci_dev *pdev = php_slot->pdev;
42 int irq = php_slot->irq;
41 u16 ctrl; 43 u16 ctrl;
42 44
43 if (php_slot->irq > 0) { 45 if (php_slot->irq > 0) {
@@ -56,10 +58,14 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot)
56 php_slot->wq = NULL; 58 php_slot->wq = NULL;
57 } 59 }
58 60
59 if (pdev->msix_enabled) 61 if (disable_device || irq > 0) {
60 pci_disable_msix(pdev); 62 if (pdev->msix_enabled)
61 else if (pdev->msi_enabled) 63 pci_disable_msix(pdev);
62 pci_disable_msi(pdev); 64 else if (pdev->msi_enabled)
65 pci_disable_msi(pdev);
66
67 pci_disable_device(pdev);
68 }
63} 69}
64 70
65static void pnv_php_free_slot(struct kref *kref) 71static void pnv_php_free_slot(struct kref *kref)
@@ -68,7 +74,7 @@ static void pnv_php_free_slot(struct kref *kref)
68 struct pnv_php_slot, kref); 74 struct pnv_php_slot, kref);
69 75
70 WARN_ON(!list_empty(&php_slot->children)); 76 WARN_ON(!list_empty(&php_slot->children));
71 pnv_php_disable_irq(php_slot); 77 pnv_php_disable_irq(php_slot, false);
72 kfree(php_slot->name); 78 kfree(php_slot->name);
73 kfree(php_slot); 79 kfree(php_slot);
74} 80}
@@ -76,7 +82,7 @@ static void pnv_php_free_slot(struct kref *kref)
76static inline void pnv_php_put_slot(struct pnv_php_slot *php_slot) 82static inline void pnv_php_put_slot(struct pnv_php_slot *php_slot)
77{ 83{
78 84
79 if (WARN_ON(!php_slot)) 85 if (!php_slot)
80 return; 86 return;
81 87
82 kref_put(&php_slot->kref, pnv_php_free_slot); 88 kref_put(&php_slot->kref, pnv_php_free_slot);
@@ -430,9 +436,21 @@ static int pnv_php_enable(struct pnv_php_slot *php_slot, bool rescan)
430 if (ret) 436 if (ret)
431 return ret; 437 return ret;
432 438
433 /* Proceed if there have nothing behind the slot */ 439 /*
434 if (presence == OPAL_PCI_SLOT_EMPTY) 440 * Proceed if there have nothing behind the slot. However,
441 * we should leave the slot in registered state at the
442 * beginning. Otherwise, the PCI devices inserted afterwards
443 * won't be probed and populated.
444 */
445 if (presence == OPAL_PCI_SLOT_EMPTY) {
446 if (!php_slot->power_state_check) {
447 php_slot->power_state_check = true;
448
449 return 0;
450 }
451
435 goto scan; 452 goto scan;
453 }
436 454
437 /* 455 /*
438 * If the power supply to the slot is off, we can't detect 456 * If the power supply to the slot is off, we can't detect
@@ -705,10 +723,15 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
705 if (sts & PCI_EXP_SLTSTA_DLLSC) { 723 if (sts & PCI_EXP_SLTSTA_DLLSC) {
706 pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lsts); 724 pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lsts);
707 added = !!(lsts & PCI_EXP_LNKSTA_DLLLA); 725 added = !!(lsts & PCI_EXP_LNKSTA_DLLLA);
708 } else if (sts & PCI_EXP_SLTSTA_PDC) { 726 } else if (!(php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) &&
727 (sts & PCI_EXP_SLTSTA_PDC)) {
709 ret = pnv_pci_get_presence_state(php_slot->id, &presence); 728 ret = pnv_pci_get_presence_state(php_slot->id, &presence);
710 if (!ret) 729 if (ret) {
730 dev_warn(&pdev->dev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
731 php_slot->name, ret, sts);
711 return IRQ_HANDLED; 732 return IRQ_HANDLED;
733 }
734
712 added = !!(presence == OPAL_PCI_SLOT_PRESENT); 735 added = !!(presence == OPAL_PCI_SLOT_PRESENT);
713 } else { 736 } else {
714 return IRQ_NONE; 737 return IRQ_NONE;
@@ -752,6 +775,7 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
752static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq) 775static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
753{ 776{
754 struct pci_dev *pdev = php_slot->pdev; 777 struct pci_dev *pdev = php_slot->pdev;
778 u32 broken_pdc = 0;
755 u16 sts, ctrl; 779 u16 sts, ctrl;
756 int ret; 780 int ret;
757 781
@@ -759,29 +783,44 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
759 php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name); 783 php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name);
760 if (!php_slot->wq) { 784 if (!php_slot->wq) {
761 dev_warn(&pdev->dev, "Cannot alloc workqueue\n"); 785 dev_warn(&pdev->dev, "Cannot alloc workqueue\n");
762 pnv_php_disable_irq(php_slot); 786 pnv_php_disable_irq(php_slot, true);
763 return; 787 return;
764 } 788 }
765 789
790 /* Check PDC (Presence Detection Change) is broken or not */
791 ret = of_property_read_u32(php_slot->dn, "ibm,slot-broken-pdc",
792 &broken_pdc);
793 if (!ret && broken_pdc)
794 php_slot->flags |= PNV_PHP_FLAG_BROKEN_PDC;
795
766 /* Clear pending interrupts */ 796 /* Clear pending interrupts */
767 pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &sts); 797 pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &sts);
768 sts |= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC); 798 if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC)
799 sts |= PCI_EXP_SLTSTA_DLLSC;
800 else
801 sts |= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
769 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, sts); 802 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, sts);
770 803
771 /* Request the interrupt */ 804 /* Request the interrupt */
772 ret = request_irq(irq, pnv_php_interrupt, IRQF_SHARED, 805 ret = request_irq(irq, pnv_php_interrupt, IRQF_SHARED,
773 php_slot->name, php_slot); 806 php_slot->name, php_slot);
774 if (ret) { 807 if (ret) {
775 pnv_php_disable_irq(php_slot); 808 pnv_php_disable_irq(php_slot, true);
776 dev_warn(&pdev->dev, "Error %d enabling IRQ %d\n", ret, irq); 809 dev_warn(&pdev->dev, "Error %d enabling IRQ %d\n", ret, irq);
777 return; 810 return;
778 } 811 }
779 812
780 /* Enable the interrupts */ 813 /* Enable the interrupts */
781 pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &ctrl); 814 pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &ctrl);
782 ctrl |= (PCI_EXP_SLTCTL_HPIE | 815 if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) {
783 PCI_EXP_SLTCTL_PDCE | 816 ctrl &= ~PCI_EXP_SLTCTL_PDCE;
784 PCI_EXP_SLTCTL_DLLSCE); 817 ctrl |= (PCI_EXP_SLTCTL_HPIE |
818 PCI_EXP_SLTCTL_DLLSCE);
819 } else {
820 ctrl |= (PCI_EXP_SLTCTL_HPIE |
821 PCI_EXP_SLTCTL_PDCE |
822 PCI_EXP_SLTCTL_DLLSCE);
823 }
785 pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, ctrl); 824 pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, ctrl);
786 825
787 /* The interrupt is initialized successfully when @irq is valid */ 826 /* The interrupt is initialized successfully when @irq is valid */
@@ -793,6 +832,14 @@ static void pnv_php_enable_irq(struct pnv_php_slot *php_slot)
793 struct pci_dev *pdev = php_slot->pdev; 832 struct pci_dev *pdev = php_slot->pdev;
794 int irq, ret; 833 int irq, ret;
795 834
835 /*
836 * The MSI/MSIx interrupt might have been occupied by other
837 * drivers. Don't populate the surprise hotplug capability
838 * in that case.
839 */
840 if (pci_dev_msi_enabled(pdev))
841 return;
842
796 ret = pci_enable_device(pdev); 843 ret = pci_enable_device(pdev);
797 if (ret) { 844 if (ret) {
798 dev_warn(&pdev->dev, "Error %d enabling device\n", ret); 845 dev_warn(&pdev->dev, "Error %d enabling device\n", ret);