diff options
Diffstat (limited to 'target/linux/coldfire/patches/039-Add-PCI-bus-driver-for-M54455EVB-and-M547X_8X.patch')
-rw-r--r-- | target/linux/coldfire/patches/039-Add-PCI-bus-driver-for-M54455EVB-and-M547X_8X.patch | 3051 |
1 files changed, 0 insertions, 3051 deletions
diff --git a/target/linux/coldfire/patches/039-Add-PCI-bus-driver-for-M54455EVB-and-M547X_8X.patch b/target/linux/coldfire/patches/039-Add-PCI-bus-driver-for-M54455EVB-and-M547X_8X.patch deleted file mode 100644 index 6b462fee58..0000000000 --- a/target/linux/coldfire/patches/039-Add-PCI-bus-driver-for-M54455EVB-and-M547X_8X.patch +++ /dev/null @@ -1,3051 +0,0 @@ -From 3f21ef5f7b72937a1ae293e8ba6ebd0bb0b175e3 Mon Sep 17 00:00:00 2001 -From: Jingchang Lu <b35083@freescale.com> -Date: Thu, 4 Aug 2011 09:59:49 +0800 -Subject: [PATCH 39/52] Add PCI bus driver for M54455EVB and M547X_8X - -Signed-off-by: Jingchang Lu <b35083@freescale.com> ---- - arch/m68k/coldfire/m5445x/devices.c | 9 + - arch/m68k/coldfire/m5445x/mcf5445x-pci.c | 721 +++++++++++++++++++++ - arch/m68k/coldfire/m5445x/pci.c | 247 +++++++ - arch/m68k/coldfire/m547x/pci.c | 1023 ++++++++++++++++++++++++++++++ - arch/m68k/coldfire/m547x/pci_dummy.S | 45 ++ - arch/m68k/include/asm/5445x_pci.h | 111 ++++ - arch/m68k/include/asm/548x_pci.h | 99 +++ - arch/m68k/include/asm/pci.h | 6 + - arch/m68k/kernel/bios32_mcf548x.c | 632 ++++++++++++++++++ - drivers/pci/Makefile | 1 + - drivers/pci/access.c | 18 + - drivers/pci/setup-bus.c | 6 + - lib/iomap.c | 4 + - 13 files changed, 2922 insertions(+), 0 deletions(-) - create mode 100644 arch/m68k/coldfire/m5445x/mcf5445x-pci.c - create mode 100644 arch/m68k/coldfire/m5445x/pci.c - create mode 100644 arch/m68k/coldfire/m547x/pci.c - create mode 100644 arch/m68k/coldfire/m547x/pci_dummy.S - create mode 100644 arch/m68k/include/asm/5445x_pci.h - create mode 100644 arch/m68k/include/asm/548x_pci.h - create mode 100644 arch/m68k/kernel/bios32_mcf548x.c - ---- a/arch/m68k/coldfire/m5445x/devices.c -+++ b/arch/m68k/coldfire/m5445x/devices.c -@@ -25,12 +25,15 @@ - #include <linux/spi/mmc_spi.h> - #endif - -+#include <linux/pci.h> -+ - #include <asm/coldfire.h> - #include <asm/mcfsim.h> - #include <asm/mcfuart.h> - #include <asm/mcfqspi.h> - #include <asm/mcfdspi.h> - #include <asm/cf_io.h> -+#include <asm/pci.h> - - /* ATA Interrupt */ - #define IRQ_ATA (64 + 64 + 54) -@@ -517,6 +520,12 @@ void m5445x_uarts_init(void) - - static int __init init_BSP(void) - { -+#ifndef CONFIG_M54455_PCI_initcall -+#if defined(CONFIG_M54455) && defined(CONFIG_PCI) -+ pci_init(); -+ pcibios_init(); -+#endif -+#endif - m5445x_uarts_init(); - platform_add_devices(m5445x_devices, ARRAY_SIZE(m5445x_devices)); - return 0; ---- /dev/null -+++ b/arch/m68k/coldfire/m5445x/mcf5445x-pci.c -@@ -0,0 +1,721 @@ -+/* -+ * arch/m68k/coldfire/m5445x/mcf5445x-pci.c -+ * -+ * Coldfire M5445x specific PCI implementation. -+ * -+ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved. -+ * Kurt Mahan <kmahan@freescale.com> -+ */ -+ -+#include <linux/delay.h> -+#include <linux/interrupt.h> -+#include <linux/pci.h> -+ -+#include <asm/mcfsim.h> -+#include <asm/pci.h> -+#include <asm/irq.h> -+#include <asm/mcf5445x_pciarb.h> -+#include <asm/mcf5445x_pci.h> -+#include <asm/cf_io.h> -+/* -+ * Layout MCF5445x to PCI memory mappings: -+ * -+ * WIN MCF5445x PCI TYPE -+ * --- -------- --- ---- -+ * [0] 0xA0000000 -> 0xACFFFFFF 0xA0000000 -> 0xACFFFFFF MEM -+ * [1] 0xAC000000 -> 0xAEFFFFFF 0xAC000000 -> 0xAEFFFFFF IO -+ * [2] 0xAF000000 -> 0xAFFFFFFF 0xAF000000 -> 0xAFFFFFFF CONFIG -+ */ -+ -+void __iomem *pci_mem_map; -+unsigned long pci_mem_mapsize = 256 * 1024 * 1024; -+ -+#define MCF5445X_PCI_MEM_BASE ((unsigned int)pci_mem_map) -+#define MCF5445X_PCI_MEM_BASE_PHY 0xA0000000 -+#define MCF5445X_PCI_MEM_SIZE 0x0C000000 -+ -+#define MCF5445X_PCI_IO_BASE \ -+ (MCF5445X_PCI_MEM_BASE + MCF5445X_PCI_MEM_SIZE) -+#define MCF5445X_PCI_IO_SIZE 0x03000000 -+ -+#define MCF5445X_PCI_CONFIG_BASE \ -+ (MCF5445X_PCI_IO_BASE + MCF5445X_PCI_IO_SIZE) -+#define MCF5445X_PCI_CONFIG_SIZE 0x01000000 -+ -+#define HOST_IO_BASE \ -+ (MCF5445X_PCI_MEM_BASE + MCF5445X_PCI_MEM_SIZE) -+#define PCI_IO_MASK (MCF5445X_PCI_IO_SIZE - 1) -+ -+#undef DEBUG -+#ifdef DEBUG -+# define DBG(x...) printk(x) -+#else -+# define DBG(x...) -+#endif -+ -+/* PCI Bus memory resource block */ -+struct resource pci_iomem_resource = { -+ .name = "PCI memory space", -+ .flags = IORESOURCE_MEM, -+}; -+ -+/* PCI Bus ioport resource block */ -+struct resource pci_ioport_resource = { -+ .name = "PCI I/O space", -+ .flags = IORESOURCE_IO, -+}; -+ -+/* -+ * The M54455EVB multiplexes all the PCI interrupts via -+ * the FPGA and routes them to a single interrupt. The -+ * PCI spec requires all PCI interrupt routines be smart -+ * enough to sort out their own interrupts. -+ * The interrupt source from the FPGA is configured -+ * to EPORT 3. -+ */ -+#define MCF5445X_PCI_IRQ 0x43 -+ -+#define PCI_SLOTS 4 -+ -+/* -+ * FPGA Info -+ */ -+#define FPGA_PCI_IRQ_ENABLE (u32 *)0x09000000 -+#define FPGA_PCI_IRQ_STATUS (u32 *)0x09000004 -+#define FPGA_PCI_IRQ_ROUTE (u32 *)0x0900000c -+#define FPGA_SEVEN_LED (u32 *)0x09000014 -+ -+ -+/* -+ * mcf5445x_conf_device(struct pci_dev *dev) -+ * -+ * Machine dependent Configure the given device. -+ * -+ * Parameters: -+ * -+ * dev - the pci device. -+ */ -+void -+mcf5445x_conf_device(struct pci_dev *dev) -+{ -+ set_fpga(FPGA_PCI_IRQ_ENABLE, 0x0f); -+} -+ -+/* -+ * int mcf5445x_pci_config_read(unsigned int seg, unsigned int bus, -+ * unsigned int devfn, int reg, -+ * u32 *value) -+ * -+ * Read from PCI configuration space. -+ * -+ */ -+int mcf5445x_pci_config_read(unsigned int seg, unsigned int bus, -+ unsigned int devfn, int reg, int len, u32 *value) -+{ -+ u32 addr = MCF_PCI_PCICAR_BUSNUM(bus) | -+ MCF_PCI_PCICAR_DEVNUM(PCI_SLOT(devfn)) | -+ MCF_PCI_PCICAR_FUNCNUM(PCI_FUNC(devfn)) | -+ MCF_PCI_PCICAR_DWORD(reg) | -+ MCF_PCI_PCICAR_E; -+ -+ if ((bus > 255) || (devfn > 255) || (reg > 255)) { -+ *value = -1; -+ return -EINVAL; -+ } -+ -+ /* setup for config mode */ -+ MCF_PCI_PCICAR = addr; -+ __asm__ __volatile__("nop"); -+ -+ switch (len) { -+ case 1: -+ *value = *(volatile u8 *)(MCF5445X_PCI_CONFIG_BASE+(reg&3)); -+ break; -+ case 2: -+ *value = le16_to_cpu(*(volatile u16 *) -+ (MCF5445X_PCI_CONFIG_BASE + (reg&2))); -+ break; -+ case 4: -+ *value = le32_to_cpu(*(volatile u32 *) -+ (MCF5445X_PCI_CONFIG_BASE)); -+ break; -+ } -+ -+ /* clear config mode */ -+ MCF_PCI_PCICAR = ~MCF_PCI_PCICAR_E; -+ __asm__ __volatile__("nop"); -+ -+ return 0; -+} -+ -+/* -+ * int mcf5445x_pci_config_write(unsigned int seg, unsigned int bus, -+ * unsigned int devfn, int reg, -+ * u32 *value) -+ * -+ * Write to PCI configuration space -+ */ -+int mcf5445x_pci_config_write(unsigned int seg, unsigned int bus, -+ unsigned int devfn, int reg, int len, u32 value) -+{ -+ u32 addr = MCF_PCI_PCICAR_BUSNUM(bus) | -+ MCF_PCI_PCICAR_DEVNUM(PCI_SLOT(devfn)) | -+ MCF_PCI_PCICAR_FUNCNUM(PCI_FUNC(devfn)) | -+ MCF_PCI_PCICAR_DWORD(reg) | -+ MCF_PCI_PCICAR_E; -+ -+ if ((bus > 255) || (devfn > 255) || (reg > 255)) -+ return -EINVAL; -+ -+ /* setup for config mode */ -+ MCF_PCI_PCICAR = addr; -+ __asm__ __volatile__("nop"); -+ -+ switch (len) { -+ case 1: -+ *(volatile u8 *)(MCF5445X_PCI_CONFIG_BASE+(reg&3)) = (u8)value; -+ break; -+ case 2: -+ *(volatile u16 *)(MCF5445X_PCI_CONFIG_BASE+(reg&2)) = -+ cpu_to_le16((u16)value); -+ break; -+ case 4: -+ *(volatile u32 *)(MCF5445X_PCI_CONFIG_BASE) = -+ cpu_to_le32(value); -+ break; -+ } -+ -+ /* clear config mode */ -+ MCF_PCI_PCICAR = ~MCF_PCI_PCICAR_E; -+ __asm__ __volatile__("nop"); -+ -+ return 0; -+} -+ -+/* hardware operations */ -+static struct pci_raw_ops mcf5445x_pci_ops = { -+ .read = mcf5445x_pci_config_read, -+ .write = mcf5445x_pci_config_write, -+}; -+ -+/************************************************************************/ -+ -+/* -+ * u8 pci_inb() -+ * -+ * Read a byte at specified address from I/O space -+ */ -+unsigned char pci_inb(long addr) -+{ -+ char value; -+ -+ value = *(volatile unsigned char *) (HOST_IO_BASE | -+ (addr & PCI_IO_MASK)); -+ DBG("PCI: inb addr=0x%08X, value=0x%02X\n", addr, value); -+ -+ return (unsigned char) value; -+} -+ -+ -+/* -+ * u16 pci_inw() -+ * -+ * Read a word at specified address from I/O space -+ */ -+unsigned short pci_inw(long addr) -+{ -+ short value; -+ volatile unsigned short *ptr; -+ -+ ptr = (volatile unsigned short *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ value = le16_to_cpu(*ptr); -+ -+ DBG("PCI: inw addr=0x%08X, value=0x%04X\n", addr, value); -+ return (unsigned short) value; -+} -+ -+/* -+ * u16 pci_raw_inw() -+ * -+ * Read a raw word at specified address from I/O space -+ */ -+unsigned short pci_raw_inw(long addr) -+{ -+ short value; -+ volatile unsigned short *ptr; -+ -+ ptr = (volatile unsigned short *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ value = *ptr; -+ -+ DBG("PCI: raw_inw addr=0x%08X, value=0x%04X\n", addr, value); -+ return (unsigned short) value; -+} -+ -+/* -+ * u32 pci_inl() -+ * -+ * Read a dword at specified address from I/O space -+ */ -+unsigned long pci_inl(long addr) -+{ -+ long value; -+ volatile unsigned long *ptr; -+ -+ ptr = (volatile unsigned long *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ value = le32_to_cpu(*ptr); -+ -+ DBG("PCI: inl addr=0x%08X, value=0x%08X\n", addr, value); -+ return (unsigned long) value; -+} -+ -+/* -+ * u32 pci_raw_inl() -+ * -+ * Read a raw dword at specified address from I/O space -+ */ -+unsigned long pci_raw_inl(long addr) -+{ -+ long value; -+ volatile unsigned long *ptr; -+ -+ ptr = (volatile unsigned long *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ value = *ptr; -+ -+ DBG("PCI: raw_inl addr=0x%08X, value=0x%08X\n", addr, value); -+ return (unsigned long) value; -+} -+ -+/* -+ * void pci_outb() -+ * -+ * Write a byte value at specified address to I/O space -+ */ -+void pci_outb(unsigned char value, long addr) -+{ -+ -+ *(volatile unsigned char *) (HOST_IO_BASE | (addr & PCI_IO_MASK)) \ -+ = value; -+ DBG("PCI: outb addr=0x%08X, value=0x%02X\n", addr, value); -+} -+ -+ -+/* -+ * void pci_outw() -+ * -+ * Write a word value at specified address to I/O space -+ */ -+void pci_outw(volatile unsigned short value, volatile long addr) -+{ -+ volatile unsigned short *ptr; -+ -+ ptr = (volatile unsigned short *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ *ptr = cpu_to_le16(value); -+ DBG("PCI: outw addr=0x%08X, value=0x%04X\n", addr, value); -+} -+ -+/* -+ * void pci_raw_outw() -+ * -+ * Write a raw word value at specified address to I/O space -+ */ -+void pci_raw_outw(volatile unsigned short value, volatile long addr) -+{ -+ volatile unsigned short *ptr; -+ -+ ptr = (volatile unsigned short *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ *ptr = value; -+ DBG("PCI: raw_outw addr=0x%08X, value=0x%04X\n", addr, value); -+} -+ -+/* -+ * void pci_outl() -+ * -+ * Write a long word value at specified address to I/O space -+ */ -+void pci_outl(volatile unsigned long value, volatile long addr) -+{ -+ volatile unsigned long *ptr; -+ -+ ptr = (volatile unsigned long *)(HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ *ptr = cpu_to_le32(value); -+ DBG("PCI: outl addr=0x%08X, value=0x%08X\n", addr, value); -+} -+ -+/* -+ * void pci_raw_outl() -+ * -+ * Write a raw long word value at specified address to I/O space -+ */ -+void pci_raw_outl(volatile unsigned long value, volatile long addr) -+{ -+ volatile unsigned long *ptr; -+ -+ ptr = (volatile unsigned long *)(HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ *ptr = value; -+ DBG("PCI: raw_outl addr=0x%08X, value=0x%08X\n", addr, value); -+} -+ -+/* -+ * void pci_insb() -+ * -+ * Read several byte values from specified I/O port -+ */ -+void pci_insb(volatile unsigned char *addr, unsigned char *buf, int len) -+{ -+ for (; len--; buf++) -+ *buf = pci_inb((unsigned long)addr); -+ DBG("PCI: pci_insb addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+ -+/* -+ * void pci_insw() -+ * -+ * Read several word values from specified I/O port -+ */ -+void pci_insw(volatile unsigned short *addr, unsigned short *buf, int len) -+{ -+ for (; len--; buf++) -+ *buf = pci_inw((unsigned long)addr); -+ DBG("PCI: pci_insw addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+/* -+ * void pci_insl() -+ * -+ * Read several dword values from specified I/O port -+ */ -+void pci_insl(volatile unsigned long *addr, unsigned long *buf, int len) -+{ -+ for (; len--; buf++) -+ *buf = pci_inl((unsigned long)addr); -+ DBG("PCI: pci_insl addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+/* -+ * void pci_outsb() -+ * -+ * Write several byte values to specified I/O port -+ */ -+void pci_outsb(volatile unsigned char *addr, const unsigned char *buf, int len) -+{ -+ for (; len--; buf++) -+ pci_outb((unsigned long)addr, *buf); -+ DBG("PCI: pci_outsb addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+/* -+ * void pci_outsw() -+ * -+ * Write several word values to specified I/O port -+ */ -+void -+pci_outsw(volatile unsigned short *addr, const unsigned short *buf, int len) -+{ -+ for (; len--; buf++) -+ pci_outw((unsigned long)addr, *buf); -+ DBG("PCI: pci_outsw addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+/* -+ * void pci_outsl() -+ * -+ * Write several dword values to specified I/O port -+ */ -+void pci_outsl(volatile unsigned long *addr, const unsigned long *buf, int len) -+{ -+ for (; len--; buf++) -+ pci_outl((unsigned long)addr, *buf); -+ DBG("PCI: pci_outsl addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+/* -+ * irqreturn_t mcf5445x_pci_interrupt( int irq, void *dev) -+ * -+ * PCI controller interrupt handler. -+ */ -+static irqreturn_t -+mcf5445x_pci_interrupt(int irq, void *dev) -+{ -+ u32 status = MCF_PCI_PCIGSCR; -+#ifdef DEBUG -+ printk(KERN_INFO "PCI: Controller irq status=0x%08x\n", status); -+#endif -+ /* clear */ -+ MCF_PCI_PCIGSCR = status; -+ -+ return IRQ_HANDLED; -+} -+ -+/* -+ * irqreturn_t mcf5445x_pci_arb_interrupt( int irq, void *dev) -+ * -+ * PCI Arbiter interrupt handler. -+ */ -+static irqreturn_t -+mcf5445x_pci_arb_interrupt(int irq, void *dev) -+{ -+ u32 status = MCF_PCIARB_PASR; -+#ifdef DEBUG -+ printk(KERN_INFO "PCI: Arbiter irq status=0x%08x\n", status); -+#endif -+ /* clear */ -+ MCF_PCIARB_PASR = status; -+ return IRQ_HANDLED; -+} -+ -+/* -+ * struct pci_bus_info *init_mcf5445x_pci(void) -+ * -+ * Machine specific initialisation: -+ * -+ * - Allocate and initialise a 'pci_bus_info' structure -+ * - Initialize hardware -+ * -+ * Result: pointer to 'pci_bus_info' structure. -+ */ -+int __init -+init_mcf5445x_pci(void) -+{ -+ /* -+ * Initialize the PCI core -+ */ -+ printk(KERN_INFO "init_mcf5445x_pci\n"); -+ -+ /* pci memory mapping */ -+ pci_mem_map = ioremap(MCF5445X_PCI_MEM_BASE_PHY, pci_mem_mapsize); -+ if (!pci_mem_map) { -+ printk(KERN_ERR "PCI memory map failed by ioremap!\n"); -+ return -ENOMEM; -+ } -+ printk(KERN_INFO "MCF5445X_PCI_MEM_BASE value is 0x%x\n", \ -+ MCF5445X_PCI_MEM_BASE); -+ -+ /* Initialize pci resource */ -+ pci_iomem_resource.start = MCF5445X_PCI_MEM_BASE; -+ pci_iomem_resource.end = MCF5445X_PCI_MEM_BASE + \ -+ MCF5445X_PCI_MEM_SIZE - 1; -+ -+ pci_ioport_resource.start = MCF5445X_PCI_IO_BASE; -+ pci_ioport_resource.end = MCF5445X_PCI_IO_BASE + \ -+ MCF5445X_PCI_IO_SIZE - 1; -+ -+ /* -+ * Must Reset!!! If bootloader has PCI enabled, it will cause -+ * problem in linux when it tries to configure/find resources -+ * for the pci devices -+ */ -+ MCF_PCI_PCIGSCR = 1; -+ -+ /* arbitration controller */ -+ MCF_PCIARB_PACR = MCF_PCIARB_PACR_INTMPRI | -+ MCF_PCIARB_PACR_EXTMPRI(0x0f) | -+ MCF_PCIARB_PACR_INTMINTEN | -+ MCF_PCIARB_PACR_EXTMINTEN(0x0f); -+ -+ /* pci pin assignment regs */ -+#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE) -+ MCF_GPIO_PAR_PCI = MCF_GPIO_PAR_PCI_GNT0 | -+ MCF_GPIO_PAR_PCI_GNT1 | -+ MCF_GPIO_PAR_PCI_GNT2 | -+ MCF_GPIO_PAR_PCI_GNT3_GNT3 | -+ MCF_GPIO_PAR_PCI_REQ0 | -+ MCF_GPIO_PAR_PCI_REQ1 | -+ MCF_GPIO_PAR_PCI_REQ2 | -+ MCF_GPIO_PAR_PCI_REQ3_REQ3; -+ -+ MCF_GPIO_PAR_PCI = (MCF_GPIO_PAR_PCI & -+ (MCF_GPIO_PAR_PCI_GNT3_MASK & -+ MCF_GPIO_PAR_PCI_REQ3_MASK)) | -+ MCF_GPIO_PAR_PCI_GNT3_ATA_DMACK | -+ MCF_GPIO_PAR_PCI_REQ3_ATA_INTRQ; -+#else -+ MCF_GPIO_PAR_PCI = MCF_GPIO_PAR_PCI_GNT0 | -+ MCF_GPIO_PAR_PCI_GNT1 | -+ MCF_GPIO_PAR_PCI_GNT2 | -+ MCF_GPIO_PAR_PCI_GNT3_GNT3 | -+ MCF_GPIO_PAR_PCI_REQ0 | -+ MCF_GPIO_PAR_PCI_REQ1 | -+ MCF_GPIO_PAR_PCI_REQ2 | -+ MCF_GPIO_PAR_PCI_REQ3_REQ3; -+#endif -+ /* target control reg */ -+ MCF_PCI_PCITCR = MCF_PCI_PCITCR_P | -+ MCF_PCI_PCITCR_WCT(8); -+ -+ /* PCI MEM address */ -+ MCF_PCI_PCIIW0BTAR = MCF5445X_PCI_MEM_BASE_PHY | -+ (MCF5445X_PCI_MEM_BASE >> 16); -+ -+ /* PCI MEM address */ -+ MCF_PCI_PCIIW1BTAR = (MCF5445X_PCI_MEM_BASE_PHY + -+ MCF5445X_PCI_MEM_SIZE) -+ | (MCF5445X_PCI_IO_BASE >> 16); -+ -+ /* PCI IO address */ -+ MCF_PCI_PCIIW2BTAR = (MCF5445X_PCI_MEM_BASE_PHY + -+ MCF5445X_PCI_MEM_SIZE + MCF5445X_PCI_IO_SIZE) -+ | (MCF5445X_PCI_CONFIG_BASE >> 16); -+ -+ /* window control */ -+ MCF_PCI_PCIIWCR = MCF_PCI_PCIIWCR_WINCTRL0_ENABLE | -+ MCF_PCI_PCIIWCR_WINCTRL0_MEMREAD | -+ MCF_PCI_PCIIWCR_WINCTRL1_ENABLE | -+ MCF_PCI_PCIIWCR_WINCTRL1_IO | -+ MCF_PCI_PCIIWCR_WINCTRL2_ENABLE | -+ MCF_PCI_PCIIWCR_WINCTRL2_IO; -+ -+ /* initiator control reg */ -+ MCF_PCI_PCIICR = 0; -+ -+ /* type 0 - command */ -+ MCF_PCI_PCISCR = MCF_PCI_PCISCR_MW | /* mem write/inval */ -+ MCF_PCI_PCISCR_B | /* bus master enable */ -+ MCF_PCI_PCISCR_MA | /* clear master abort error */ -+ MCF_PCI_PCISCR_M; /* mem access enable */ -+ -+ /* type 0 - config reg */ -+ MCF_PCI_PCICR1 = MCF_PCI_PCICR1_CACHELINESIZE(4) | -+ MCF_PCI_PCICR1_LATTIMER(0xFF); -+ /* type 0 - config 2 reg */ -+ MCF_PCI_PCICR2 = 0; -+ -+ /* target control reg */ -+ MCF_PCI_PCITCR2 = MCF_PCI_PCITCR2_B0E | MCF_PCI_PCITCR2_B5E; -+ -+ /* translate addresses from PCI[0] to CF[SDRAM] */ -+ MCF_PCI_PCITBATR0 = 0xFC000000 | MCF_PCI_PCITBATR5_EN; -+ MCF_PCI_PCITBATR5 = MCF_RAMBAR1 | MCF_PCI_PCITBATR5_EN; -+ -+ /* inbound window for memory */ -+ MCF_PCI_PCIBAR0 = 0xFC000000; -+ MCF_PCI_PCIBAR5 = MCF_RAMBAR1; -+ -+ /* setup controller interrupt handlers */ -+ if (request_irq(55+128, mcf5445x_pci_interrupt, IRQF_SHARED, -+ "PCI Controller", NULL)) -+ printk(KERN_ERR "PCI: Unable to register controller irq\n"); -+ -+ if (request_irq(56+128, mcf5445x_pci_arb_interrupt, IRQF_SHARED, -+ "PCI Arbiter", NULL)) -+ printk(KERN_ERR "PCI: Unable to register arbiter irq\n"); -+ -+ /* global control - clear reset bit */ -+ MCF_PCI_PCIGSCR = MCF_PCI_PCIGSCR_SEE | -+ MCF_PCI_PCIGSCR_PEE; -+ -+ /* let everything settle */ -+ udelay(1000); -+ -+ /* allocate bus ioport resource */ -+ if (request_resource(&ioport_resource, &pci_ioport_resource) < 0) -+ printk(KERN_ERR "PCI: Unable to alloc ioport resource\n"); -+ -+ /* allocate bus iomem resource */ -+ if (request_resource(&iomem_resource, &pci_iomem_resource) < 0) -+ printk(KERN_ERR "PCI: Unable to alloc iomem resource\n"); -+ -+ /* setup FPGA to route PCI to IRQ3(67), SW7 to IRQ7, SW6 to IRQ4 */ -+ set_fpga(FPGA_PCI_IRQ_ENABLE, 0x00000000); -+ set_fpga(FPGA_PCI_IRQ_ROUTE, 0x00000039); -+ set_fpga(FPGA_SEVEN_LED, 0x000000FF); -+ -+ raw_pci_ops = &mcf5445x_pci_ops; -+#ifdef DEBUG -+ mcf5445x_pci_dumpregs(); -+#endif -+ return 0; -+} -+ -+/* -+ * DEBUGGING -+ */ -+ -+#ifdef DEBUG -+struct regdump { -+ u32 addr; -+ char regname[16]; -+}; -+ -+struct regdump type0regs[] = { -+ { 0xfc0a8000, "PCIIDR" }, -+ { 0xfc0a8004, "PCISCR" }, -+ { 0xfc0a8008, "PCICCRIR" }, -+ { 0xfc0a800c, "PCICR1" }, -+ { 0xfc0a8010, "PCIBAR0" }, -+ { 0xfc0a8014, "PCIBAR1" }, -+ { 0xfc0a8018, "PCIBAR2" }, -+ { 0xfc0a801c, "PCIBAR3" }, -+ { 0xfc0a8020, "PCIBAR4" }, -+ { 0xfc0a8024, "PCIBAR5" }, -+ { 0xfc0a8028, "PCICCPR" }, -+ { 0xfc0a802c, "PCISID" }, -+ { 0xfc0a8030, "PCIERBAR" }, -+ { 0xfc0a8034, "PCICPR" }, -+ { 0xfc0a803c, "PCICR2" }, -+ { 0, "" } -+}; -+ -+struct regdump genregs[] = { -+ { 0xfc0a8060, "PCIGSCR" }, -+ { 0xfc0a8064, "PCITBATR0" }, -+ { 0xfc0a8068, "PCITBATR1" }, -+ { 0xfc0a806c, "PCITCR1" }, -+ { 0xfc0a8070, "PCIIW0BTAR" }, -+ { 0xfc0a8074, "PCIIW1BTAR" }, -+ { 0xfc0a8078, "PCIIW2BTAR" }, -+ { 0xfc0a8080, "PCIIWCR" }, -+ { 0xfc0a8084, "PCIICR" }, -+ { 0xfc0a8088, "PCIISR" }, -+ { 0xfc0a808c, "PCITCR2" }, -+ { 0xfc0a8090, "PCITBATR0" }, -+ { 0xfc0a8094, "PCITBATR1" }, -+ { 0xfc0a8098, "PCITBATR2" }, -+ { 0xfc0a809c, "PCITBATR3" }, -+ { 0xfc0a80a0, "PCITBATR4" }, -+ { 0xfc0a80a4, "PCITBATR5" }, -+ { 0xfc0a80a8, "PCIINTR" }, -+ { 0xfc0a80f8, "PCICAR" }, -+ { 0, "" } -+}; -+ -+struct regdump arbregs[] = { -+ { 0xfc0ac000, "PACR" }, -+ { 0xfc0ac004, "PASR" }, /* documentation error */ -+ { 0, "" } -+}; -+ -+/* -+ * void mcf5445x_pci_dumpregs() -+ * -+ * Dump out all the PCI registers -+ */ -+void -+mcf5445x_pci_dumpregs(void) -+{ -+ struct regdump *reg; -+ -+ printk(KERN_INFO "*** MCF5445x PCI TARGET 0 REGISTERS ***\n"); -+ -+ reg = type0regs; -+ while (reg->addr) { -+ printk(KERN_INFO "0x%08x 0x%08x %s\n", reg->addr, -+ *((u32 *)reg->addr), reg->regname); -+ reg++; -+ } -+ -+ printk(KERN_INFO "\n*** MCF5445x PCI GENERAL REGISTERS ***\n"); -+ reg = genregs; -+ while (reg->addr) { -+ printk(KERN_INFO "0x%08x 0x%08x %s\n", reg->addr, -+ *((u32 *)reg->addr), reg->regname); -+ reg++; -+ } -+ printk(KERN_INFO "\n*** MCF5445x PCI ARBITER REGISTERS ***\n"); -+ reg = arbregs; -+ while (reg->addr) { -+ printk(KERN_INFO "0x%08x 0x%08x %s\n", reg->addr, -+ *((u32 *)reg->addr), reg->regname); -+ reg++; -+ } -+} -+#endif /* DEBUG */ ---- /dev/null -+++ b/arch/m68k/coldfire/m5445x/pci.c -@@ -0,0 +1,247 @@ -+/* -+ * linux/arch/m68k/coldfire/m5445x/pci.c -+ * -+ * PCI initialization for Coldfire architectures. -+ * -+ * Currently Supported: -+ * M5445x -+ * -+ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved. -+ * Kurt Mahan <kmahan@freescale.com> -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/pci.h> -+ -+#include <asm/mcfsim.h> -+#include <asm/pci.h> -+ -+/* pci ops for reading/writing config */ -+struct pci_raw_ops *raw_pci_ops; -+ -+/* pci debug flag */ -+static int debug_pci; -+ -+static int -+pci_read(struct pci_bus *bus, unsigned int devfn, int where, -+ int size, u32 *value) -+{ -+ return raw_pci_ops->read(0, bus->number, devfn, where, size, value); -+} -+ -+static int -+pci_write(struct pci_bus *bus, unsigned int devfn, int where, -+ int size, u32 value) -+{ -+ return raw_pci_ops->write(0, bus->number, devfn, where, size, value); -+} -+ -+struct pci_ops pci_root_ops = { -+ .read = pci_read, -+ .write = pci_write, -+}; -+ -+/* -+ * pcibios_setup(char *) -+ * -+ * Initialize the pcibios based on cmd line params. -+ */ -+char * -+pcibios_setup(char *str) -+{ -+ if (!strcmp(str, "debug")) { -+ debug_pci = 1; -+ return NULL; -+ } -+ return str; -+} -+ -+/* -+ * We need to avoid collisions with `mirrored' VGA ports -+ * and other strange ISA hardware, so we always want the -+ * addresses to be allocated in the 0x000-0x0ff region -+ * modulo 0x400. -+ * -+ * Why? Because some silly external IO cards only decode -+ * the low 10 bits of the IO address. The 0x00-0xff region -+ * is reserved for motherboard devices that decode all 16 -+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff, -+ * but we want to try to avoid allocating at 0x2900-0x2bff -+ * which might have be mirrored at 0x0100-0x03ff.. -+ */ -+resource_size_t -+pcibios_align_resource(void *data, const struct resource *res, -+ resource_size_t size, resource_size_t align) -+{ -+ struct pci_dev *dev = data; -+ resource_size_t start = res->start; -+ -+ if (res->flags & IORESOURCE_IO) { -+ if (size > 0x100) -+ printk(KERN_ERR "PCI: I/O Region %s/%d too large" -+ " (%ld bytes)\n", pci_name(dev), -+ dev->resource - res, (long int)size); -+ -+ if (start & 0x3ff) -+ start = (start + 0x3ff) & ~0x3ff; -+ } -+ -+ return start; -+} -+EXPORT_SYMBOL(pcibios_align_resource); -+ -+/* -+ * Swizzle the device pin each time we cross a bridge -+ * and return the slot number. -+ */ -+static u8 __devinit -+pcibios_swizzle(struct pci_dev *dev, u8 *pin) -+{ -+ return 0; -+} -+ -+/* -+ * Map a slot/pin to an IRQ. -+ */ -+static int -+pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -+{ -+ return 0x43; -+} -+ -+/* -+ * pcibios_update_irq(struct pci_dev *dev, int irq) -+ * -+ * Update a PCI interrupt. -+ */ -+void -+pcibios_update_irq(struct pci_dev *dev, int irq) -+{ -+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -+} -+ -+/* -+ * pcibios_enable_device(struct pci_dev *dev, int mask) -+ * -+ * Enable a device on the PCI bus. -+ */ -+int -+pcibios_enable_device(struct pci_dev *dev, int mask) -+{ -+ u16 cmd, old_cmd; -+ int idx; -+ struct resource *r; -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ old_cmd = cmd; -+ for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) { -+ r = &dev->resource[idx]; -+ if (!r->start && r->end) { -+ printk(KERN_ERR "PCI: Device %s not available because " -+ "of resource collisions\n", pci_name(dev)); -+ return -EINVAL; -+ } -+ if (r->flags & IORESOURCE_IO) -+ cmd |= PCI_COMMAND_IO; -+ if (r->flags & IORESOURCE_MEM) -+ cmd |= PCI_COMMAND_MEMORY; -+ } -+ if (cmd != old_cmd) { -+ printk("PCI: Enabling device %s (%04x -> %04x)\n", -+ pci_name(dev), old_cmd, cmd); -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+#ifdef CONFIG_M54455 -+ mcf5445x_conf_device(dev); -+#endif -+ } -+ -+ return 0; -+} -+ -+/* -+ * pcibios_fixup_bus(struct pci_bus *bus) -+ */ -+void -+pcibios_fixup_bus(struct pci_bus *bus) -+{ -+ struct pci_dev *dev = bus->self; -+ -+ if (!dev) { -+ /* Root bus. */ -+#ifdef CONFIG_M54455 -+ bus->resource[0] = &pci_ioport_resource; -+ bus->resource[1] = &pci_iomem_resource; -+#endif -+ } -+} -+ -+/* -+ * pcibios_init(void) -+ * -+ * Allocate/initialize low level pci bus/devices. -+ */ -+#ifdef CONFIG_M54455_PCI_initcall -+static int __init -+#else -+int __init -+#endif -+pcibios_init(void) -+{ -+ struct pci_bus *bus; -+ -+ if (!raw_pci_ops) { -+ printk(KERN_WARNING "PCIBIOS: FATAL: NO PCI Hardware found\n"); -+ return 0; -+ } -+ -+ /* allocate and scan the (only) bus */ -+ bus = pci_scan_bus_parented(NULL, 0, &pci_root_ops, NULL); -+ -+ /* setup everything */ -+ if (bus) { -+ /* compute the bridge window sizes */ -+ pci_bus_size_bridges(bus); -+ -+ /* (re)assign device resources */ -+ pci_bus_assign_resources(bus); -+ -+ /* add the bus to the system */ -+ pci_bus_add_devices(bus); -+ -+ /* fixup irqs */ -+ pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq); -+ } -+ -+ return 0; -+} -+ -+/* -+ * pci_init(void) -+ * -+ * Initialize the PCI Hardware. -+ */ -+#ifdef CONFIG_M54455_PCI_initcall -+static int __init -+#else -+int __init -+#endif -+pci_init(void) -+{ -+ printk(KERN_INFO "pci_init\n"); -+#if defined(CONFIG_M54455) -+ init_mcf5445x_pci(); -+#endif -+ if (!raw_pci_ops) -+ printk(KERN_ERR "PCI: FATAL: NO PCI Detected\n"); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_M54455_PCI_initcall -+/* low level hardware (first) */ -+arch_initcall(pci_init); -+ -+/* basic bios init (second) */ -+subsys_initcall(pcibios_init); -+#endif ---- /dev/null -+++ b/arch/m68k/coldfire/m547x/pci.c -@@ -0,0 +1,1023 @@ -+/* -+ * ColdFire 547x/548x PCI Host Controller functions -+ * -+ * Copyright (C) 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved. -+ * Shrek Wu b16972@freescale.com -+ * This code is based on the 2.6.10 version of pci.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+#include <linux/kernel.h> -+#include <linux/types.h> -+#include <linux/init.h> -+#include <linux/mm.h> -+#include <linux/string.h> -+#include <linux/pci.h> -+#include <linux/ioport.h> -+#include <linux/slab.h> -+#include <linux/version.h> -+#include <linux/interrupt.h> -+#include <linux/delay.h> -+ -+#include <linux/dma-mapping.h> -+#include <asm/coldfire.h> -+#include <linux/io.h> -+#include <asm/m5485sim.h> -+#include <asm/m5485pci.h> -+#include <asm/irq.h> -+#include <linux/pci.h> -+#include <asm/virtconvert.h> -+ -+ -+#undef DEBUG -+/*define DEBUG*/ -+#ifdef DEBUG -+/*#define DBG(x...) printk(KERN_DEBUG x)*/ -+#define DBG(x...) printk(x) -+#else -+#define DBG(x...) -+#endif -+ -+/* -+ * Bridge configration dafaults -+ */ -+#define PCI_RETRIES 0 -+#define PCI_CACHE_LINE 8 -+#define PCI_MINGNT 1 -+#define PCI_MAXLAT 42 -+ -+ -+/* -+ * Initiator windows setting -+ */ -+#define HOST_MEM_BASE 0xD0000000 -+/* ColdFire Memory window base */ -+#define PCI_MEM_BASE 0xD0000000 -+/* PCI Memory window base */ -+#define PCI_MEM_SIZE 0x08000000 -+/* Memory window size (128M) */ -+#define HOST_IO_BASE 0xD8000000 -+/* ColdFire I/O window base */ -+#define PCI_IO_BASE_ADDR 0x00000000 -+/* PCI I/O window base */ -+#define PCI_IO_SIZE 0x00010000 -+/* I/O window size (64K) */ -+/*#define HOST_CFG_BASE 0xD8000000*/ -+#define HOST_CFG_BASE 0xD8008000 -+/* ColdFire config window base */ -+#define HOST_DMA_BASE CONFIG_SDRAM_BASE -+/* ColdFire PCI-DMA window base */ -+#define PCI_HDR_BASE (MCF_MBAR+0xB00) -+/* ColdFire config registers */ -+ -+#define PCI_MEM_MASK (PCI_MEM_SIZE-1) -+#define PCI_IO_MASK (PCI_IO_SIZE-1) -+ -+/* Macro to set initiator window */ -+#define WxBAR(host_address, pci_address, size) \ -+ (((host_address) & 0xff000000) | \ -+ ((((size)-1) & 0xff000000) >> 8) | \ -+ ((pci_address) & 0xff000000) >> 16) -+ -+/* -+ * BIOS internal data -+ */ -+static u8 revision; /* controller revision */ -+ -+/* -+ * Board specific setting -+ */ -+const unsigned int irq_lines[] = { 5, 7 }; -+ -+#define N_SLOTS (sizeof(board_info) / sizeof(board_info[0])) -+#define N_IRQS (sizeof(irq_lines) / sizeof(irq_lines[0])) -+#define BRIDGE_SLOT 0 -+ -+const struct slotinfo { -+ unsigned char idsel; /* device number */ -+ unsigned char irq; /* external IRQ */ -+ unsigned char req; /* REQ line number */ -+ unsigned char gnt; /* GNT line number */ -+} board_info[] = { -+ {0, 0, 0, 0}, /* Bridge */ -+ {17, 5, 1, 1}, /* Slot #1 */ -+ {18, 5, 2, 2}, /* Slot #2 */ -+ {20, 7, 3, 3}, /* Slot #3 */ -+ {21, 7, 4, 4}, /* Slot #4 */ -+}; -+ -+/************************************************************************/ -+ -+/* -+ * static int mk_conf_addr() -+ * -+ * Return type0 or type1 configuration address -+ * by the means of device address and PCI dword location -+ * 0 - for not existing slots -+ */ -+static int mk_conf_addr(/*struct pci_dev *dev*/ -+ struct pci_bus *bus, unsigned int devfn, int where) -+{ -+ int slot, func, address, idsel, dev_fn; -+ -+ if (bus->number) { -+ address = MCF_PCICAR_E | (bus->number << 16) | -+ (devfn << 8) | (where & 0xfc); -+ } else { -+ slot = PCI_SLOT(devfn); -+ if (slot > N_SLOTS || slot == BRIDGE_SLOT) -+ return 0; -+ else { -+ func = PCI_FUNC(devfn); -+ idsel = board_info[slot].idsel; -+ -+ dev_fn = PCI_DEVFN(idsel, func); -+ address = MCF_PCICAR_E | (bus->number << 16) | -+ (dev_fn << 8) | (where & 0xfc); -+ } -+ } -+ -+ return address; -+} -+ -+/* -+ * static int read_config_byte() -+ * -+ * Read a byte from configuration space of specified device -+ */ -+static int read_config_byte(/*struct pci_dev *dev*/ -+ struct pci_bus *bus, unsigned int devfn, int where, u8 *value) -+{ -+ int slot; -+ int address; -+ int result; -+ -+ *value = 0xff; -+ result = PCIBIOS_SUCCESSFUL; -+ -+ slot = PCI_SLOT(devfn); -+ if (slot == BRIDGE_SLOT) { -+ if (where <= 0x40) -+ *value = *(volatile u8 *) (PCI_HDR_BASE + -+ (where & 0xfc) + (where & 3)); -+ else -+ *value = 0; -+ } else { -+ address = mk_conf_addr(bus, devfn, where); -+ if (!address) -+ result = PCIBIOS_DEVICE_NOT_FOUND; -+ else { -+ MCF_PCICAR = address; -+ __asm__ __volatile__("nop"); -+ *value = *(volatile u8 *) (HOST_CFG_BASE + (where & 3)); -+ } -+ } -+ __asm("tpf"); -+ MCF_PCICAR &= ~MCF_PCICAR_E; -+ DBG("PCI: read_config_byte bus=%d, dev=%d, fn=%d," -+ " addr=0x%02X, val=0x%02X, ret=%02X\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, *value, result); -+ -+ return result; -+} -+ -+/* -+ * static int read_config_word() -+ * -+ * Read a word from configuration space of specified device -+ */ -+static int read_config_word(/*struct pci_dev *dev*/ -+ struct pci_bus *bus, unsigned int devfn, int where, u16 *value) -+{ -+ int slot; -+ int address; -+ int result; -+ -+ *value = 0xffff; -+ result = PCIBIOS_SUCCESSFUL; -+ -+ if (where & 0x1) -+ result = PCIBIOS_BAD_REGISTER_NUMBER; -+ else { -+ slot = PCI_SLOT(devfn); -+ if (slot == BRIDGE_SLOT) { -+ if (where <= 0x3f) -+ *value = -+ *(volatile u16 *) (PCI_HDR_BASE + -+ (where & 0xfc) + (where & 2)); -+ else -+ *value = 0; -+ } else { -+ address = mk_conf_addr(bus, devfn, where); -+ if (!address) -+ result = PCIBIOS_DEVICE_NOT_FOUND; -+ else { -+ MCF_PCICAR = address; -+ __asm__ __volatile__("nop"); -+ *value = le16_to_cpu(*(volatile u16 *) -+ (HOST_CFG_BASE + -+ (where & 2))); -+ } -+ } -+ } -+ __asm("tpf"); -+ MCF_PCICAR &= ~MCF_PCICAR_E; -+ DBG("PCI: read_config_word bus=%d, dev=%d, fn=%d," -+ " addr=0x%02X, val=0x%04X ret=%02X\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, *value, result); -+ -+ return result; -+} -+ -+/* -+ * static int read_config_dword() -+ * -+ * Read a long word from configuration space of specified device -+ */ -+static int read_config_dword(/*struct pci_dev *dev*/ -+ struct pci_bus *bus, unsigned int devfn, int where, u32 *value) -+{ -+ int slot; -+ int address; -+ int result; -+ -+ *value = 0xffffffff; -+ result = PCIBIOS_SUCCESSFUL; -+ -+ if (where & 0x3) -+ result = PCIBIOS_BAD_REGISTER_NUMBER; -+ else { -+ slot = PCI_SLOT(devfn); -+ if (slot == BRIDGE_SLOT) { -+ if (where <= 0x3d) -+ *value = -+ *(volatile u32 *) (PCI_HDR_BASE + where); -+ else -+ *value = 0; -+ __asm("tpf"); -+ } else { -+ address = mk_conf_addr(bus, devfn, where); -+ if (!address) -+ result = PCIBIOS_DEVICE_NOT_FOUND; -+ else { -+ MCF_PCICAR = address; -+ __asm__ __volatile__("nop"); -+ *value = le32_to_cpu(*(volatile u32 *) -+ (HOST_CFG_BASE)); -+ __asm("tpf"); -+ if (bus->number != 0 && revision < 1) { -+ volatile u32 temp; -+ MCF_PCICAR |= 0xff0000; -+ temp = *(volatile u32 *) -+ (HOST_CFG_BASE); -+ } -+ } -+ } -+ } -+ -+ MCF_PCICAR &= ~MCF_PCICAR_E; -+ DBG("PCI: read_config_dword bus=%d, dev=%d, fn=%d, " -+ "addr=0x%02X, value=0x%08X ret=%02X\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, *value, result); -+ -+ return result; -+} -+ -+ -+ -+/* -+ * static int write_config_byte() -+ * -+ * Write a byte to configuration space of specified device -+ */ -+static int write_config_byte(/*struct pci_dev *dev*/ -+ struct pci_bus *bus, unsigned int devfn, int where, u8 value) -+{ -+ int slot; -+ int address; -+ int result; -+ -+ result = PCIBIOS_SUCCESSFUL; -+ -+ slot = PCI_SLOT(devfn); -+ if (slot == BRIDGE_SLOT) { -+ if (where <= 0x40) -+ *(volatile u8 *) (PCI_HDR_BASE + (where & 0xfc) -+ + (where & 3)) = value; -+ } else { -+ address = mk_conf_addr(bus, devfn, where); -+ if (!address) -+ result = PCIBIOS_DEVICE_NOT_FOUND; -+ else { -+ MCF_PCICAR = address; -+ __asm__ __volatile__("tpf"); -+ *(volatile u8 *) (HOST_CFG_BASE + (where & 3)) = value; -+ } -+ } -+ __asm("tpf"); -+ MCF_PCICAR &= ~MCF_PCICAR_E; -+ pci_dummy_function(); -+ -+ DBG("PCI: write_config_byte bus=%d, dev=%d, fn=%d, " -+ "addr=0x%02X, value=0x%02X ret=%02X\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, value, result); -+ -+ return result; -+} -+ -+/* -+ * static int write_config_word() -+ * -+ * Write a word to configuration space of specified device -+ */ -+static int write_config_word(/*struct pci_dev *dev*/ -+ struct pci_bus *bus, unsigned int devfn, int where, u16 value) -+{ -+ int slot; -+ int address; -+ int result; -+ -+ result = PCIBIOS_SUCCESSFUL; -+ -+ if (where & 0x1) -+ result = PCIBIOS_BAD_REGISTER_NUMBER; -+ else { -+ slot = PCI_SLOT(devfn); -+ if (slot == BRIDGE_SLOT) { -+ if (where <= 0x3f) -+ *(volatile u16 *) (PCI_HDR_BASE + -+ (where & 0xfc) + (where & 2)) = value; -+ } else { -+ address = mk_conf_addr(bus, devfn, where); -+ if (!address) -+ result = PCIBIOS_DEVICE_NOT_FOUND; -+ else { -+ MCF_PCICAR = address; -+ __asm__ __volatile__("tpf"); -+ *(volatile u16 *) (HOST_CFG_BASE -+ + (where & 2)) = -+ cpu_to_le16(value); -+ } -+ } -+ } -+ __asm("tpf"); -+ MCF_PCICAR &= ~MCF_PCICAR_E; -+ pci_dummy_function(); -+ -+ DBG("PCI: write_config_word bus=%d, dev=%d, fn=%d, " -+ "addr=0x%02X, value=0x%04X ret=%02X\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, value, result); -+ -+ return result; -+} -+ -+/* -+ * static int write_config_dword() -+ * -+ * Write a long word to configuration space of specified device -+ */ -+static int write_config_dword(/*struct pci_dev *dev*/ -+ struct pci_bus *bus, unsigned int devfn, int where, u32 value) -+{ -+ int slot; -+ int address; -+ int result; -+ -+ result = PCIBIOS_SUCCESSFUL; -+ -+ if (where & 0x3) -+ result = PCIBIOS_BAD_REGISTER_NUMBER; -+ else { -+ slot = PCI_SLOT(devfn); -+ if (slot == BRIDGE_SLOT) { -+ if (where <= 0x3d) -+ *(volatile u32 *) (PCI_HDR_BASE + where) = -+ value; -+ } else { -+ address = mk_conf_addr(bus, devfn, where); -+ if (!address) -+ result = PCIBIOS_DEVICE_NOT_FOUND; -+ else { -+ MCF_PCICAR = address; -+ __asm__ __volatile__("tpf"); -+ *(volatile u32 *) (HOST_CFG_BASE) = -+ cpu_to_le32(value); -+ } -+ } -+ } -+ __asm("tpf"); -+ MCF_PCICAR &= ~MCF_PCICAR_E; -+ pci_dummy_function(); -+ -+ DBG("PCI: write_config_dword dev=%d, fn=%d," -+ "addr=0x%02X, value=0x%08X ret=%02X\n", -+ PCI_SLOT(devfn), PCI_FUNC(devfn), where, value, result); -+ -+ return result; -+} -+ -+static int config_read(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 *val) -+{ -+ switch (size) { -+ case 1: -+ return read_config_byte(bus, devfn, where, (u8 *) val); -+ case 2: -+ return read_config_word(bus, devfn, where, (u16 *) val); -+ default: -+ return read_config_dword(bus, devfn, where, val); -+ } -+} -+ -+static int config_write(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 val) -+{ -+ switch (size) { -+ case 1: -+ return write_config_byte(bus, devfn, where, (u8) val); -+ case 2: -+ return write_config_word(bus, devfn, where, (u16) val); -+ default: -+ return write_config_dword(bus, devfn, where, val); -+ } -+} -+ -+/* -+ * configuration routines entry points -+ */ -+static struct pci_ops bus_ops = { -+ .read = config_read, -+ .write = config_write, -+}; -+ -+/************************************************************************/ -+ -+/* -+ * u8 pci_inb() -+ * -+ * Read a byte at specified address from I/O space -+ */ -+unsigned char pci_inb(long addr) -+{ -+ char value; -+ -+ value = *(volatile unsigned char *)(HOST_IO_BASE | -+ (addr & PCI_IO_MASK)); -+ DBG("PCI: inb addr=0x%08X, value=0x%02X\n", addr, value); -+ -+ return (unsigned char) value; -+} -+ -+ -+/* -+ * u16 pci_inw() -+ * -+ * Read a word at specified address from I/O space -+ */ -+unsigned short pci_inw(long addr) -+{ -+ short value; -+ volatile unsigned short *ptr; -+ -+ ptr = (volatile unsigned short *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ value = le16_to_cpu(*ptr); -+ -+ DBG("PCI: inw addr=0x%08X, value=0x%04X\n", addr, value); -+ return (unsigned short) value; -+} -+ -+/* -+ * u16 pci_raw_inw() -+ * -+ * Read a raw word at specified address from I/O space -+ */ -+unsigned short pci_raw_inw(long addr) -+{ -+ short value; -+ volatile unsigned short *ptr; -+ -+ ptr = (volatile unsigned short *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ value = *ptr; -+ -+ DBG("PCI: raw_inw addr=0x%08X, value=0x%04X\n", addr, value); -+ return (unsigned short) value; -+} -+ -+/* -+ * u32 pci_inl() -+ * -+ * Read a dword at specified address from I/O space -+ */ -+unsigned long pci_inl(long addr) -+{ -+ long value; -+ volatile unsigned long *ptr; -+ -+ ptr = (volatile unsigned long *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ value = le32_to_cpu(*ptr); -+ -+ DBG("PCI: inl addr=0x%08X, value=0x%08X\n", addr, value); -+ return (unsigned long) value; -+} -+ -+/* -+ * u32 pci_raw_inl() -+ * -+ * Read a raw dword at specified address from I/O space -+ */ -+unsigned long pci_raw_inl(long addr) -+{ -+ long value; -+ volatile unsigned long *ptr; -+ -+ ptr = (volatile unsigned long *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ value = *ptr; -+ -+ DBG("PCI: raw_inl addr=0x%08X, value=0x%08X\n", addr, value); -+ return (unsigned long) value; -+} -+ -+/* -+ * void pci_outb() -+ * -+ * Write a byte value at specified address to I/O space -+ */ -+void pci_outb(unsigned char value, long addr) -+{ -+ -+ *(volatile unsigned char *)(HOST_IO_BASE | (addr & PCI_IO_MASK)) -+ = value; -+ DBG("PCI: outb addr=0x%08X, value=0x%02X\n", addr, value); -+} -+ -+ -+/* -+ * void pci_outw() -+ * -+ * Write a word value at specified address to I/O space -+ */ -+void pci_outw(volatile unsigned short value, volatile long addr) -+{ -+ volatile unsigned short *ptr; -+ -+ ptr = (volatile unsigned short *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ *ptr = cpu_to_le16(value); -+ DBG("PCI: outw addr=0x%08X, value=0x%04X\n", addr, value); -+} -+ -+/* -+ * void pci_raw_outw() -+ * -+ * Write a raw word value at specified address to I/O space -+ */ -+void pci_raw_outw(volatile unsigned short value, volatile long addr) -+{ -+ volatile unsigned short *ptr; -+ -+ ptr = (volatile unsigned short *) (HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ *ptr = value; -+ DBG("PCI: raw_outw addr=0x%08X, value=0x%04X\n", addr, value); -+} -+ -+/* -+ * void pci_outl() -+ * -+ * Write a long word value at specified address to I/O space -+ */ -+void pci_outl(volatile unsigned long value, volatile long addr) -+{ -+ volatile unsigned long *ptr; -+ -+ ptr = (volatile unsigned long *)(HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ *ptr = cpu_to_le32(value); -+ DBG("PCI: outl addr=0x%08X, value=0x%08X\n", addr, value); -+} -+ -+/* -+ * void pci_raw_outl() -+ * -+ * Write a raw long word value at specified address to I/O space -+ */ -+void pci_raw_outl(volatile unsigned long value, volatile long addr) -+{ -+ volatile unsigned long *ptr; -+ -+ ptr = (volatile unsigned long *)(HOST_IO_BASE | (addr & PCI_IO_MASK)); -+ *ptr = value; -+ DBG("PCI: raw_outl addr=0x%08X, value=0x%08X\n", addr, value); -+} -+ -+/* -+ * void pci_insb() -+ * -+ * Read several byte values from specified I/O port -+ */ -+void pci_insb(volatile unsigned char *addr, unsigned char *buf, int len) -+{ -+ for (; len--; buf++) -+ *buf = pci_inb((unsigned long)addr); -+ DBG("PCI: pci_insb addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+ -+/* -+ * void pci_insw() -+ * -+ * Read several word values from specified I/O port -+ */ -+void pci_insw(volatile unsigned short *addr, unsigned short *buf, int len) -+{ -+ for (; len--; buf++) -+ *buf = pci_inw((unsigned long)addr); -+ DBG("PCI: pci_insw addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+/* -+ * void pci_insl() -+ * -+ * Read several dword values from specified I/O port -+ */ -+void pci_insl(volatile unsigned long *addr, unsigned long *buf, int len) -+{ -+ for (; len--; buf++) -+ *buf = pci_inl((unsigned long)addr); -+ DBG("PCI: pci_insl addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+/* -+ * void pci_outsb() -+ * -+ * Write several byte values to specified I/O port -+ */ -+void pci_outsb(volatile unsigned char *addr, const unsigned char *buf, int len) -+{ -+ for (; len--; buf++) -+ pci_outb((unsigned long)addr, *buf); -+ DBG("PCI: pci_outsb addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+/* -+ * void pci_outsw() -+ * -+ * Write several word values to specified I/O port -+ */ -+void pci_outsw(volatile unsigned short *addr, -+ const unsigned short *buf, int len) -+{ -+ for (; len--; buf++) -+ pci_outw((unsigned long)addr, *buf); -+ DBG("PCI: pci_outsw addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+/* -+ * void pci_outsl() -+ * -+ * Write several dword values to specified I/O port -+ */ -+void pci_outsl(volatile unsigned long *addr, const unsigned long *buf, int len) -+{ -+ for (; len--; buf++) -+ pci_outl((unsigned long)addr, *buf); -+ DBG("PCI: pci_outsl addr=0x%08X, buf=%p, len=%d\n", addr, buf, len); -+} -+ -+/* -+ * void pci_xlb_handler() -+ * -+ * PCI XLB interrupt handler -+ */ -+irqreturn_t xlb_interrupt(int irq, void *dev) -+{ -+ volatile int xlb_error = MCF_PCIISR; -+ -+ /* Acknowlege interrupt */ -+ MCF_PCIISR = xlb_error; -+ -+ /* Dump interrupt reason */ -+ if (xlb_error & MCF_PCIISR_RE) -+ DBG("PCI: Retry Error Received\n"); -+ -+ if (xlb_error & MCF_PCIISR_IA) -+ DBG("PCI: Initiator Abort Received\n"); -+ -+ if (xlb_error & MCF_PCIISR_TA) -+ DBG("PCI: Target Abort Received\n"); -+ -+ return IRQ_HANDLED; -+} -+ -+ -+/* -+ * void pci_arbiter_handler() -+ * -+ * PCI arbiter interrupt handler -+ */ -+irqreturn_t arb_interrupt(int irq, void *dev) -+{ -+ volatile unsigned long arb_error = MCF_PCIARB_PASR; -+ -+ /* Acknowlege interrupt */ -+ printk(KERN_ERR "%s\n", __func__); -+ MCF_PCIARB_PASR = arb_error; -+ -+ if (arb_error & MCF_PCIARB_PASR_ITLMBK) { -+ DBG("PCI: coldfire master time-out\n"); -+ -+ /* Set infinite number of retries */ -+ MCF_PCIICR &= ~0xFF; -+ } -+ -+ if (arb_error & MCF_PCIARB_PASR_EXTMBK(0x1F)) { -+ arb_error >>= 17; -+ DBG("PCI: external master time-out (mask = 0x%X)\n", arb_error); -+ -+ /* raise arbitration priority level */ -+ MCF_PCIARB_PACR = MCF_PCIARB_PACR_EXTMPRI(arb_error); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+ -+/* -+ * void pci_eint_handler() -+ * -+ * Eport interrupt handler -+ */ -+irqreturn_t eint_handler(int irq, void *dev) -+{ -+ /* Just acknowlege interrupt and exit */ -+ MCF_EPFR = 0x1 << (irq - 64); -+ return IRQ_HANDLED; -+} -+ -+resource_size_t -+pcibios_align_resource(void *data, const struct resource *res, -+ resource_size_t size, resource_size_t align) -+{ -+ struct pci_dev *dev = data; -+ resource_size_t start = res->start; -+ -+ if (res->flags & IORESOURCE_IO) { -+ if (size > 0x100) -+ printk(KERN_ERR "PCI: I/O Region %s/%d too large" -+ " (%ld bytes)\n", pci_name(dev), -+ dev->resource - res, (long int)size); -+ -+ if (start & 0x3ff) -+ start = (start + 0x3ff) & ~0x3ff; -+ } -+ -+ return start; -+} -+EXPORT_SYMBOL(pcibios_align_resource); -+ -+/* -+ * void __init coldfire_fixup(int pci_modify) -+ * -+ * Assign IRQ numbers as used by Linux to the interrupt pins -+ * of the PCI cards. -+ */ -+static void __init coldfire_fixup(int pci_modify) -+{ -+ struct pci_dev *dev; -+ unsigned char slot, pin; -+ -+ DBG("%s\n", __func__); -+#ifdef NL_ORIGINAL -+ pci_for_each_dev(dev) { -+#else -+ dev = NULL; -+ while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { -+#endif -+ if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) { -+ slot = PCI_SLOT(dev->devfn); -+ dev->irq = 64 + board_info[slot].irq; -+ -+ /* Check if device needs interrupt */ -+#ifdef NL_ORIGINAL -+ pcibios_read_config_byte( -+ dev->bus->number, dev->devfn, -+ PCI_INTERRUPT_PIN, &pin); -+ -+ if (pin) { -+ pcibios_write_config_byte( -+ dev->bus->number, dev->devfn, -+ PCI_INTERRUPT_LINE, dev->irq); -+ } -+#else -+ pci_read_config_byte(dev, -+ PCI_INTERRUPT_PIN, &pin); -+ -+ if (pin) { -+ pci_write_config_byte(dev, -+ PCI_INTERRUPT_LINE, dev->irq); -+ } -+#endif -+ } -+ } -+} -+ -+static void __init configure_device(struct pci_dev *dev) -+{ -+ /* TODO: This should depend from disable_pci_burst setting */ -+ DBG("%s\n", __func__); -+#ifdef NL_ORIGINAL -+ pcibios_write_config_byte(bus, devfn, -+ PCI_CACHE_LINE_SIZE, PCI_CACHE_LINE); -+#else -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, PCI_CACHE_LINE); -+ -+ MCF_PCICR1 = MCF_PCICR1_LATTIMER(0xF8) | -+ MCF_PCICR1_CACHELINESIZE(PCI_CACHE_LINE); -+ -+#endif -+} -+ -+ -+struct pci_bus_info *__init init_coldfire_pci(void) -+{ -+ struct pci_bus_info *bus; -+ int i; -+ unsigned long pci_mem_va; -+ static char irq_name[N_IRQS][15]; -+ -+ MCF_SPCR |= 0x02; /*Enable the PCI clock*/ -+ -+ /* Get controller revision */ -+ revision = MCF_PCICCRIR; -+ printk(KERN_INFO "ColdFire PCI Host Bridge " -+ "(Rev. %d) detected:" -+ "MEMBase %x,MEMLen %x,IOBase %x,IOLen %x\n", -+ revision, HOST_MEM_BASE, -+ PCI_MEM_SIZE - 1, 0, PCI_IO_SIZE - 1); -+ -+ bus = (struct pci_bus_info *)kmalloc(sizeof(struct pci_bus_info), -+ GFP_KERNEL); -+ if (!bus) { -+ printk(KERN_ERR "can not alloc mem for pci bus!\n"); -+ return NULL; -+ } -+ -+ /* Setup bus info structure. */ -+ memset(bus, 0, sizeof(struct pci_bus_info)); -+ -+ /* Request intiator memory resource */ -+ bus->mem_space.start = PCI_MEM_BASE;/*HOST_MEM_BASE;*/ -+ bus->mem_space.end = bus->mem_space.start + PCI_MEM_SIZE - 1; -+ bus->mem_space.name = "PCI Bus #0"; -+ if (request_resource(&iomem_resource, -+ &(bus->mem_space)) != 0) { -+ printk(KERN_ERR "Failed to request bridge iomem resource\n"); -+ return NULL; -+ } -+ -+ /* Request intiator memory resource */ -+ /*bus->io_space.start = 0;*/ -+ bus->io_space.start = HOST_IO_BASE; -+ bus->io_space.end = bus->io_space.start + PCI_IO_SIZE - 1; -+ bus->io_space.name = "PCI Bus #0"; -+ if (request_resource(&ioport_resource, -+ &(bus->io_space)) != 0) { -+ printk(KERN_ERR "Failed to request bridge " -+ "ioport resource\n"); -+ return NULL; -+ } -+ -+ /* Must Reset!!! If bootloader has PCI enabled, it will cause -+ * problem in linux when it tries to configure/find resources -+ * for the pci devices. Both registers need to be reset. -+ */ -+ /*MCF_PCIGSCR |= 0x1;*/ -+ MCF_PCIGSCR = 0x1; -+ MCF_PCITCR = 0x00000000; -+ -+ /* Set up the arbiter */ -+ MCF_PCIARB_PACR = 0; /*MCF_PCIARB_PACR_PKMD*/ -+ -+ /* GNT and REQ */ -+ MCF_PAR_PCIBG = 0x3FF; -+ MCF_PAR_PCIBR = 0x3FF; -+ -+ /* Enable bus mastering, memory access and MWI */ -+ MCF_PCISCR = (MCF_PCISCR_B | MCF_PCISCR_M); -+ -+ /* Setup burst parameters */ -+ /*The offset 0x0e normally was header_type, set it to 0 and fix later*/ -+ MCF_PCICR1 = MCF_PCICR1_LATTIMER(0x00) | -+ MCF_PCICR1_CACHELINESIZE(PCI_CACHE_LINE); -+ -+ MCF_PCICR2 = 0; -+ /*MCF_PCICR2_MINGNT(PCI_MINGNT) | -+ MCF_PCICR2_MAXLAT(PCI_MAXLAT); -+ */ -+ /* Turn on error signaling */ -+ MCF_PCIICR = MCF_PCIICR_TAE | MCF_PCIICR_IAE | PCI_RETRIES; -+ MCF_PCIGSCR |= MCF_PCIGSCR_SEE; -+ /* -+ * Configure Initiator Windows -+ * Window 0: 128M PCI Memory @ HOST_MEM_BASE, 1:1 mapping -+ * Window 1: 64K I/O Memory @ HOST_IO_BASE, 1:0 mapping -+ */ -+ MCF_PCIIW0BTAR = WxBAR(HOST_MEM_BASE, PCI_MEM_BASE, PCI_MEM_SIZE); -+ MCF_PCIIW1BTAR = WxBAR(HOST_IO_BASE, PCI_IO_BASE_ADDR, PCI_IO_SIZE); -+ -+ MCF_PCIIWCR = MCF_PCIIWCR_WINCTRL1_IO | -+ MCF_PCIIWCR_WINCTRL0_MEMREAD; -+ -+ /* Target PCI DMA Windows */ -+ MCF_PCIBAR1 = PCI_DMA_BASE; -+ MCF_PCITBATR1 = HOST_DMA_BASE | MCF_PCITBATR1_EN; -+ -+ /* Enable internal PCI controller interrupts */ -+ MCF_ICR(ISC_PCI_XLB) = ILP_PCI_XLB; -+ /*request_irq(64+ISC_PCI_XLB, xlb_interrupt, -+ SA_INTERRUPT, "PCI XL Bus", (void*)-1); -+ enable_irq (64+ISC_PCI_XLB); -+ */ -+ if (request_irq(64+ISC_PCI_XLB, xlb_interrupt, -+ IRQF_DISABLED, "PCI XL Bus", (void *)-1)) { -+ printk(KERN_ERR "Cannot allocate " -+ "ISC_PCI_XLB IRQ\n"); -+ return (struct pci_bus_info *)-EBUSY; -+ } -+ -+ MCF_ICR(ISC_PCI_ARB) = ILP_PCI_ARB; -+ /*request_irq(64+ISC_PCI_ARB, arb_interrupt, -+ SA_INTERRUPT, "PCI Arbiter", (void*)-1); -+ enable_irq (64+ISC_PCI_ARB); -+ */ -+ if (request_irq(64 + ISC_PCI_ARB, arb_interrupt, -+ IRQF_DISABLED, "PCI Arbiter", (void *)-1)) { -+ printk(KERN_ERR "Cannot allocate " -+ "ISC_PCI_ARB IRQ\n"); -+ return (struct pci_bus_info *)-EBUSY; -+ } -+ -+ /* Set slots interrupt setting */ -+ for (i = 0; i < N_IRQS; i++) { -+ /* Set trailing edge for PCI interrupts */ -+ MCF_EPPAR &= ~MCF_EPPAR_EPPA(irq_lines[i], 0x3); -+ if (irq_lines[i] == 5) -+ MCF_EPPAR |= MCF_EPPAR_EPPA(irq_lines[i], -+ MCF_EPPAR_EPPAx_FALLING); -+ else -+ MCF_EPPAR |= MCF_EPPAR_EPPA(irq_lines[i], -+ 0/*MCF_EPPAR_EPPAx_FALLING*/); -+ /* Turn on irq line in eport */ -+ MCF_EPIER |= MCF_EPIER_EPIE(irq_lines[i]); -+ -+ /* Enable irq in gpio */ -+ if (irq_lines[i] == 5) -+ MCF_PAR_FECI2CIRQ |= 1; -+ -+ if (irq_lines[i] == 6) -+ MCF_PAR_FECI2CIRQ |= 2; -+ -+ /* Register external interrupt handlers */ -+ sprintf(irq_name[i], "PCI IRQ%d", irq_lines[i]); -+ /*request_irq(64 + irq_lines[i], eint_handler, -+ SA_SHIRQ, irq_name[i], (void*)-1); -+ enable_irq(64 + irq_lines[i]);*/ -+ if (request_irq(64 + irq_lines[i], eint_handler, -+ IRQF_SHARED, irq_name[i], (void *)-1)) { -+ printk(KERN_ERR "Cannot allocate " -+ "irq_lines[%d] IRQ\n", -+ irq_lines[i]); -+ return (struct pci_bus_info *)-EBUSY; -+ } -+ } -+ -+ /* Clear PCI Reset and wait for devices to reset */ -+ MCF_PCIGSCR &= ~MCF_PCIGSCR_PR; -+ schedule_timeout((5 * HZ)); -+ /* Remap initiator windows (should be 1:1 to the physical memory) */ -+ pci_mem_va = (int) ioremap_nocache(HOST_MEM_BASE, -+ PCI_MEM_SIZE + PCI_IO_SIZE); -+ udelay(1000); /* let every thing effect */ -+#if 1 -+ printk(KERN_INFO "%s: MEMBase_phy %x, Virt %x, len %x\n", -+ __func__, HOST_MEM_BASE, pci_mem_va, -+ PCI_MEM_SIZE + PCI_IO_SIZE); -+#endif -+ BUG_ON(pci_mem_va != HOST_MEM_BASE); -+ -+ /* Setup bios32 and pci bus driver callbacks */ -+ bus->m68k_pci_ops = &bus_ops; -+ bus->fixup = coldfire_fixup; -+ bus->conf_device = configure_device; -+ -+ return bus; -+} ---- /dev/null -+++ b/arch/m68k/coldfire/m547x/pci_dummy.S -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved. -+ * Author: Jason Jin <Jason.jin@freescale.com> -+ * -+ * This routine is the dummy function for PCI errata -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+ -+.global _pci_dummy_function -+.global pci_dummy_function -+.text -+ -+pci_dummy_function: -+_pci_dummy_function: -+ -+/* force function start to 16-byte boundary.Can be done in linker file also */ -+.align 16 -+clr.l %d0 -+move.l %d0, 0xF0000F0C -+/* Must use direct addressing. write to EPORT module -+* xlbus -> slavebus -> eport, writing '0' to register has no -+* effect -+*/ -+ -+rts -+tpf.l #0x0 -+tpf.l #0x0 -+tpf.l #0x0 -+tpf.l #0x0 -+tpf.l #0x0 -+.end ---- /dev/null -+++ b/arch/m68k/include/asm/5445x_pci.h -@@ -0,0 +1,111 @@ -+/* -+ * asm-m68k/pci.h - m68k specific PCI declarations. -+ * -+ * Copyright (C) 2007, 2009-2011 Freescale Semiconductor, Inc. -+ * All Rights Reserved. -+ * Kurt Mahan <kmahan@freescale.com> -+ */ -+#ifndef _ASM_M68K_5445X_PCI_H -+#define _ASM_M68K_5445x_PCI_H -+ -+#ifndef CONFIG_PCI -+/* -+ * The PCI address space does equal the physical memory -+ * address space. The networking and block device layers use -+ * this boolean for bounce buffer decisions. -+ */ -+#define PCI_DMA_BUS_IS_PHYS (1) -+#else -+#include <asm-generic/pci-dma-compat.h> -+ -+#define PCI_DMA_BASE 0 /* PCI-DMA window base */ -+#define NL_ORIGINAL -+/* -+ * The PCI address space does equal the physical memory -+ * address space. The networking and block device layers use -+ * this boolean for bounce buffer decisions. -+ */ -+#define PCI_DMA_BUS_IS_PHYS (1) -+ -+#define PCIBIOS_MIN_IO 0x00004000 -+#define PCIBIOS_MIN_MEM 0x02000000 -+ -+#define pcibios_assign_all_busses() 0 -+#define pcibios_scan_all_fns(a, b) 0 -+ -+struct pci_raw_ops { -+ int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, -+ int reg, int len, u32 *val); -+ int (*write)(unsigned int domain, unsigned int bus, unsigned int devfn, -+ int reg, int len, u32 val); -+}; -+ -+extern struct pci_raw_ops *raw_pci_ops; -+ -+static inline void -+pcibios_set_master(struct pci_dev *dev) -+{ -+ /* no special bus mastering setup handling */ -+} -+ -+static inline void -+pcibios_penalize_isa_irq(int irq, int active) -+{ -+ /* no dynamic PCI IRQ allocation */ -+} -+ -+#if 0 -+static inline void -+pcibios_add_platform_entries(struct pci_dev *dev) -+{ -+ /* no special handling */ -+} -+#endif -+ -+static inline void -+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, -+ struct resource *res) -+{ -+ region->start = res->start; -+ region->end = res->end; -+} -+ -+static inline void -+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, -+ struct pci_bus_region *region) -+{ -+ res->start = region->start; -+ res->end = region->end; -+} -+ -+static inline struct resource * -+pcibios_select_root(struct pci_dev *pdev, struct resource *res) -+{ -+ struct resource *root = NULL; -+ -+ if (res->flags & IORESOURCE_IO) -+ root = &ioport_resource; -+ if (res->flags & IORESOURCE_MEM) -+ root = &iomem_resource; -+ -+ return root; -+} -+ -+#ifndef CONFIG_M54455_PCI_initcall -+extern int pci_init(void); -+extern int pcibios_init(void); -+#endif -+ -+extern void set_fpga(u32 *addr, u32 val); -+ -+#ifdef CONFIG_M54455 -+extern int init_mcf5445x_pci(void); -+extern void mcf5445x_conf_device(struct pci_dev *dev); -+extern void mcf5445x_pci_dumpregs(void); -+ -+extern struct resource pci_ioport_resource; -+extern struct resource pci_iomem_resource; -+#endif -+ -+#endif /* CONFIG_PCI */ -+#endif /* _ASM_M68K_5445X_PCI_H */ ---- /dev/null -+++ b/arch/m68k/include/asm/548x_pci.h -@@ -0,0 +1,99 @@ -+/* -+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved. -+ * Written by Wout Klaren. -+ */ -+ -+#ifndef _ASM_M68K_548X_PCI_H -+#define _ASM_M68K_548X_PCI_H -+ -+#include <linux/mm.h> -+#include <asm/scatterlist.h> -+ -+#include <asm-generic/pci.h> -+ -+struct pci_ops; -+ -+/* -+ * Structure with hardware dependent information and functions of the -+ * PCI bus. -+ */ -+ -+struct pci_bus_info { -+ /* -+ * Resources of the PCI bus. -+ */ -+ -+ struct resource mem_space; -+ struct resource io_space; -+ -+ /* -+ * System dependent functions. -+ */ -+ -+ struct pci_ops *m68k_pci_ops; -+ -+ void (*fixup)(int pci_modify); -+ void (*conf_device)(struct pci_dev *dev); -+}; -+ -+#define pcibios_assign_all_busses() 0 -+#define pcibios_scan_all_fns(a, b) 0 -+ -+static inline void pcibios_set_master(struct pci_dev *dev) -+{ -+ /* No special bus mastering setup handling */ -+} -+ -+static inline void pcibios_penalize_isa_irq(int irq) -+{ -+ /* We don't do dynamic PCI IRQ allocation */ -+} -+ -+#ifndef CONFIG_COLDFIRE -+/* The PCI address space does equal the physical memory -+ * address space. The networking and block device layers use -+ * this boolean for bounce buffer decisions. -+ */ -+#define PCI_DMA_BUS_IS_PHYS (1) -+ -+#define PCIBIOS_MIN_IO 0x00004000 -+#define PCIBIOS_MIN_MEM 0x04000000 -+ -+#else /* !CONFIG_COLDFIRE */ -+#include <asm-generic/pci-dma-compat.h> -+#define PCI_DMA_BASE /*0x40000000*/0 -+/* PCI-DMA window base */ -+ -+extern struct pci_bus_info *__init init_coldfire_pci(void); -+extern void *pci_alloc_son(struct pci_dev *, size_t, -+ dma_addr_t *, int); -+/* -+ * The PCI address space equal the virtual memory -+ * address space on m547X/m548X. -+ */ -+#define PCI_DMA_BUS_IS_PHYS (1) -+ -+#define PCIBIOS_MIN_IO 0x00000100 -+#define PCIBIOS_MIN_MEM 0x02000000 -+ -+struct scatterlist; -+ -+ -+/* This is always fine. */ -+#define pci_dac_dma_supported(pci_dev, mask) (1) -+ -+ -+/* These macros should be used after a pci_map_sg call has been done -+ * to get bus addresses of each of the SG entries and their lengths. -+ * You should only work with the number of sg entries pci_map_sg -+ * returns. -+ */ -+#define sg_dma_address(sg) ((sg)->dma_address) -+#define sg_dma_len(sg) ((sg)->length) -+ -+extern void pci_dummy_function(void); -+/*Declarations of hardware specific initialisation functions*/ -+extern struct pci_bus_info *init_hades_pci(void); -+ -+#endif /* !CONFIG_COLDFIRE*/ -+#endif /* _ASM_M68K_548X_PCI_H */ ---- a/arch/m68k/include/asm/pci.h -+++ b/arch/m68k/include/asm/pci.h -@@ -1,7 +1,13 @@ - #ifndef _ASM_M68K_PCI_H - #define _ASM_M68K_PCI_H - -+#if defined(CONFIG_M5445X) -+#include "5445x_pci.h" -+#elif defined(CONFIG_M547X_8X) -+#include "548x_pci.h" -+#else - #include <asm-generic/pci-dma-compat.h> -+#endif - - /* The PCI address space does equal the physical memory - * address space. The networking and block device layers use ---- /dev/null -+++ b/arch/m68k/kernel/bios32_mcf548x.c -@@ -0,0 +1,632 @@ -+/* -+ * bios32.c - PCI BIOS functions for m68k systems. -+ * -+ * Written by Wout Klaren. -+ * -+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved. -+ * Shrek Wu B16972@freescale.com -+ * -+ * Based on the DEC Alpha bios32.c by Dave Rusling and David Mosberger. -+ */ -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/device.h> -+#include <linux/delay.h> -+ -+# define DBG_DEVS(args) -+ -+#ifdef CONFIG_PCI -+ -+/* -+ * PCI support for Linux/m68k. Currently only the Hades is supported. -+ * -+ * The support for PCI bridges in the DEC Alpha version has -+ * been removed in this version. -+ */ -+ -+#include <linux/pci.h> -+#include <linux/slab.h> -+#include <linux/mm.h> -+ -+#include <asm/io.h> -+#include <asm/pci.h> -+#include <asm/uaccess.h> -+ -+#define KB 1024 -+#define MB (1024*KB) -+#define GB (1024*MB) -+ -+#define MAJOR_REV 0 -+#define MINOR_REV 5 -+ -+/* -+ * Align VAL to ALIGN, which must be a power of two. -+ */ -+ -+#define MAX(val1, val2) (((val1) > (val2)) ? val1 : val2) -+ -+/* -+ * Offsets relative to the I/O and memory base addresses from where resources -+ * are allocated. -+ */ -+ -+#ifdef CONFIG_COLDFIRE -+#define IO_ALLOC_OFFSET 0x00000100 -+#define MEM_ALLOC_OFFSET 0x00000000 -+#else /* CONFIG_COLDFIRE */ -+#define IO_ALLOC_OFFSET 0x00004000 -+#define MEM_ALLOC_OFFSET 0x04000000 -+#endif /* CONFIG_COLDFIRE */ -+ -+/* -+ * Bus info structure of the PCI bus. A pointer to this structure is -+ * put in the sysdata member of the pci_bus structure. -+ */ -+ -+static struct pci_bus_info *bus_info; -+ -+static int pci_modify = 1; -+/* If set, layout the PCI bus ourself. */ -+static int skip_vga; -+/* If set do not modify base addresses of vga cards.*/ -+static int disable_pci_burst; -+/* If set do not allow PCI bursts. */ -+ -+static volatile unsigned int io_base; -+static volatile unsigned int mem_base; -+ -+/* -+ * static void disable_dev(struct pci_dev *dev) -+ * -+ * Disable PCI device DEV so that it does not respond to I/O or memory -+ * accesses. -+ * -+ * Parameters: -+ * -+ * dev - device to disable. -+ */ -+ -+static void __init disable_dev(struct pci_dev *dev) -+{ -+ unsigned short cmd; -+ -+ if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) || -+ (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) || -+ (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga) -+ return; -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ -+ cmd &= (~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY & ~PCI_COMMAND_MASTER); -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+} -+ -+/* Stolen from pcibios_enable_resources/i386 */ -+int pcibios_enable_device(struct pci_dev *dev, int mask) -+{ -+ u16 cmd, old_cmd; -+ int idx; -+ struct resource *r; -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ old_cmd = cmd; -+ for (idx = 0; idx < 6; idx++) { -+ /* Only set up the requested stuff */ -+ if (!(mask & (1<<idx))) -+ continue; -+ -+ r = &dev->resource[idx]; -+ if (!r->start && r->end) { -+ printk(KERN_ERR "PCI: Device %s not" -+ " available because" -+ " of resource collisions\n", -+ dev_name(&(dev->dev))); -+ return -EINVAL; -+ } -+ if (r->flags & IORESOURCE_IO) -+ cmd |= PCI_COMMAND_IO; -+ if (r->flags & IORESOURCE_MEM) -+ cmd |= PCI_COMMAND_MEMORY; -+ } -+ if (dev->resource[PCI_ROM_RESOURCE].start) -+ cmd |= PCI_COMMAND_MEMORY; -+ if (cmd != old_cmd) { -+ printk(KERN_ERR "PCI: Enabling device " -+ "%s (%04x -> %04x)\n", -+ dev_name(&(dev->dev)), old_cmd, cmd); -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ } -+ return 0; -+} -+ -+/* -+ * static void layout_dev(struct pci_dev *dev) -+ * -+ * Layout memory and I/O for a device. -+ * -+ * Parameters: -+ * -+ * device - device to layout memory and I/O for. -+ */ -+ -+static void __init layout_dev(struct pci_dev *dev) -+{ -+ unsigned short cmd; -+ unsigned int base, mask, size, reg; -+ unsigned int alignto; -+ int i; -+ -+ /* -+ * Skip video cards if requested. -+ */ -+ if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) || -+ (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) || -+ (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga) { -+ printk(KERN_ERR "%s: VGA\n", __func__); -+ return; -+ } -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ -+ for (reg = PCI_BASE_ADDRESS_0, i = 0; -+ reg <= PCI_BASE_ADDRESS_5; reg += 4, i++) { -+ /* -+ * Figure out how much space and of what type this -+ * device wants. -+ */ -+ -+ pci_write_config_dword(dev, reg, 0xffffffff); -+ pci_read_config_dword(dev, reg, &base); -+ if (!base) { -+ /* this base-address register is unused */ -+ dev->resource[i].start = 0; -+ dev->resource[i].end = 0; -+ dev->resource[i].flags = 0; -+ continue; -+ } -+ -+ /* -+ * We've read the base address register back after -+ * writing all ones and so now we must decode it. -+ */ -+ if (base & PCI_BASE_ADDRESS_SPACE_IO) { -+ /* -+ * I/O space base address register. -+ */ -+ -+ cmd |= PCI_COMMAND_IO; -+ -+ base &= PCI_BASE_ADDRESS_IO_MASK; -+ mask = (~base << 1) | 0x1; -+ size = (mask & base) & 0xffffffff; -+ -+ /* -+ * Align to multiple of size of minimum base. -+ */ -+ -+#ifdef CONFIG_COLDFIRE -+ alignto = MAX(PAGE_SIZE, size) ; -+#else /* !CONFIG_COLDFIRE */ -+ alignto = MAX(0x040, size) ; -+#endif /* CONFIG_COLDFIRE */ -+ base = ALIGN(io_base, alignto); -+ io_base = base + size; -+ pci_write_config_dword(dev, reg, -+ base | PCI_BASE_ADDRESS_SPACE_IO); -+ dev->resource[i].start = base; -+ dev->resource[i].end = -+ dev->resource[i].start + size - 1; -+ dev->resource[i].flags = -+ IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; -+ -+ DBG_DEVS(("layout_dev: IO address: %x\n", base)); -+ } else { -+ unsigned int type; -+ -+ /* -+ * Memory space base address register. -+ */ -+ cmd |= PCI_COMMAND_MEMORY; -+ -+ type = base & PCI_BASE_ADDRESS_MEM_TYPE_MASK; -+ base &= PCI_BASE_ADDRESS_MEM_MASK; -+ mask = (~base << 1) | 0x1; -+ size = (mask & base) & 0xffffffff; -+ switch (type) { -+ case PCI_BASE_ADDRESS_MEM_TYPE_32: -+ case PCI_BASE_ADDRESS_MEM_TYPE_64: -+ break; -+ -+ case PCI_BASE_ADDRESS_MEM_TYPE_1M: -+ printk(KERN_INFO "bios32 WARNING: slot %d," -+ " function %d " -+ "requests memory below 1MB---don't " -+ "know how to do that.\n", -+ PCI_SLOT(dev->devfn), -+ PCI_FUNC(dev->devfn)); -+ continue; -+ } -+ DBG_DEVS(("%s MEM: base %x,type %x,mask %x,size %x\n", -+ __func__, base, type, mask, size)); -+ /* -+ * Align to multiple of size of minimum base. -+ */ -+ -+ alignto = max_t(unsigned int, 0x1000, size); -+ base = ALIGN(mem_base, alignto); -+ mem_base = base + size; -+ pci_write_config_dword(dev, reg, base); -+ dev->resource[i].start = base; -+ dev->resource[i].end = -+ dev->resource[i].start + size - 1; -+ dev->resource[i].flags = IORESOURCE_MEM; -+ -+ DBG_DEVS(("%s MEM :base %x,size %x\n", -+ __func__, base, size)); -+ if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) { -+ /* -+ * 64-bit address, set the highest 32 bits -+ * to zero. -+ */ -+ -+ reg += 4; -+ pci_write_config_dword(dev, reg, 0); -+ -+ i++; -+ dev->resource[i].start = 0; -+ dev->resource[i].end = 0; -+ dev->resource[i].flags = 0; -+ printk(KERN_ERR "%s:type == 64\n", __func__); -+ } -+ } -+ } -+ /* -+ * Enable device: -+ */ -+ if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED || -+ dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA || -+ dev->class >> 8 == PCI_CLASS_DISPLAY_VGA || -+ dev->class >> 8 == PCI_CLASS_DISPLAY_XGA) { -+ /* -+ * All of these (may) have I/O scattered all around -+ * and may not use i/o-base address registers at all. -+ * So we just have to always enable I/O to these -+ * devices. -+ */ -+ cmd |= PCI_COMMAND_IO; -+ pci_write_config_word(dev, PCI_COMMAND, -+ cmd | PCI_COMMAND_MASTER); -+ } -+ -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, -+ (disable_pci_burst) ? 0 : 32); -+ -+ if (bus_info != NULL) -+ bus_info->conf_device(dev); -+ /* Machine dependent configuration. */ -+ -+ printk(KERN_INFO "layout_dev: bus %d slot 0x%x " -+ "VID 0x%x DID 0x%x class 0x%x\n", -+ dev->bus->number, PCI_SLOT(dev->devfn), -+ dev->vendor, dev->device, dev->class); -+} -+ -+/* -+ * static void layout_bus(struct pci_bus *bus) -+ * -+ * Layout memory and I/O for all devices on the given bus. -+ * -+ * Parameters: -+ * -+ * bus - bus. -+ */ -+ -+static void __init layout_bus(struct pci_bus *bus) -+{ -+ unsigned int bio, bmem; -+ struct pci_dev *dev; -+ -+ DBG_DEVS(("layout_bus: starting bus %d\n", bus->number)); -+ -+ if (list_empty(&bus->devices) && list_empty(&bus->children)) -+ return; -+ -+ /* -+ * Align the current bases on appropriate boundaries (4K for -+ * IO and 1MB for memory). -+ */ -+ -+ bio = io_base = ALIGN(io_base, 4*KB); -+ bmem = mem_base = ALIGN(mem_base, 1*MB); -+ -+ /* -+ * PCI devices might have been setup by a PCI BIOS emulation -+ * running under TOS. In these cases there is a -+ * window during which two devices may have an overlapping -+ * address range. To avoid this causing trouble, we first -+ * turn off the I/O and memory address decoders for all PCI -+ * devices. They'll be re-enabled only once all address -+ * decoders are programmed consistently. -+ */ -+ -+ DBG_DEVS(("layout_bus: disable_dev for bus %d\n", bus->number)); -+ -+#ifdef NL_ORIGINAL -+ for (dev = bus->devices; dev; dev = dev->sibling) { -+#else -+ dev = NULL; -+ while ((dev = pci_get_device( -+ PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { -+#endif -+ if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) || -+ (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) -+ disable_dev(dev); -+ } -+ -+ /* -+ * Allocate space to each device: -+ */ -+ -+ DBG_DEVS(("layout_bus: starting bus %d devices\n", bus->number)); -+ -+#ifdef NL_ORIGINAL -+ for (dev = bus->devices; dev; dev = dev->sibling) { -+#else -+ dev = NULL; -+ while ((dev = pci_get_device( -+ PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { -+#endif -+ -+ if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) || -+ (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) -+ layout_dev(dev); -+ } -+ -+ DBG_DEVS(("layout_bus: bus %d finished\n", bus->number)); -+} -+ -+/* -+ * static void pcibios_fixup(void) -+ * -+ * Layout memory and I/O of all devices on the PCI bus if 'pci_modify' is -+ * true. This might be necessary because not every m68k machine with a PCI -+ * bus has a PCI BIOS. This function should be called right after -+ * pci_scan_bus() in pcibios_init(). -+ */ -+ -+static void __init pcibios_fixup(void) -+{ -+ DBG_DEVS(("%s\n", __func__)); -+ if (pci_modify) { -+ /* -+ * Set base addresses for allocation of I/O and memory space. -+ */ -+ -+ io_base = bus_info->io_space.start + IO_ALLOC_OFFSET; -+ mem_base = bus_info->mem_space.start + MEM_ALLOC_OFFSET; -+ -+ /* -+ * Scan the tree, allocating PCI memory and I/O space. -+ */ -+ -+#ifdef NL_ORIGINAL -+ layout_bus(pci_bus_b(pci_root.next)); -+#else -+ layout_bus(pci_bus_b(pci_root_buses.next)); -+#endif -+ } -+ -+ /* -+ * Fix interrupt assignments, etc. -+ */ -+ -+ bus_info->fixup(pci_modify); -+} -+ -+/* -+ * static void pcibios_claim_resources(struct pci_bus *bus) -+ * -+ * Claim all resources that are assigned to devices on the given bus. -+ * -+ * Parameters: -+ * -+ * bus - bus. -+ */ -+ -+static void __init pcibios_claim_resources(struct pci_bus *bus) -+{ -+ struct pci_dev *dev; -+ int i; -+ DBG_DEVS(("%s\n", __func__)); -+#ifdef NL_ORIGINAL -+ while (bus) { -+#else -+ while ((bus = pci_find_next_bus(bus)) != NULL) { -+#endif -+ -+#ifdef NL_ORIGINAL -+ for (dev = bus->devices; (dev != NULL); -+ dev = dev->sibling) { -+#else -+ dev = NULL; -+ while ((dev = pci_get_device( -+ PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { -+#endif -+ for (i = 0; i < PCI_NUM_RESOURCES; i++) { -+ struct resource *r = &dev->resource[i]; -+ struct resource *pr; -+ struct pci_bus_info *bus_info = -+ (struct pci_bus_info *)dev->sysdata; -+ -+ if ((r->start == 0) || (r->parent != NULL)) -+ continue; -+ -+#ifdef CONFIG_COLDFIRE -+ if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) -+ continue; -+#endif /* CONFIG_COLDFIRE */ -+#if 1 -+ if (r->flags & IORESOURCE_IO) -+ pr = &bus_info->io_space; -+ else -+ pr = &bus_info->mem_space; -+#else -+ if (r->flags & IORESOURCE_IO) -+ pr = &ioport_resource; -+ else -+ pr = &iomem_resource; -+#endif -+ if (request_resource(pr, r) < 0) { -+#ifdef NL_ORIGINAL -+ DBG_DEVS(("PCI: Address space" -+ " collision on " -+ "region %d of device %s\n", -+ i, dev->name)); -+#else -+ printk(KERN_INFO "PCI: Address space" -+ " collision on region %d of" -+ " device %s\n", -+ i, dev_name(&(dev->dev))); -+#endif -+ } -+ } -+ -+#ifdef NL_ORIGINAL -+ } -+ if (bus->children) -+ pcibios_claim_resources(bus->children); -+#else -+ } -+ if (!list_empty(&bus->children)) -+ pcibios_claim_resources(pci_bus_b(bus->children.next)); -+#endif -+ -+#ifdef NL_ORIGINAL -+ bus = bus->next; -+#endif -+ } -+} -+ -+/* -+ * int pcibios_assign_resource(struct pci_dev *dev, int i) -+ * -+ * Assign a new address to a PCI resource. -+ * -+ * Parameters: -+ * -+ * dev - device. -+ * i - resource. -+ * -+ * Result: 0 if successful. -+ */ -+ -+int __init pcibios_assign_resource(struct pci_dev *dev, int i) -+{ -+ struct resource *r = &dev->resource[i]; -+ struct resource *pr = pci_find_parent_resource(dev, r); -+ unsigned long size = r->end + 1; -+ DBG_DEVS(("%s:IO_ALLOC_OFFSET %x\n", __func__, IO_ALLOC_OFFSET)); -+ if (!pr) -+ return -EINVAL; -+ -+ if (r->flags & IORESOURCE_IO) { -+ DBG_DEVS(("%s:IORESOURCE_IO:start %x, size %lx\n", -+ __func__, bus_info->io_space.start, size)); -+ if (size > 0x100) -+ return -EFBIG; -+ -+#ifdef NL_ORIGINAL -+ if (allocate_resource(pr, r, size, bus_info->io_space.start + -+ IO_ALLOC_OFFSET, -+ bus_info->io_space.end, -+ 1024)) -+#else -+ if (allocate_resource(pr, r, size, bus_info->io_space.start + -+ IO_ALLOC_OFFSET, -+ bus_info->io_space.end, -+ 1024, NULL, NULL)) -+#endif -+ return -EBUSY; -+ } else { -+ DBG_DEVS(("%s:IORESOURCE_MEM:start %x, size %lx\n", -+ __func__, bus_info->mem_space.start, size)); -+#ifdef NL_ORIGINAL -+ if (allocate_resource(pr, r, size, bus_info->mem_space.start + -+ MEM_ALLOC_OFFSET, -+ bus_info->mem_space.end, size)) -+#else -+ if (allocate_resource(pr, r, size, bus_info->io_space.start + -+ IO_ALLOC_OFFSET, bus_info->io_space.end, -+ 1024, NULL, NULL)) -+#endif -+ return -EBUSY; -+ } -+ -+ if (i < 6) -+ pci_write_config_dword(dev, -+ PCI_BASE_ADDRESS_0 + 4 * i, r->start); -+ -+ return 0; -+} -+ -+void pcibios_fixup_bus(struct pci_bus *bus) -+{ -+ struct pci_dev *dev; -+ void *sysdata; -+ -+ sysdata = (bus->parent) ? bus->parent->sysdata : bus->sysdata; -+ -+#ifdef NL_ORIGINAL -+ for (dev = bus->devices; (dev != NULL); dev = dev->sibling) -+#else -+ dev = NULL; -+ while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) -+#endif -+ dev->sysdata = sysdata; -+} -+ -+int __init pcibios_init(void) -+{ -+ printk(KERN_INFO "Linux/m68k PCI BIOS32 " -+ "revision %x.%02x\n", MAJOR_REV, MINOR_REV); -+ -+ bus_info = NULL; -+#ifdef CONFIG_COLDFIRE -+ bus_info = init_coldfire_pci(); -+#endif /* CONFIG_COLDFIRE */ -+#ifdef CONFIG_HADES -+ if (MACH_IS_HADES) -+ bus_info = init_hades_pci(); -+#endif -+ if (bus_info != NULL) { -+ printk(KERN_ERR "PCI: Probing PCI hardware\n"); -+ pci_scan_bus(0, bus_info->m68k_pci_ops, bus_info); -+ pcibios_fixup(); -+#ifdef NL_ORIGINAL -+ pcibios_claim_resources(pci_root); -+#else -+ pcibios_claim_resources(pci_bus_b(pci_root_buses.next)); -+#endif -+ } else -+ printk(KERN_ERR "PCI: No PCI bus detected\n"); -+ return 0; -+} -+ -+subsys_initcall(pcibios_init); -+ -+char *pcibios_setup(char *str) -+{ -+ if (!strcmp(str, "nomodify")) { -+ pci_modify = 0; -+ return NULL; -+ } else if (!strcmp(str, "skipvga")) { -+ skip_vga = 1; -+ return NULL; -+ } else if (!strcmp(str, "noburst")) { -+ disable_pci_burst = 1; -+ return NULL; -+ } -+ -+ return str; -+} -+#endif /* CONFIG_PCI */ ---- a/drivers/pci/Makefile -+++ b/drivers/pci/Makefile -@@ -50,6 +50,7 @@ obj-$(CONFIG_X86_VISWS) += setup-irq.o - obj-$(CONFIG_MN10300) += setup-bus.o - obj-$(CONFIG_MICROBLAZE) += setup-bus.o - obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o -+obj-$(CONFIG_M54455) += setup-bus.o setup-irq.o - - # - # ACPI Related PCI FW Functions ---- a/drivers/pci/access.c -+++ b/drivers/pci/access.c -@@ -25,6 +25,7 @@ static DEFINE_RAW_SPINLOCK(pci_lock); - #define PCI_word_BAD (pos & 1) - #define PCI_dword_BAD (pos & 3) - -+#ifdef NL_ORIGINAL - #define PCI_OP_READ(size,type,len) \ - int pci_bus_read_config_##size \ - (struct pci_bus *bus, unsigned int devfn, int pos, type *value) \ -@@ -39,6 +40,23 @@ int pci_bus_read_config_##size \ - raw_spin_unlock_irqrestore(&pci_lock, flags); \ - return res; \ - } -+#else /* NL_ORIGINAL */ -+#define PCI_OP_READ(size, type, len) \ -+ int pci_bus_read_config_##size \ -+ (struct pci_bus *bus, unsigned int devfn, \ -+ int pos, type * value) \ -+{ \ -+ int res; \ -+ unsigned long flags; \ -+ if (PCI_##size##_BAD) \ -+ return PCIBIOS_BAD_REGISTER_NUMBER; \ -+ raw_spin_lock_irqsave(&pci_lock, flags); \ -+ res = bus->ops->read( \ -+ bus, devfn, pos, len, (u32 *)value); \ -+ raw_spin_unlock_irqrestore(&pci_lock, flags); \ -+ return res; \ -+} -+#endif /* NL_ORIGINAL */ - - #define PCI_OP_WRITE(size,type,len) \ - int pci_bus_write_config_##size \ ---- a/drivers/pci/setup-bus.c -+++ b/drivers/pci/setup-bus.c -@@ -77,7 +77,13 @@ static void __dev_sort_resources(struct - u16 class = dev->class >> 8; - - /* Don't touch classless devices or host bridges or ioapics. */ -+#ifdef CONFIG_M5445X -+ if (class == PCI_CLASS_NOT_DEFINED || \ -+ class == PCI_CLASS_BRIDGE_HOST || \ -+ class == PCI_CLASS_BRIDGE_OTHER) -+#else - if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST) -+#endif - return; - - /* Don't touch ioapic devices already enabled by firmware */ ---- a/lib/iomap.c -+++ b/lib/iomap.c -@@ -227,9 +227,13 @@ EXPORT_SYMBOL(iowrite32_rep); - /* Create a virtual mapping cookie for an IO port range */ - void __iomem *ioport_map(unsigned long port, unsigned int nr) - { -+#ifndef CONFIG_M54455 - if (port > PIO_MASK) - return NULL; - return (void __iomem *) (unsigned long) (port + PIO_OFFSET); -+#else -+ return (void __iomem *) (unsigned long) port; -+#endif - } - - void ioport_unmap(void __iomem *addr) |