forked from luck/tmp_suning_uos_patched
powerpc/pseries: Perform proper max_bus_speed detection
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 is done by overwriting the weak pcibios_root_bridge_prepare function which is called by pci_create_root_bus(). From: Lucas Kannebley Tavares <lucaskt@linux.vnet.ibm.com> Signed-off-by: Kleber Sacilotto de Souza <klebers@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
e61133dda4
commit
d82fb31abc
|
@ -29,6 +29,7 @@ struct rtc_time;
|
|||
struct file;
|
||||
struct pci_controller;
|
||||
struct kimage;
|
||||
struct pci_host_bridge;
|
||||
|
||||
struct machdep_calls {
|
||||
char *name;
|
||||
|
@ -108,6 +109,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);
|
||||
|
|
|
@ -845,6 +845,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
|
||||
*/
|
||||
|
|
|
@ -108,3 +108,56 @@ 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 = of_get_next_parent(pdn)) {
|
||||
pcie_link_speed_stats = (const uint32_t *) of_get_property(pdn,
|
||||
"ibm,pcie-link-speed-stats", NULL);
|
||||
if (pcie_link_speed_stats)
|
||||
break;
|
||||
}
|
||||
|
||||
of_node_put(pdn);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -63,4 +63,8 @@ extern int dlpar_detach_node(struct device_node *);
|
|||
/* Snooze Delay, pseries_idle */
|
||||
DECLARE_PER_CPU(long, smt_snooze_delay);
|
||||
|
||||
/* PCI root bridge prepare function override for pseries */
|
||||
struct pci_host_bridge;
|
||||
int pseries_root_bridge_prepare(struct pci_host_bridge *bridge);
|
||||
|
||||
#endif /* _PSERIES_PSERIES_H */
|
||||
|
|
|
@ -466,6 +466,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) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user