aboutsummaryrefslogtreecommitdiff
path: root/arch/mn10300/unit-asb2305/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mn10300/unit-asb2305/pci.c')
-rw-r--r--arch/mn10300/unit-asb2305/pci.c143
1 files changed, 52 insertions, 91 deletions
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c
index 1a86425fec4..6b4339f8c9c 100644
--- a/arch/mn10300/unit-asb2305/pci.c
+++ b/arch/mn10300/unit-asb2305/pci.c
@@ -17,16 +17,38 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/delay.h>
+#include <linux/irq.h>
#include <asm/io.h>
+#include <asm/irq.h>
#include "pci-asb2305.h"
unsigned int pci_probe = 1;
-int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus;
struct pci_ops *pci_root_ops;
/*
+ * The accessible PCI window does not cover the entire CPU address space, but
+ * there are devices we want to access outside of that window, so we need to
+ * insert specific PCI bus resources instead of using the platform-level bus
+ * resources directly for the PCI root bus.
+ *
+ * These are configured and inserted by pcibios_init().
+ */
+static struct resource pci_ioport_resource = {
+ .name = "PCI IO",
+ .start = 0xbe000000,
+ .end = 0xbe03ffff,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource pci_iomem_resource = {
+ .name = "PCI mem",
+ .start = 0xb8000000,
+ .end = 0xbbffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+/*
* Functions for accessing PCI configuration space
*/
@@ -55,52 +77,6 @@ static inline int __query(const struct pci_bus *bus, unsigned int devfn)
}
/*
- * translate Linuxcentric addresses to PCI bus addresses
- */
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
- struct resource *res)
-{
- if (res->flags & IORESOURCE_IO) {
- region->start = (res->start & 0x00ffffff);
- region->end = (res->end & 0x00ffffff);
- }
-
- if (res->flags & IORESOURCE_MEM) {
- region->start = (res->start & 0x03ffffff) | MEM_PAGING_REG;
- region->end = (res->end & 0x03ffffff) | MEM_PAGING_REG;
- }
-
-#if 0
- printk(KERN_DEBUG "RES->BUS: %lx-%lx => %lx-%lx\n",
- res->start, res->end, region->start, region->end);
-#endif
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-/*
- * translate PCI bus addresses to Linuxcentric addresses
- */
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
- struct pci_bus_region *region)
-{
- if (res->flags & IORESOURCE_IO) {
- res->start = (region->start & 0x00ffffff) | 0xbe000000;
- res->end = (region->end & 0x00ffffff) | 0xbe000000;
- }
-
- if (res->flags & IORESOURCE_MEM) {
- res->start = (region->start & 0x03ffffff) | 0xb8000000;
- res->end = (region->end & 0x03ffffff) | 0xb8000000;
- }
-
-#if 0
- printk(KERN_INFO "BUS->RES: %lx-%lx => %lx-%lx\n",
- region->start, region->end, res->start, res->end);
-#endif
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
-/*
*
*/
static int pci_ampci_read_config_byte(struct pci_bus *bus, unsigned int devfn,
@@ -173,7 +149,7 @@ static int pci_ampci_write_config_byte(struct pci_bus *bus, unsigned int devfn,
BRIDGEREGB(where) = value;
} else {
if (bus->number == 0 &&
- (devfn == PCI_DEVFN(2, 0) && devfn == PCI_DEVFN(3, 0))
+ (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(3, 0))
)
__pcidebug("<= %02x", bus, devfn, where, value);
CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where);
@@ -279,7 +255,7 @@ static int __init pci_sanity_check(struct pci_ops *o)
(x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
return 1;
- printk(KERN_ERROR "PCI: Sanity check failed\n");
+ printk(KERN_ERR "PCI: Sanity check failed\n");
return 0;
}
@@ -297,6 +273,7 @@ static int __init pci_check_direct(void)
printk(KERN_INFO "PCI: Using configuration ampci\n");
request_mem_region(0xBE040000, 256, "AMPCI bridge");
request_mem_region(0xBFFFFFF4, 12, "PCI ampci");
+ request_mem_region(0xBC000000, 32 * 1024 * 1024, "PCI SRAM");
return 0;
}
@@ -304,15 +281,13 @@ static int __init pci_check_direct(void)
return -ENODEV;
}
-static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
+static int is_valid_resource(struct pci_dev *dev, int idx)
{
unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
- struct resource *devr = &dev->resource[idx];
+ struct resource *devr = &dev->resource[idx], *busr;
if (dev->bus) {
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
- struct resource *busr = dev->bus->resource[i];
-
+ pci_bus_for_each_resource(dev->bus, busr, i) {
if (!busr || (busr->flags ^ devr->flags) & type_mask)
continue;
@@ -326,11 +301,9 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
return 0;
}
-static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
+static void pcibios_fixup_device_resources(struct pci_dev *dev)
{
- struct pci_bus_region region;
- int i;
- int limit;
+ int limit, i;
if (dev->bus->number != 0)
return;
@@ -342,9 +315,6 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
if (!dev->resource[i].flags)
continue;
- region.start = dev->resource[i].start;
- region.end = dev->resource[i].end;
- pcibios_bus_to_resource(dev, &dev->resource[i], &region);
if (is_valid_resource(dev, i))
pci_claim_resource(dev, i);
}
@@ -354,7 +324,7 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
* Called after each bus is probed, but before its children
* are examined.
*/
-void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+void pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_dev *dev;
@@ -375,11 +345,19 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
*/
static int __init pcibios_init(void)
{
+ resource_size_t io_offset, mem_offset;
+ LIST_HEAD(resources);
+
ioport_resource.start = 0xA0000000;
ioport_resource.end = 0xDFFFFFFF;
iomem_resource.start = 0xA0000000;
iomem_resource.end = 0xDFFFFFFF;
+ if (insert_resource(&iomem_resource, &pci_iomem_resource) < 0)
+ panic("Unable to insert PCI IOMEM resource\n");
+ if (insert_resource(&ioport_resource, &pci_ioport_resource) < 0)
+ panic("Unable to insert PCI IOPORT resource\n");
+
if (!pci_probe)
return 0;
@@ -391,32 +369,18 @@ static int __init pcibios_init(void)
printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n",
MEM_PAGING_REG);
- {
-#if 0
- static struct pci_bus am33_root_bus = {
- .children = LIST_HEAD_INIT(am33_root_bus.children),
- .devices = LIST_HEAD_INIT(am33_root_bus.devices),
- .number = 0,
- .secondary = 0,
- .resource = { &ioport_resource, &iomem_resource },
- };
-
- am33_root_bus.ops = pci_root_ops;
- list_add_tail(&am33_root_bus.node, &pci_root_buses);
-
- am33_root_bus.subordinate = pci_do_scan_bus(0);
-
- pci_root_bus = &am33_root_bus;
-#else
- pci_root_bus = pci_scan_bus(0, &pci_direct_ampci, NULL);
-#endif
- }
+ io_offset = pci_ioport_resource.start -
+ (pci_ioport_resource.start & 0x00ffffff);
+ mem_offset = pci_iomem_resource.start -
+ ((pci_iomem_resource.start & 0x03ffffff) | MEM_PAGING_REG);
+
+ pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset);
+ pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset);
+ pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, &resources);
pcibios_irq_init();
pcibios_fixup_irqs();
-#if 0
pcibios_resource_survey();
-#endif
return 0;
}
@@ -427,10 +391,6 @@ char *__init pcibios_setup(char *str)
if (!strcmp(str, "off")) {
pci_probe = 0;
return NULL;
-
- } else if (!strncmp(str, "lastbus=", 8)) {
- pcibios_last_bus = simple_strtol(str+8, NULL, 0);
- return NULL;
}
return str;
@@ -440,7 +400,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
{
int err;
- err = pcibios_enable_resources(dev, mask);
+ err = pci_enable_resources(dev, mask);
if (err == 0)
pcibios_enable_irq(dev);
return err;
@@ -455,6 +415,7 @@ static void __init unit_disable_pcnet(struct pci_bus *bus, struct pci_ops *o)
bus->number = 0;
+ o->read (bus, PCI_DEVFN(2, 0), PCI_VENDOR_ID, 4, &x);
o->read (bus, PCI_DEVFN(2, 0), PCI_COMMAND, 2, &x);
x |= PCI_COMMAND_MASTER |
PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
@@ -491,7 +452,7 @@ asmlinkage void __init unit_pci_init(void)
struct pci_ops *o = &pci_direct_ampci;
u32 x;
- set_intr_level(XIRQ1, GxICR_LEVEL_3);
+ set_intr_level(XIRQ1, NUM2GxICR_LEVEL(CONFIG_PCI_IRQ_LEVEL));
memset(&bus, 0, sizeof(bus));