Message ID | 1365685994-32603-2-git-send-email-lucaskt@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Apr 11, 2013 at 10:13:13AM -0300, Lucas Kannebley Tavares wrote: > On pseries machines the detection for max_bus_speed should be done > through an OpenFirmware property. This patch adds a function to perform this > detection and a hook to perform dynamic adding of the function only for > pseries. The crucial detail you didn't mention is that pcibios_root_bridge_prepare() already exists as a weak function in the PCI code and is called from pci_create_root_bus(). > diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c > index 8bcc9ca..15796b5 100644 > --- a/arch/powerpc/platforms/pseries/setup.c > +++ b/arch/powerpc/platforms/pseries/setup.c > @@ -430,6 +430,8 @@ static void pSeries_machine_kexec(struct kimage *image) > } > #endif > > +int pseries_root_bridge_prepare(struct pci_host_bridge *bridge); > + Don't do that, put it in a header where it belongs. cheers
On Thu, Apr 11, 2013 at 10:13:13AM -0300, Lucas Kannebley Tavares wrote: > On pseries machines the detection for max_bus_speed should be done > through an OpenFirmware property. This patch adds a function to perform this > detection and a hook to perform dynamic adding of the function only for > pseries. This fails to build for me on ppc64_defconfig, with: arch/powerpc/include/asm/machdep.h:111:5: error: 'struct pci_host_bridge' declared inside parameter list [-Werror] Presumably you tested it using some other defconfig? cheers
On 04/15/2013 02:00 AM, Michael Ellerman wrote: > On Thu, Apr 11, 2013 at 10:13:13AM -0300, Lucas Kannebley Tavares wrote: >> On pseries machines the detection for max_bus_speed should be done >> through an OpenFirmware property. This patch adds a function to perform this >> detection and a hook to perform dynamic adding of the function only for >> pseries. > > The crucial detail you didn't mention is that pcibios_root_bridge_prepare() > already exists as a weak function in the PCI code and is called from > pci_create_root_bus(). Adding this comment. > >> diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c >> index 8bcc9ca..15796b5 100644 >> --- a/arch/powerpc/platforms/pseries/setup.c >> +++ b/arch/powerpc/platforms/pseries/setup.c >> @@ -430,6 +430,8 @@ static void pSeries_machine_kexec(struct kimage *image) >> } >> #endif >> >> +int pseries_root_bridge_prepare(struct pci_host_bridge *bridge); >> + > > Don't do that, put it in a header where it belongs. > And done as well. > cheers >
On 04/15/2013 08:42 AM, Michael Ellerman wrote: > On Thu, Apr 11, 2013 at 10:13:13AM -0300, Lucas Kannebley Tavares wrote: >> On pseries machines the detection for max_bus_speed should be done >> through an OpenFirmware property. This patch adds a function to perform this >> detection and a hook to perform dynamic adding of the function only for >> pseries. > > This fails to build for me on ppc64_defconfig, with: > > arch/powerpc/include/asm/machdep.h:111:5: error: 'struct pci_host_bridge' declared inside parameter list [-Werror] > > > Presumably you tested it using some other defconfig? > > cheers > Yes, I tested with another config, I did get warnings, though, so I should've fixed that earlier. Adding a forward declaration to prevent this from even throwing out warnings.
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 3d6b410..8f558bf 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -107,6 +107,8 @@ struct machdep_calls { void (*pcibios_fixup)(void); int (*pci_probe_mode)(struct pci_bus *); void (*pci_irq_fixup)(struct pci_dev *dev); + int (*pcibios_root_bridge_prepare)(struct pci_host_bridge + *bridge); /* To setup PHBs when using automatic OF platform driver for PCI */ int (*pci_setup_phb)(struct pci_controller *host); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index fa12ae4..80986cf 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -844,6 +844,14 @@ int pci_proc_domain(struct pci_bus *bus) return 1; } +int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) +{ + if (ppc_md.pcibios_root_bridge_prepare) + return ppc_md.pcibios_root_bridge_prepare(bridge); + + return 0; +} + /* This header fixup will do the resource fixup for all devices as they are * probed, but not for bridge ranges */ diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index 0b580f4..7f9c956 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -108,3 +108,54 @@ static void fixup_winbond_82c105(struct pci_dev* dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, fixup_winbond_82c105); + +int pseries_root_bridge_prepare(struct pci_host_bridge *bridge) +{ + struct device_node *dn, *pdn; + struct pci_bus *bus; + const uint32_t *pcie_link_speed_stats; + + bus = bridge->bus; + + dn = pcibios_get_phb_of_node(bus); + if (!dn) + return 0; + + for (pdn = dn; pdn != NULL; pdn = pdn->parent) { + pcie_link_speed_stats = (const uint32_t *) of_get_property(dn, + "ibm,pcie-link-speed-stats", NULL); + if (pcie_link_speed_stats) + break; + } + + if (!pcie_link_speed_stats) { + pr_err("no ibm,pcie-link-speed-stats property\n"); + return 0; + } + + switch (pcie_link_speed_stats[0]) { + case 0x01: + bus->max_bus_speed = PCIE_SPEED_2_5GT; + break; + case 0x02: + bus->max_bus_speed = PCIE_SPEED_5_0GT; + break; + default: + bus->max_bus_speed = PCI_SPEED_UNKNOWN; + break; + } + + switch (pcie_link_speed_stats[1]) { + case 0x01: + bus->cur_bus_speed = PCIE_SPEED_2_5GT; + break; + case 0x02: + bus->cur_bus_speed = PCIE_SPEED_5_0GT; + break; + default: + bus->cur_bus_speed = PCI_SPEED_UNKNOWN; + break; + } + + return 0; +} diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 8bcc9ca..15796b5 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -430,6 +430,8 @@ static void pSeries_machine_kexec(struct kimage *image) } #endif +int pseries_root_bridge_prepare(struct pci_host_bridge *bridge); + static void __init pSeries_setup_arch(void) { panic_timeout = 10; @@ -466,6 +468,8 @@ static void __init pSeries_setup_arch(void) else ppc_md.enable_pmcs = power4_enable_pmcs; + ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare; + if (firmware_has_feature(FW_FEATURE_SET_MODE)) { long rc; if ((rc = pSeries_enable_reloc_on_exc()) != H_SUCCESS) {
On pseries machines the detection for max_bus_speed should be done through an OpenFirmware property. This patch adds a function to perform this detection and a hook to perform dynamic adding of the function only for pseries. Signed-off-by: Lucas Kannebley Tavares <lucaskt@linux.vnet.ibm.com> --- arch/powerpc/include/asm/machdep.h | 2 + arch/powerpc/kernel/pci-common.c | 8 +++++ arch/powerpc/platforms/pseries/pci.c | 51 ++++++++++++++++++++++++++++++++ arch/powerpc/platforms/pseries/setup.c | 4 ++ 4 files changed, 65 insertions(+), 0 deletions(-)