@@ -15,6 +15,7 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
obj-y += common.o early.o
obj-y += amd_bus.o
+obj-y += broadcom_bus.o
obj-$(CONFIG_X86_64) += intel_bus.o
ifeq ($(CONFIG_PCI_DEBUG),y)
@@ -17,8 +17,6 @@
* also get peer root bus resource for io,mmio
*/
-#ifdef CONFIG_X86_64
-
int pci_root_num;
struct pci_root_info pci_root_info[PCI_ROOT_NR];
static int found_all_numa_early;
@@ -29,6 +27,8 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b)
int j;
struct pci_root_info *info;
+ printk(KERN_DEBUG "PCI: %s called\n", __func__);
+
/* don't go for it if _CRS is used already */
if (b->resource[0] != &ioport_resource ||
b->resource[1] != &iomem_resource)
@@ -67,6 +67,8 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b)
}
}
+#ifdef CONFIG_X86_64
+
#define RANGE_NUM 16
struct res_range {
@@ -119,6 +121,8 @@ static void __init update_range(struct res_range *range, size_t start,
}
}
+#endif /* CONFIG_X86_64 */
+
void __init update_res(struct pci_root_info *info, size_t start,
size_t end, unsigned long flags, int merge)
{
@@ -168,6 +172,8 @@ addit:
info->res_num++;
}
+#ifdef CONFIG_X86_64
+
struct pci_hostbridge_probe {
u32 bus;
u32 slot;
new file mode 100644
@@ -0,0 +1,108 @@
+/*
+ * Read address ranges from a Broadcom CNB20LE Host Bridge
+ *
+ * Copyright (c) 2009 Ira W. Snyder <iws@ovro.caltech.edu>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#define DEBUG 1
+
+#include <linux/delay.h>
+#include <linux/dmi.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <asm/pci_x86.h>
+
+#include "bus_numa.h"
+
+#if 0
+static int res_num = 0;
+#endif
+
+static void __devinit cnb20le_res(struct pci_dev *dev)
+{
+#if 0
+ struct pci_bus *bus = dev->bus;
+#endif
+ struct pci_root_info *info;
+ unsigned long flags;
+ u16 word1, word2;
+ u32 start, end;
+ u8 fbus, lbus;
+
+ info = &pci_root_info[pci_root_num];
+ pci_root_num++;
+
+ pci_read_config_byte(dev, 0x44, &fbus);
+ pci_read_config_byte(dev, 0x45, &lbus);
+ dev_dbg(&dev->dev, "CNB20LE: busses: %d to %d\n", fbus, lbus);
+
+ info->bus_min = fbus;
+ info->bus_max = lbus;
+
+ pci_read_config_word(dev, 0xc0, &word1);
+ pci_read_config_word(dev, 0xc2, &word2);
+ dev_dbg(&dev->dev, "CNB20LE: noPF 0x%.4x 0x%.4x\n", word1, word2);
+ if (word1 != word2) {
+ start = word1;
+ end = word2;
+ flags = IORESOURCE_MEM;
+ update_res(info, start, end, flags, 0);
+#if 0
+ bus->resource[res_num]->start = (word1 << 16) | 0x0000;
+ bus->resource[res_num]->end = (word2 << 16) | 0xffff;
+ bus->resource[res_num]->flags = IORESOURCE_MEM;
+ dev_dbg(&dev->dev, "CNB20LE: noPF %pR\n", bus->resource[res_num]);
+ res_num++;
+#endif
+ }
+
+ pci_read_config_word(dev, 0xc4, &word1);
+ pci_read_config_word(dev, 0xc6, &word2);
+ dev_dbg(&dev->dev, "CNB20LE: PF 0x%.4x 0x%.4x\n", word1, word2);
+ if (word1 != word2) {
+ start = (word1 << 16) | 0x0000;
+ end = (word2 << 16) | 0xffff;
+ flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ update_res(info, start, end, flags, 0);
+#if 0
+ bus->resource[res_num]->start = (word1 << 16) | 0x0000;
+ bus->resource[res_num]->end = (word2 << 16) | 0xffff;
+ bus->resource[res_num]->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ dev_dbg(&dev->dev, "CNB20LE: PF %pR\n", bus->resource[res_num]);
+ res_num++;
+#endif
+ }
+
+ pci_read_config_word(dev, 0xd0, &word1);
+ pci_read_config_word(dev, 0xd2, &word2);
+ dev_dbg(&dev->dev, "CNB20LE: IO 0x%.4x 0x%.4x\n", word1, word2);
+ if (word1 != word2) {
+ start = (word1 << 16) | 0x0000;
+ end = (word2 << 16) | 0xffff;
+ flags = IORESOURCE_IO;
+ update_res(info, start, end, flags, 0);
+#if 0
+ bus->resource[res_num]->start = word1;
+ bus->resource[res_num]->end = word2;
+ bus->resource[res_num]->flags = IORESOURCE_IO;
+ dev_dbg(&dev->dev, "CNB20LE: IO %pR\n", bus->resource[res_num]);
+ res_num++;
+#endif
+ }
+
+#if 0
+ dev_dbg(&dev->dev, "CNB20LE: parent bus: %p number %d pri %d sec %d\n", bus, bus->number, bus->primary, bus->secondary);
+ dev_dbg(&dev->dev, "CNB20LE: parent res0: %pR\n", dev->bus->resource[0]);
+ dev_dbg(&dev->dev, "CNB20LE: parent res1: %pR\n", dev->bus->resource[1]);
+ dev_dbg(&dev->dev, "CNB20LE: parent res2: %pR\n", dev->bus->resource[2]);
+ dev_dbg(&dev->dev, "CNB20LE: parent res3: %pR\n", dev->bus->resource[3]);
+ dev_dbg(&dev->dev, "CNB20LE: parent res4: %pR\n", dev->bus->resource[4]);
+ dev_dbg(&dev->dev, "CNB20LE: parent res5: %pR\n", dev->bus->resource[5]);
+#endif
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE, cnb20le_res);
@@ -1,5 +1,3 @@
-#ifdef CONFIG_X86_64
-
/*
* sub bus (transparent) will use entres from 3 to store extra from
* root, so need to make sure we have enought slot there, Should we
@@ -23,4 +21,4 @@ extern struct pci_root_info pci_root_info[PCI_ROOT_NR];
extern void update_res(struct pci_root_info *info, size_t start,
size_t end, unsigned long flags, int merge);
-#endif
+