|
@@ -15,10 +15,11 @@
|
|
|
#include <linux/pci.h>
|
|
|
#include <linux/init.h>
|
|
|
#include <asm/pci_x86.h>
|
|
|
+#include <asm/pci-direct.h>
|
|
|
|
|
|
#include "bus_numa.h"
|
|
|
|
|
|
-static void __devinit cnb20le_res(struct pci_dev *dev)
|
|
|
+static void __init cnb20le_res(u8 bus, u8 slot, u8 func)
|
|
|
{
|
|
|
struct pci_root_info *info;
|
|
|
struct resource res;
|
|
@@ -26,21 +27,12 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
|
|
|
u8 fbus, lbus;
|
|
|
int i;
|
|
|
|
|
|
-#ifdef CONFIG_ACPI
|
|
|
- /*
|
|
|
- * We should get host bridge information from ACPI unless the BIOS
|
|
|
- * doesn't support it.
|
|
|
- */
|
|
|
- if (acpi_os_get_root_pointer())
|
|
|
- return;
|
|
|
-#endif
|
|
|
-
|
|
|
info = &pci_root_info[pci_root_num];
|
|
|
pci_root_num++;
|
|
|
|
|
|
/* read the PCI bus numbers */
|
|
|
- pci_read_config_byte(dev, 0x44, &fbus);
|
|
|
- pci_read_config_byte(dev, 0x45, &lbus);
|
|
|
+ fbus = read_pci_config_byte(bus, slot, func, 0x44);
|
|
|
+ lbus = read_pci_config_byte(bus, slot, func, 0x45);
|
|
|
info->bus_min = fbus;
|
|
|
info->bus_max = lbus;
|
|
|
|
|
@@ -59,8 +51,8 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
|
|
|
}
|
|
|
|
|
|
/* read the non-prefetchable memory window */
|
|
|
- pci_read_config_word(dev, 0xc0, &word1);
|
|
|
- pci_read_config_word(dev, 0xc2, &word2);
|
|
|
+ word1 = read_pci_config_16(bus, slot, func, 0xc0);
|
|
|
+ word2 = read_pci_config_16(bus, slot, func, 0xc2);
|
|
|
if (word1 != word2) {
|
|
|
res.start = (word1 << 16) | 0x0000;
|
|
|
res.end = (word2 << 16) | 0xffff;
|
|
@@ -69,8 +61,8 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
|
|
|
}
|
|
|
|
|
|
/* read the prefetchable memory window */
|
|
|
- pci_read_config_word(dev, 0xc4, &word1);
|
|
|
- pci_read_config_word(dev, 0xc6, &word2);
|
|
|
+ word1 = read_pci_config_16(bus, slot, func, 0xc4);
|
|
|
+ word2 = read_pci_config_16(bus, slot, func, 0xc6);
|
|
|
if (word1 != word2) {
|
|
|
res.start = (word1 << 16) | 0x0000;
|
|
|
res.end = (word2 << 16) | 0xffff;
|
|
@@ -79,8 +71,8 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
|
|
|
}
|
|
|
|
|
|
/* read the IO port window */
|
|
|
- pci_read_config_word(dev, 0xd0, &word1);
|
|
|
- pci_read_config_word(dev, 0xd2, &word2);
|
|
|
+ word1 = read_pci_config_16(bus, slot, func, 0xd0);
|
|
|
+ word2 = read_pci_config_16(bus, slot, func, 0xd2);
|
|
|
if (word1 != word2) {
|
|
|
res.start = word1;
|
|
|
res.end = word2;
|
|
@@ -92,13 +84,37 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
|
|
|
res.start = fbus;
|
|
|
res.end = lbus;
|
|
|
res.flags = IORESOURCE_BUS;
|
|
|
- dev_info(&dev->dev, "CNB20LE PCI Host Bridge (domain %04x %pR)\n",
|
|
|
- pci_domain_nr(dev->bus), &res);
|
|
|
+ printk(KERN_INFO "CNB20LE PCI Host Bridge (domain 0000 %pR)\n", &res);
|
|
|
|
|
|
for (i = 0; i < info->res_num; i++)
|
|
|
- dev_info(&dev->dev, "host bridge window %pR\n", &info->res[i]);
|
|
|
+ printk(KERN_INFO "host bridge window %pR\n", &info->res[i]);
|
|
|
}
|
|
|
|
|
|
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
|
|
|
- cnb20le_res);
|
|
|
+static int __init broadcom_postcore_init(void)
|
|
|
+{
|
|
|
+ u8 bus = 0, slot = 0;
|
|
|
+ u32 id;
|
|
|
+ u16 vendor, device;
|
|
|
+
|
|
|
+#ifdef CONFIG_ACPI
|
|
|
+ /*
|
|
|
+ * We should get host bridge information from ACPI unless the BIOS
|
|
|
+ * doesn't support it.
|
|
|
+ */
|
|
|
+ if (acpi_os_get_root_pointer())
|
|
|
+ return 0;
|
|
|
+#endif
|
|
|
+
|
|
|
+ id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
|
|
|
+ vendor = id & 0xffff;
|
|
|
+ device = (id >> 16) & 0xffff;
|
|
|
+
|
|
|
+ if (vendor == PCI_VENDOR_ID_SERVERWORKS &&
|
|
|
+ device == PCI_DEVICE_ID_SERVERWORKS_LE) {
|
|
|
+ cnb20le_res(bus, slot, 0);
|
|
|
+ cnb20le_res(bus, slot, 1);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
+postcore_initcall(broadcom_postcore_init);
|