diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2014-06-11 04:26:44 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-06-11 05:12:23 -0400 |
commit | 357b2f3dd9b7e220ddbaef5bcc108f0359dc0fcf (patch) | |
tree | 722fdbf7ec1406f437f5f4bb2c7073c4fb629642 /arch/powerpc/kernel/eeh_pe.c | |
parent | d4e58e5928f8c6c49228451dd03e0714cbab299a (diff) |
powerpc/eeh: Dump PE location code
As Ben suggested, it's meaningful to dump PE's location code
for site engineers when hitting EEH errors. The patch introduces
function eeh_pe_loc_get() to retireve the location code from
dev-tree so that we can output it when hitting EEH errors.
If primary PE bus is root bus, the PHB's dev-node would be tried
prior to root port's dev-node. Otherwise, the upstream bridge's
dev-node of the primary PE bus will be check for the location code
directly.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/eeh_pe.c')
-rw-r--r-- | arch/powerpc/kernel/eeh_pe.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 995c2a284630..fbd01eba4473 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c | |||
@@ -792,6 +792,66 @@ void eeh_pe_restore_bars(struct eeh_pe *pe) | |||
792 | } | 792 | } |
793 | 793 | ||
794 | /** | 794 | /** |
795 | * eeh_pe_loc_get - Retrieve location code binding to the given PE | ||
796 | * @pe: EEH PE | ||
797 | * | ||
798 | * Retrieve the location code of the given PE. If the primary PE bus | ||
799 | * is root bus, we will grab location code from PHB device tree node | ||
800 | * or root port. Otherwise, the upstream bridge's device tree node | ||
801 | * of the primary PE bus will be checked for the location code. | ||
802 | */ | ||
803 | const char *eeh_pe_loc_get(struct eeh_pe *pe) | ||
804 | { | ||
805 | struct pci_controller *hose; | ||
806 | struct pci_bus *bus = eeh_pe_bus_get(pe); | ||
807 | struct pci_dev *pdev; | ||
808 | struct device_node *dn; | ||
809 | const char *loc; | ||
810 | |||
811 | if (!bus) | ||
812 | return "N/A"; | ||
813 | |||
814 | /* PHB PE or root PE ? */ | ||
815 | if (pci_is_root_bus(bus)) { | ||
816 | hose = pci_bus_to_host(bus); | ||
817 | loc = of_get_property(hose->dn, | ||
818 | "ibm,loc-code", NULL); | ||
819 | if (loc) | ||
820 | return loc; | ||
821 | loc = of_get_property(hose->dn, | ||
822 | "ibm,io-base-loc-code", NULL); | ||
823 | if (loc) | ||
824 | return loc; | ||
825 | |||
826 | pdev = pci_get_slot(bus, 0x0); | ||
827 | } else { | ||
828 | pdev = bus->self; | ||
829 | } | ||
830 | |||
831 | if (!pdev) { | ||
832 | loc = "N/A"; | ||
833 | goto out; | ||
834 | } | ||
835 | |||
836 | dn = pci_device_to_OF_node(pdev); | ||
837 | if (!dn) { | ||
838 | loc = "N/A"; | ||
839 | goto out; | ||
840 | } | ||
841 | |||
842 | loc = of_get_property(dn, "ibm,loc-code", NULL); | ||
843 | if (!loc) | ||
844 | loc = of_get_property(dn, "ibm,slot-location-code", NULL); | ||
845 | if (!loc) | ||
846 | loc = "N/A"; | ||
847 | |||
848 | out: | ||
849 | if (pci_is_root_bus(bus) && pdev) | ||
850 | pci_dev_put(pdev); | ||
851 | return loc; | ||
852 | } | ||
853 | |||
854 | /** | ||
795 | * eeh_pe_bus_get - Retrieve PCI bus according to the given PE | 855 | * eeh_pe_bus_get - Retrieve PCI bus according to the given PE |
796 | * @pe: EEH PE | 856 | * @pe: EEH PE |
797 | * | 857 | * |