From 25c3e17436068c7d949bcbd5b3fe6e623e683215 Mon Sep 17 00:00:00 2001 From: Mike Baker Date: Thu, 2 Feb 2006 23:38:35 +0000 Subject: [PATCH] split patch; start irq cleanup SVN-Revision: 3117 --- .../linux/aruba-2.6/patches/000-aruba.patch | 1266 ----------------- .../linux/aruba-2.6/patches/001-flash.patch | 159 +++ .../linux/aruba-2.6/patches/002-irq.patch | 488 +++++++ .../linux/aruba-2.6/patches/003-pci.patch | 618 ++++++++ 4 files changed, 1265 insertions(+), 1266 deletions(-) create mode 100644 openwrt/target/linux/aruba-2.6/patches/001-flash.patch create mode 100644 openwrt/target/linux/aruba-2.6/patches/002-irq.patch create mode 100644 openwrt/target/linux/aruba-2.6/patches/003-pci.patch diff --git a/openwrt/target/linux/aruba-2.6/patches/000-aruba.patch b/openwrt/target/linux/aruba-2.6/patches/000-aruba.patch index ce9cf2289f..f25523044d 100644 --- a/openwrt/target/linux/aruba-2.6/patches/000-aruba.patch +++ b/openwrt/target/linux/aruba-2.6/patches/000-aruba.patch @@ -1,523 +1,3 @@ -diff -Nur linux-2.6.15/arch/mips/aruba/flash_lock.c linux-2.6.15-openwrt/arch/mips/aruba/flash_lock.c ---- linux-2.6.15/arch/mips/aruba/flash_lock.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.15-openwrt/arch/mips/aruba/flash_lock.c 2006-01-10 00:32:32.000000000 +0100 -@@ -0,0 +1,27 @@ -+#include -+#include -+#include -+ -+#define AP70_PROT_ADDR 0xb8010008 -+#define AP70_PROT_DATA 0x8 -+#define AP60_PROT_ADDR 0xB8400000 -+#define AP60_PROT_DATA 0x04000000 -+ -+void unlock_ap60_70_flash(void) -+{ -+ volatile __u32 val; -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ val = *(volatile __u32 *)AP70_PROT_ADDR; -+ val &= ~(AP70_PROT_DATA); -+ *(volatile __u32 *)AP70_PROT_ADDR = val; -+ break; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ val = *(volatile __u32 *)AP60_PROT_ADDR; -+ val &= ~(AP60_PROT_DATA); -+ *(volatile __u32 *)AP60_PROT_ADDR = val; -+ break; -+ } -+} -diff -Nur linux-2.6.15/arch/mips/aruba/idtIRQ.S linux-2.6.15-openwrt/arch/mips/aruba/idtIRQ.S ---- linux-2.6.15/arch/mips/aruba/idtIRQ.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.15-openwrt/arch/mips/aruba/idtIRQ.S 2006-01-10 00:32:32.000000000 +0100 -@@ -0,0 +1,87 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * Intterrupt dispatcher code for IDT boards -+ * -+ * Copyright 2004 IDT Inc. (rischelp@idt.com) -+ * -+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * 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. -+ * -+ * -+ ************************************************************************** -+ * May 2004 rkt, neb -+ * -+ * Initial Release -+ * -+ * -+ * -+ ************************************************************************** -+ */ -+ -+ -+#include -+#include -+#include -+#include -+ -+ .text -+ .set noreorder -+ .set noat -+ .align 5 -+ NESTED(idtIRQ, PT_SIZE, sp) -+ .set noat -+ SAVE_ALL -+ CLI -+ -+ .set at -+ .set noreorder -+ -+ /* Get the pending interrupts */ -+ mfc0 t0, CP0_CAUSE -+ nop -+ -+ /* Isolate the allowed ones by anding the irq mask */ -+ mfc0 t2, CP0_STATUS -+ move a1, sp /* need a nop here, hence we anticipate */ -+ andi t0, CAUSEF_IP -+ and t0, t2 -+ -+ /* check for r4k counter/timer IRQ. */ -+ -+ andi t1, t0, CAUSEF_IP7 -+ beqz t1, 1f -+ nop -+ -+ jal aruba_timer_interrupt -+ -+ li a0, 7 -+ -+ j ret_from_irq -+ nop -+1: -+ jal aruba_irqdispatch -+ move a0, t0 -+ j ret_from_irq -+ nop -+ -+ END(idtIRQ) -+ -+ -diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/aruba/irq.c ---- linux-2.6.15/arch/mips/aruba/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.15-openwrt/arch/mips/aruba/irq.c 2006-01-10 00:32:32.000000000 +0100 -@@ -0,0 +1,394 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * Interrupt routines for IDT EB434 boards -+ * -+ * Copyright 2004 IDT Inc. (rischelp@idt.com) -+ * -+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * 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. -+ * -+ * -+ ************************************************************************** -+ * May 2004 rkt, neb -+ * -+ * Initial Release -+ * -+ * -+ * -+ ************************************************************************** -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#undef DEBUG_IRQ -+#ifdef DEBUG_IRQ -+/* note: prints function name for you */ -+#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) -+#else -+#define DPRINTK(fmt, args...) -+#endif -+ -+extern asmlinkage void idtIRQ(void); -+static unsigned int startup_irq(unsigned int irq); -+static void end_irq(unsigned int irq_nr); -+static void mask_and_ack_irq(unsigned int irq_nr); -+static void aruba_enable_irq(unsigned int irq_nr); -+static void aruba_disable_irq(unsigned int irq_nr); -+ -+extern void __init init_generic_irq(void); -+ -+typedef struct { -+ u32 mask; -+ volatile u32 *base_addr; -+} intr_group_t; -+ -+static const intr_group_t intr_group_merlot[NUM_INTR_GROUPS] = { -+ {0xffffffff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 0)}, -+}; -+ -+#define READ_PEND_MERLOT(base) (*((volatile unsigned long *)(0xbc003010))) -+#define READ_MASK_MERLOT(base) (*((volatile unsigned long *)(0xbc003010 + 4))) -+#define WRITE_MASK_MERLOT(base, val) ((*((volatile unsigned long *)((0xbc003010) + 4))) = (val)) -+ -+static const intr_group_t intr_group_muscat[NUM_INTR_GROUPS] = { -+ {0x0000efff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 0 * IC_GROUP_OFFSET)}, -+ {0x00001fff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 1 * IC_GROUP_OFFSET)}, -+ {0x00000007, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 2 * IC_GROUP_OFFSET)}, -+ {0x0003ffff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 3 * IC_GROUP_OFFSET)}, -+ {0xffffffff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 4 * IC_GROUP_OFFSET)} -+}; -+ -+#define READ_PEND_MUSCAT(base) (*(base)) -+#define READ_MASK_MUSCAT(base) (*(base + 2)) -+#define WRITE_MASK_MUSCAT(base, val) (*(base + 2) = (val)) -+ -+static inline int irq_to_group(unsigned int irq_nr) -+{ -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ return ((irq_nr - GROUP0_IRQ_BASE) >> 5); -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ return 0; -+ } -+} -+ -+static inline int group_to_ip(unsigned int group) -+{ -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ return group + 2; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ return 6; -+ } -+} -+ -+static inline void enable_local_irq(unsigned int ip) -+{ -+ int ipnum = 0x100 << ip; -+ clear_c0_cause(ipnum); -+ set_c0_status(ipnum); -+} -+ -+static inline void disable_local_irq(unsigned int ip) -+{ -+ int ipnum = 0x100 << ip; -+ clear_c0_status(ipnum); -+} -+ -+static inline void ack_local_irq(unsigned int ip) -+{ -+ int ipnum = 0x100 << ip; -+ clear_c0_cause(ipnum); -+} -+ -+static void aruba_enable_irq(unsigned int irq_nr) -+{ -+ int ip = irq_nr - GROUP0_IRQ_BASE; -+ unsigned int group, intr_bit; -+ volatile unsigned int *addr; -+ if (ip < 0) { -+ enable_local_irq(irq_nr); -+ } else { -+ // calculate group -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ group = ip >> 5; -+ break; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ group = 0; -+ break; -+ } -+ -+ // calc interrupt bit within group -+ ip -= (group << 5); -+ intr_bit = 1 << ip; -+ -+ // first enable the IP mapped to this IRQ -+ enable_local_irq(group_to_ip(group)); -+ -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ addr = intr_group_muscat[group].base_addr; -+ // unmask intr within group -+ WRITE_MASK_MUSCAT(addr, READ_MASK_MUSCAT(addr) & ~intr_bit); -+ break; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ addr = intr_group_merlot[group].base_addr; -+ WRITE_MASK_MERLOT(addr, (READ_MASK_MERLOT(addr) | intr_bit)); -+ break; -+ } -+ } -+} -+ -+static void aruba_disable_irq(unsigned int irq_nr) -+{ -+ int ip = irq_nr - GROUP0_IRQ_BASE; -+ unsigned int group, intr_bit, mask; -+ volatile unsigned int *addr; -+ -+ // calculate group -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ group = ip >> 5; -+ break; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ group = 0; -+ break; -+ } -+ -+ // calc interrupt bit within group -+ ip -= group << 5; -+ intr_bit = 1 << ip; -+ -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ addr = intr_group_muscat[group].base_addr; -+ // mask intr within group -+ mask = READ_MASK_MUSCAT(addr); -+ mask |= intr_bit; -+ WRITE_MASK_MUSCAT(addr, mask); -+ -+ /* -+ if there are no more interrupts enabled in this -+ group, disable corresponding IP -+ */ -+ if (mask == intr_group_muscat[group].mask) -+ disable_local_irq(group_to_ip(group)); -+ break; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ addr = intr_group_merlot[group].base_addr; -+ addr = intr_group_merlot[group].base_addr; -+ // mask intr within group -+ WRITE_MASK_MERLOT(addr, (READ_MASK_MERLOT(addr) & ~intr_bit)); -+ if (READ_MASK_MERLOT(addr)) -+ disable_local_irq(group_to_ip(group)); -+ break; -+ } -+} -+ -+static unsigned int startup_irq(unsigned int irq_nr) -+{ -+ aruba_enable_irq(irq_nr); -+ return 0; -+} -+ -+static void shutdown_irq(unsigned int irq_nr) -+{ -+ aruba_disable_irq(irq_nr); -+ return; -+} -+ -+static void mask_and_ack_irq(unsigned int irq_nr) -+{ -+ aruba_disable_irq(irq_nr); -+ ack_local_irq(group_to_ip(irq_to_group(irq_nr))); -+} -+ -+static void end_irq(unsigned int irq_nr) -+{ -+ -+ int ip = irq_nr - GROUP0_IRQ_BASE; -+ unsigned int intr_bit, group; -+ volatile unsigned int *addr; -+ -+ if (irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS)) { -+ printk("warning: end_irq %d did not enable (%x)\n", -+ irq_nr, irq_desc[irq_nr].status); -+ } -+ -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ if (irq_nr == GROUP4_IRQ_BASE + 9) idt_gpio->gpioistat &= 0xfffffdff; -+ else if (irq_nr == GROUP4_IRQ_BASE + 10) idt_gpio->gpioistat &= 0xfffffbff; -+ else if (irq_nr == GROUP4_IRQ_BASE + 11) idt_gpio->gpioistat &= 0xfffff7ff; -+ else if (irq_nr == GROUP4_IRQ_BASE + 12) idt_gpio->gpioistat &= 0xffffefff; -+ -+ group = ip >> 5; -+ -+ // calc interrupt bit within group -+ ip -= (group << 5); -+ intr_bit = 1 << ip; -+ -+ // first enable the IP mapped to this IRQ -+ enable_local_irq(group_to_ip(group)); -+ -+ addr = intr_group_muscat[group].base_addr; -+ // unmask intr within group -+ WRITE_MASK_MUSCAT(addr, READ_MASK_MUSCAT(addr) & ~intr_bit); -+ break; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ group = 0; -+ // calc interrupt bit within group -+ intr_bit = 1 << ip; -+ // first enable the IP mapped to this IRQ -+ enable_local_irq(group_to_ip(group)); -+ addr = intr_group_merlot[group].base_addr; -+ // unmask intr within group -+ WRITE_MASK_MERLOT(addr, (READ_MASK_MERLOT(addr) | intr_bit)); -+ break; -+ } -+} -+ -+static struct hw_interrupt_type aruba_irq_type = { -+ .typename = "IDT434", -+ .startup = startup_irq, -+ .shutdown = shutdown_irq, -+ .enable = aruba_enable_irq, -+ .disable = aruba_disable_irq, -+ .ack = mask_and_ack_irq, -+ .end = end_irq, -+}; -+ -+void __init arch_init_irq(void) -+{ -+ int i; -+ printk("Initializing IRQ's: %d out of %d\n", RC32434_NR_IRQS, NR_IRQS); -+ memset(irq_desc, 0, sizeof(irq_desc)); -+ set_except_vector(0, idtIRQ); -+ -+ for (i = 0; i < RC32434_NR_IRQS; i++) { -+ irq_desc[i].status = IRQ_DISABLED; -+ irq_desc[i].action = NULL; -+ irq_desc[i].depth = 1; -+ irq_desc[i].handler = &aruba_irq_type; -+ spin_lock_init(&irq_desc[i].lock); -+ } -+ -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ break; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ WRITE_MASK_MERLOT(intr_group_merlot[0].base_addr, 0); -+ *((volatile unsigned long *)0xbc003014) = 0x10; -+ break; -+ } -+} -+ -+/* Main Interrupt dispatcher */ -+void aruba_irqdispatch(unsigned long cp0_cause, struct pt_regs *regs) -+{ -+ unsigned int pend, group, ip; -+ volatile unsigned int *addr; -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ if ((ip = (cp0_cause & 0x7c00))) { -+ group = 21 - rc32434_clz(ip); -+ -+ addr = intr_group_muscat[group].base_addr; -+ -+ pend = READ_PEND_MUSCAT(addr); -+ pend &= ~READ_MASK_MUSCAT(addr); // only unmasked interrupts -+ pend = 39 - rc32434_clz(pend); -+ do_IRQ((group << 5) + pend, regs); -+ } -+ break; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ #define MERLOT_WLAN1_IRQ 2 // bit 10 in CP0_status register -+ #define MERLOT_ENET_IRQ 4 // bit 11 in CP0_status register -+ #define MERLOT_WLAN_IRQ 5 // bit 13 in CP0_status register -+ #define MERLOT_MISC_IRQ 6 // bit 14 in CP0_status register = GROUP 0 -+ -+ if (cp0_cause & (1 << (8 + MERLOT_MISC_IRQ))) { -+ // Misc Interrupt -+ group = 0; -+ addr = intr_group_merlot[group].base_addr; -+ pend = READ_PEND_MERLOT(addr); -+ pend &= READ_MASK_MERLOT(addr); // only unmasked interrupts -+ /* handle one misc interrupt at a time */ -+ while (pend) { -+ unsigned int intr_bit, irq_nr; -+ intr_bit = pend ^ (pend - 1); -+ irq_nr = ((31 - rc32434_clz(pend)) + GROUP0_IRQ_BASE); -+ do_IRQ(irq_nr, regs); -+ do_IRQ(irq_nr, regs); -+ pend &= ~intr_bit; -+ } -+ } -+ -+ if (cp0_cause & (1 << (8 + MERLOT_WLAN_IRQ))) { -+ do_IRQ(MERLOT_WLAN_IRQ, regs); -+ } -+ -+ if (cp0_cause & (1 << (8 + MERLOT_ENET_IRQ))) { -+ do_IRQ(MERLOT_ENET_IRQ, regs); -+ } -+ break; -+ } -+} diff -Nur linux-2.6.15/arch/mips/aruba/Makefile linux-2.6.15-openwrt/arch/mips/aruba/Makefile --- linux-2.6.15/arch/mips/aruba/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.15-openwrt/arch/mips/aruba/Makefile 2006-01-10 00:32:32.000000000 +0100 @@ -1633,708 +1113,6 @@ diff -Nur linux-2.6.15/arch/mips/mm/tlbex.c linux-2.6.15-openwrt/arch/mips/mm/tl case CPU_4KEC: case CPU_24K: case CPU_34K: -diff -Nur linux-2.6.15/arch/mips/pci/fixup-aruba.c linux-2.6.15-openwrt/arch/mips/pci/fixup-aruba.c ---- linux-2.6.15/arch/mips/pci/fixup-aruba.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.15-openwrt/arch/mips/pci/fixup-aruba.c 2006-01-10 00:34:41.000000000 +0100 -@@ -0,0 +1,115 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * PCI fixups for IDT EB434 board -+ * -+ * Copyright 2004 IDT Inc. (rischelp@idt.com) -+ * -+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * 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. -+ * -+ * -+ ************************************************************************** -+ * May 2004 rkt, neb -+ * -+ * Initial Release -+ * -+ * -+ * -+ ************************************************************************** -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -+{ -+ -+ if (dev->bus->number != 0) { -+ return 0; -+ } -+ -+ slot = PCI_SLOT(dev->devfn); -+ dev->irq = 0; -+ -+ if (slot > 0 && slot <= 15) { -+#if 1 -+ if(slot == 10) { -+ if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 9; // intA -+ } else if(slot == 11) { -+ if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 10; // intA -+ if(pin == 2) dev->irq = GROUP4_IRQ_BASE + 10; // intA -+ if(pin == 3) dev->irq = GROUP4_IRQ_BASE + 10; // intA -+ } else if(slot == 12) { -+ if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 11; // intA -+ if(pin == 2) dev->irq = GROUP4_IRQ_BASE + 12; // intB -+ } else if (slot == 13) { -+ if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 12; // intA -+ if(pin == 2) dev->irq = GROUP4_IRQ_BASE + 11; // intB -+ } else { -+ dev->irq = GROUP4_IRQ_BASE + 11; -+ } -+#else -+ switch (pin) { -+ case 1: /* INTA*/ -+ dev->irq = GROUP4_IRQ_BASE + 11; -+ break; -+ case 2: /* INTB */ -+ dev->irq = GROUP4_IRQ_BASE + 11; -+ break; -+ case 3: /* INTC */ -+ dev->irq = GROUP4_IRQ_BASE + 11; -+ break; -+ case 4: /* INTD */ -+ dev->irq = GROUP4_IRQ_BASE + 11; -+ break; -+ default: -+ dev->irq = 0xff; -+ break; -+ } -+#endif -+#ifdef DEBUG -+ printk("irq fixup: slot %d, pin %d, irq %d\n", -+ slot, pin, dev->irq); -+#endif -+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE,dev->irq); -+ } -+ return (dev->irq); -+} -+ -+struct pci_fixup pcibios_fixups[] = { -+ {0} -+}; -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff -Nur linux-2.6.15/arch/mips/pci/Makefile linux-2.6.15-openwrt/arch/mips/pci/Makefile ---- linux-2.6.15/arch/mips/pci/Makefile 2006-01-03 04:21:10.000000000 +0100 -+++ linux-2.6.15-openwrt/arch/mips/pci/Makefile 2006-01-10 00:32:32.000000000 +0100 -@@ -56,3 +56,4 @@ - obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-tx4938.o ops-tx4938.o - obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o - obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o -+obj-$(CONFIG_MACH_ARUBA) += fixup-aruba.o ops-aruba.o pci-aruba.o -diff -Nur linux-2.6.15/arch/mips/pci/ops-aruba.c linux-2.6.15-openwrt/arch/mips/pci/ops-aruba.c ---- linux-2.6.15/arch/mips/pci/ops-aruba.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.15-openwrt/arch/mips/pci/ops-aruba.c 2006-01-10 00:32:32.000000000 +0100 -@@ -0,0 +1,204 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * pci_ops for IDT EB434 board -+ * -+ * Copyright 2004 IDT Inc. (rischelp@idt.com) -+ * -+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * 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. -+ * -+ * -+ ************************************************************************** -+ * May 2004 rkt, neb -+ * -+ * Initial Release -+ * -+ * -+ * -+ ************************************************************************** -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#define PCI_ACCESS_READ 0 -+#define PCI_ACCESS_WRITE 1 -+ -+ -+#define PCI_CFG_SET(slot,func,off) \ -+ (rc32434_pci->pcicfga = (0x80000000 | ((slot)<<11) | \ -+ ((func)<<8) | (off))) -+ -+static int config_access(unsigned char access_type, struct pci_bus *bus, -+ unsigned int devfn, unsigned char where, -+ u32 * data) -+{ -+ /* -+ * config cycles are on 4 byte boundary only -+ */ -+ unsigned int slot = PCI_SLOT(devfn); -+ u8 func = PCI_FUNC(devfn); -+ -+ if (slot < 2 || slot > 15) { -+ *data = 0xFFFFFFFF; -+ return -1; -+ } -+ /* Setup address */ -+ PCI_CFG_SET(slot, func, where); -+ rc32434_sync(); -+ -+ if (access_type == PCI_ACCESS_WRITE) { -+ rc32434_sync(); -+ rc32434_pci->pcicfgd = *data; -+ } else { -+ rc32434_sync(); -+ *data = rc32434_pci->pcicfgd; -+ } -+ -+ rc32434_sync(); -+ -+ return 0; -+} -+ -+ -+/* -+ * We can't address 8 and 16 bit words directly. Instead we have to -+ * read/write a 32bit word and mask/modify the data we actually want. -+ */ -+static int read_config_byte(struct pci_bus *bus, unsigned int devfn, -+ int where, u8 * val) -+{ -+ u32 data; -+ int ret; -+ -+ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); -+ *val = (data >> ((where & 3) << 3)) & 0xff; -+ return ret; -+} -+ -+static int read_config_word(struct pci_bus *bus, unsigned int devfn, -+ int where, u16 * val) -+{ -+ u32 data; -+ int ret; -+ -+ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); -+ *val = (data >> ((where & 3) << 3)) & 0xffff; -+ return ret; -+} -+ -+static int read_config_dword(struct pci_bus *bus, unsigned int devfn, -+ int where, u32 * val) -+{ -+ int ret; -+ -+ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val); -+ return ret; -+} -+ -+static int -+write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, -+ u8 val) -+{ -+ u32 data = 0; -+ -+ if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) -+ return -1; -+ -+ data = (data & ~(0xff << ((where & 3) << 3))) | -+ (val << ((where & 3) << 3)); -+ -+ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) -+ return -1; -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+ -+static int -+write_config_word(struct pci_bus *bus, unsigned int devfn, int where, -+ u16 val) -+{ -+ u32 data = 0; -+ -+ if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) -+ return -1; -+ -+ data = (data & ~(0xffff << ((where & 3) << 3))) | -+ (val << ((where & 3) << 3)); -+ -+ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) -+ return -1; -+ -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+ -+static int -+write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, -+ u32 val) -+{ -+ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val)) -+ return -1; -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int pci_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 pci_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); -+ } -+} -+ -+struct pci_ops rc32434_pci_ops = { -+ .read = pci_config_read, -+ .write = pci_config_write, -+}; -diff -Nur linux-2.6.15/arch/mips/pci/pci-aruba.c linux-2.6.15-openwrt/arch/mips/pci/pci-aruba.c ---- linux-2.6.15/arch/mips/pci/pci-aruba.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.15-openwrt/arch/mips/pci/pci-aruba.c 2006-01-10 00:32:32.000000000 +0100 -@@ -0,0 +1,235 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * PCI initialization for IDT EB434 board -+ * -+ * Copyright 2004 IDT Inc. (rischelp@idt.com) -+ * -+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * 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. -+ * -+ * -+ ************************************************************************** -+ * May 2004 rkt, neb -+ * -+ * Initial Release -+ * -+ * -+ * -+ ************************************************************************** -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define PCI_ACCESS_READ 0 -+#define PCI_ACCESS_WRITE 1 -+ -+#undef DEBUG -+#ifdef DEBUG -+#define DBG(x...) printk(x) -+#else -+#define DBG(x...) -+#endif -+/* define an unsigned array for the PCI registers */ -+unsigned int korinaCnfgRegs[25] = { -+ KORINA_CNFG1, KORINA_CNFG2, KORINA_CNFG3, KORINA_CNFG4, -+ KORINA_CNFG5, KORINA_CNFG6, KORINA_CNFG7, KORINA_CNFG8, -+ KORINA_CNFG9, KORINA_CNFG10, KORINA_CNFG11, KORINA_CNFG12, -+ KORINA_CNFG13, KORINA_CNFG14, KORINA_CNFG15, KORINA_CNFG16, -+ KORINA_CNFG17, KORINA_CNFG18, KORINA_CNFG19, KORINA_CNFG20, -+ KORINA_CNFG21, KORINA_CNFG22, KORINA_CNFG23, KORINA_CNFG24 -+}; -+ -+static struct resource rc32434_res_pci_mem2; -+ -+static struct resource rc32434_res_pci_mem1 = { -+ .name = "PCI MEM1", -+ .start = 0x50000000, -+ .end = 0x5FFFFFFF, -+ .flags = IORESOURCE_MEM, -+ .child = &rc32434_res_pci_mem2, -+}; -+static struct resource rc32434_res_pci_mem2 = { -+ .name = "PCI MEM2", -+ .start = 0x60000000, -+ .end = 0x6FFFFFFF, -+ .flags = IORESOURCE_MEM, -+ .parent = &rc32434_res_pci_mem1, -+}; -+static struct resource rc32434_res_pci_io1 = { -+ .name = "PCI I/O1", -+ .start = 0x18800000, -+ .end = 0x188FFFFF, -+ .flags = IORESOURCE_IO, -+}; -+ -+extern struct pci_ops rc32434_pci_ops; -+ -+struct pci_controller rc32434_controller = { -+ .pci_ops = &rc32434_pci_ops, -+ .mem_resource = &rc32434_res_pci_mem1, -+ .io_resource = &rc32434_res_pci_io1, -+ .mem_offset = 0x00000000UL, -+ .io_offset = 0x00000000UL, -+}; -+ -+extern unsigned int arch_has_pci; -+ -+static int __init rc32434_pcibridge_init(void) -+{ -+ -+ unsigned int pciConfigAddr = 0;/*used for writing pci config values */ -+ int loopCount=0 ;/*used for the loop */ -+ -+ unsigned int pcicValue, pcicData=0; -+ unsigned int dummyRead, pciCntlVal = 0; -+ -+ if (!arch_has_pci) return 0; -+ -+ printk("PCI: Initializing PCI\n"); -+ -+ /* Disable the IP bus error for PCI scaning */ -+ pciCntlVal=rc32434_pci->pcic; -+ pciCntlVal &= 0xFFFFFF7; -+ rc32434_pci->pcic = pciCntlVal; -+ -+ ioport_resource.start = rc32434_res_pci_io1.start; -+ ioport_resource.end = rc32434_res_pci_io1.end; -+/* -+ iomem_resource.start = rc32434_res_pci_mem1.start; -+ iomem_resource.end = rc32434_res_pci_mem1.end; -+*/ -+ -+ pcicValue = rc32434_pci->pcic; -+ pcicValue = (pcicValue >> PCIM_SHFT) & PCIM_BIT_LEN; -+ if (!((pcicValue == PCIM_H_EA) || -+ (pcicValue == PCIM_H_IA_FIX) || -+ (pcicValue == PCIM_H_IA_RR))) { -+ /* Not in Host Mode, return ERROR */ -+ return -1; -+ } -+ -+ /* Enables the Idle Grant mode, Arbiter Parking */ -+ pcicData |=(PCIC_igm_m|PCIC_eap_m|PCIC_en_m); -+ rc32434_pci->pcic = pcicData; /* Enable the PCI bus Interface */ -+ /* Zero out the PCI status & PCI Status Mask */ -+ for(;;) { -+ pcicData = rc32434_pci->pcis; -+ if (!(pcicData & PCIS_rip_m)) -+ break; -+ } -+ -+ rc32434_pci->pcis = 0; -+ rc32434_pci->pcism = 0xFFFFFFFF; -+ /* Zero out the PCI decoupled registers */ -+ rc32434_pci->pcidac=0; /* disable PCI decoupled accesses at initialization */ -+ rc32434_pci->pcidas=0; /* clear the status */ -+ rc32434_pci->pcidasm=0x0000007F; /* Mask all the interrupts */ -+ /* Mask PCI Messaging Interrupts */ -+ rc32434_pci_msg->pciiic = 0; -+ rc32434_pci_msg->pciiim = 0xFFFFFFFF; -+ rc32434_pci_msg->pciioic = 0; -+ rc32434_pci_msg->pciioim = 0; -+ -+ /* Setup PCILB0 as Memory Window */ -+ rc32434_pci->pcilba[0].a = (unsigned int) (PCI_ADDR_START); -+ -+ /* setup the PCI map address as same as the local address */ -+ -+ rc32434_pci->pcilba[0].m = (unsigned int) (PCI_ADDR_START); -+ -+ /* Setup PCILBA1 as MEM */ -+#ifdef __MIPSEB__ -+ rc32434_pci->pcilba[0].c = ( ((SIZE_16MB & 0x1f) << PCILBAC_size_b) | PCILBAC_sb_m); -+#else -+ rc32434_pci->pcilba[0].c = ( ((SIZE_16MB & 0x1f) << PCILBAC_size_b)); -+#endif -+ dummyRead = rc32434_pci->pcilba[0].c; /* flush the CPU write Buffers */ -+ -+ rc32434_pci->pcilba[1].a = 0x60000000; -+ -+ rc32434_pci->pcilba[1].m = 0x60000000; -+ /* setup PCILBA2 as IO Window*/ -+#ifdef __MIPSEB__ -+ rc32434_pci->pcilba[1].c = ( ((SIZE_256MB & 0x1f) << PCILBAC_size_b) | PCILBAC_sb_m); -+#else -+ rc32434_pci->pcilba[1].c = ((SIZE_256MB & 0x1f) << PCILBAC_size_b); -+#endif -+ dummyRead = rc32434_pci->pcilba[1].c; /* flush the CPU write Buffers */ -+ rc32434_pci->pcilba[2].a = 0x18C00000; -+ -+ rc32434_pci->pcilba[2].m = 0x18FFFFFF; -+ /* setup PCILBA2 as IO Window*/ -+#ifdef __MIPSEB__ -+ rc32434_pci->pcilba[2].c = ( ((SIZE_4MB & 0x1f) << PCILBAC_size_b) | PCILBAC_sb_m); -+#else -+ rc32434_pci->pcilba[2].c = ((SIZE_4MB & 0x1f) << PCILBAC_size_b); -+#endif -+ -+ dummyRead = rc32434_pci->pcilba[2].c; /* flush the CPU write Buffers */ -+ -+ -+ rc32434_pci->pcilba[3].a = 0x18800000; -+ -+ rc32434_pci->pcilba[3].m = 0x18800000; -+ /* Setup PCILBA3 as IO Window */ -+ -+#ifdef __MIPSEB__ -+ rc32434_pci->pcilba[3].c = ( (((SIZE_1MB & 0x1ff) << PCILBAC_size_b) | PCILBAC_msi_m) | PCILBAC_sb_m); -+#else -+ rc32434_pci->pcilba[3].c = (((SIZE_1MB & 0x1ff) << PCILBAC_size_b) | PCILBAC_msi_m); -+#endif -+ dummyRead = rc32434_pci->pcilba[2].c; /* flush the CPU write Buffers */ -+ -+ pciConfigAddr = (unsigned int)(0x80000004); -+ for(loopCount = 0; loopCount < 24; loopCount++){ -+ rc32434_pci->pcicfga = pciConfigAddr; -+ dummyRead = rc32434_pci->pcicfga; -+ rc32434_pci->pcicfgd = korinaCnfgRegs[loopCount]; -+ dummyRead=rc32434_pci->pcicfgd; -+ pciConfigAddr += 4; -+ } -+ rc32434_pci->pcitc=(unsigned int)((PCITC_RTIMER_VAL&0xff) << PCITC_rtimer_b) | -+ ((PCITC_DTIMER_VAL&0xff)<pcic; -+ pciCntlVal &= ~(PCIC_tnr_m); -+ rc32434_pci->pcic = pciCntlVal; -+ pciCntlVal = rc32434_pci->pcic; -+ -+ register_pci_controller(&rc32434_controller); -+ -+ rc32434_sync(); -+ return 0; -+} -+ -+arch_initcall(rc32434_pcibridge_init); -+ -+/* Do platform specific device initialization at pci_enable_device() time */ -+int pcibios_plat_dev_init(struct pci_dev *dev) -+{ -+ return 0; -+} -diff -Nur linux-2.6.15/drivers/mtd/chips/cfi_probe.c linux-2.6.15-openwrt/drivers/mtd/chips/cfi_probe.c ---- linux-2.6.15/drivers/mtd/chips/cfi_probe.c 2006-01-03 04:21:10.000000000 +0100 -+++ linux-2.6.15-openwrt/drivers/mtd/chips/cfi_probe.c 2006-01-10 00:32:32.000000000 +0100 -@@ -26,6 +26,74 @@ - static void print_cfi_ident(struct cfi_ident *); - #endif - -+#if 1 -+ -+#define AMD_AUTOSEL_OFF1 0xAAA -+#define AMD_AUTOSEL_OFF2 0x555 -+#define AMD_MANUF_ID 0x1 -+#define AMD_DEVICE_ID1 0xF6 /* T */ -+#define AMD_DEVICE_ID2 0xF9 /* B */ -+/* Foll. are definitions for Macronix Flash Part */ -+#define MCX_MANUF_ID 0xC2 -+#define MCX_DEVICE_ID1 0xA7 -+#define MCX_DEVICE_ID2 0xA8 -+/* Foll. common to both AMD and Macronix */ -+#define FACTORY_LOCKED 0x99 -+#define USER_LOCKED 0x19 -+ -+/* NOTE: AP-70/6x use BYTE mode flash access. Therefore the -+ * lowest Addr. pin in the flash is not A0 but A-1 (A minus 1). -+ * CPU's A0 is tied to Flash's A-1, A1 to A0 and so on. This -+ * gives 4MB of byte-addressable mem. In byte mode, all addr -+ * need to be multiplied by 2 (i.e compared to word mode). -+ * NOTE: AMD_AUTOSEL_OFF1 and OFF2 are already mult. by 2 -+ * Just blindly use the addr offsets suggested in the manual -+ * for byte mode and you'll be OK. Offs. in Table 6 need to -+ * be mult by 2 (for getting autosel params) -+ */ -+void -+flash_detect(struct map_info *map, __u32 base, struct cfi_private *cfi) -+{ -+ map_word val[3]; -+ int osf = cfi->interleave * cfi->device_type; // =2 for AP70/6x -+ char *manuf, *part, *lock ; -+ -+ if (osf != 1) return ; -+ -+ cfi_send_gen_cmd(0xAA, AMD_AUTOSEL_OFF1, base, map, cfi, cfi->device_type, NULL); -+ cfi_send_gen_cmd(0x55, AMD_AUTOSEL_OFF2, base, map, cfi, cfi->device_type, NULL); -+ cfi_send_gen_cmd(0x90, AMD_AUTOSEL_OFF1, base, map, cfi, cfi->device_type, NULL); -+ val[0] = map_read(map, base) ; // manuf ID -+ val[1] = map_read(map, base+2) ; // device ID -+ val[2] = map_read(map, base+6) ; // lock indicator -+#if 0 -+printk("v1=0x%x v2=0x%x v3=0x%x\n", val[0], val[1], val[2]) ; -+#endif -+ if (val[0].x[0] == AMD_MANUF_ID) { -+ manuf = "AMD Flash" ; -+ if (val[1].x[0] == AMD_DEVICE_ID1) -+ part = "AM29LV320D (Top)" ; -+ else if (val[1].x[0] == AMD_DEVICE_ID2) -+ part = "AM29LV320D (Bot)" ; -+ else part = "Unknown" ; -+ } else if (val[0].x[0] == MCX_MANUF_ID) { -+ manuf = "Macronix Flash" ; -+ if (val[1].x[0] == MCX_DEVICE_ID1) -+ part = "MX29LV320A (Top)" ; -+ else if (val[1].x[0] == MCX_DEVICE_ID2) -+ part = "MX29LV320A (Bot)" ; -+ else part = "Unknown" ; -+ } else -+ return ; -+ if (val[2].x[0] == FACTORY_LOCKED) -+ lock = "Factory Locked" ; -+ else if (val[2].x[0] == USER_LOCKED) -+ lock = "User Locked" ; -+ else lock = "Unknown locking" ; -+ printk("%s %s (%s)\n", manuf, part, lock) ; -+} -+#endif -+ - static int cfi_probe_chip(struct map_info *map, __u32 base, - unsigned long *chip_map, struct cfi_private *cfi); - static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi); -@@ -118,6 +186,10 @@ - } - - xip_disable(); -+#if 1 -+ //cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); -+ flash_detect(map, base, cfi) ; -+#endif - cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); - cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); - cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); -diff -Nur linux-2.6.15/drivers/mtd/maps/physmap.c linux-2.6.15-openwrt/drivers/mtd/maps/physmap.c ---- linux-2.6.15/drivers/mtd/maps/physmap.c 2006-01-03 04:21:10.000000000 +0100 -+++ linux-2.6.15-openwrt/drivers/mtd/maps/physmap.c 2006-01-10 00:32:32.000000000 +0100 -@@ -34,15 +34,31 @@ - static struct mtd_partition *mtd_parts; - static int mtd_parts_nb; - --static int num_physmap_partitions; --static struct mtd_partition *physmap_partitions; -+static int num_physmap_partitions = 3; -+static struct mtd_partition physmap_partitions[] = { -+ { -+ name: "zImage", -+ size: 0x3f0000-0x80000, -+ offset: 0x80000, -+ }, -+ { -+ name: "JFFS2", -+ size: 0x3f0000-0x120000, -+ offset: 0x120000, -+ }, -+ { -+ name: "NVRAM", -+ size: 0x2000, -+ offset: 0x3f8000, -+ } -+}; - - static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL}; - - void physmap_set_partitions(struct mtd_partition *parts, int num_parts) - { -- physmap_partitions=parts; -- num_physmap_partitions=num_parts; -+// physmap_partitions=parts; -+// num_physmap_partitions=num_parts; - } - #endif /* CONFIG_MTD_PARTITIONS */ - diff -Nur linux-2.6.15/drivers/net/Kconfig linux-2.6.15-openwrt/drivers/net/Kconfig --- linux-2.6.15/drivers/net/Kconfig 2006-01-03 04:21:10.000000000 +0100 +++ linux-2.6.15-openwrt/drivers/net/Kconfig 2006-01-10 00:32:32.000000000 +0100 @@ -3826,50 +2604,6 @@ diff -Nur linux-2.6.15/drivers/net/rc32434_eth.h linux-2.6.15-openwrt/drivers/ne + rc32434_writel(0, &ch->dmadptr); + rc32434_writel(0, &ch->dmandptr); +} -diff -Nur linux-2.6.15/drivers/pci/access.c linux-2.6.15-openwrt/drivers/pci/access.c ---- linux-2.6.15/drivers/pci/access.c 2006-01-03 04:21:10.000000000 +0100 -+++ linux-2.6.15-openwrt/drivers/pci/access.c 2006-01-10 00:43:10.000000000 +0100 -@@ -21,6 +21,7 @@ - #define PCI_word_BAD (pos & 1) - #define PCI_dword_BAD (pos & 3) - -+#ifdef __MIPSEB__ - #define PCI_OP_READ(size,type,len) \ - int pci_bus_read_config_##size \ - (struct pci_bus *bus, unsigned int devfn, int pos, type *value) \ -@@ -31,11 +32,32 @@ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irqsave(&pci_lock, flags); \ - res = bus->ops->read(bus, devfn, pos, len, &data); \ -+ if (len == 1) \ -+ *value = (type)((data >> 24) & 0xff); \ -+ else if (len == 2) \ -+ *value = (type)((data >> 16) & 0xffff); \ -+ else \ - *value = (type)data; \ - spin_unlock_irqrestore(&pci_lock, flags); \ - return res; \ - } -+#else - -+#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; \ -+ u32 data = 0; \ -+ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ -+ spin_lock_irqsave(&pci_lock, flags); \ -+ res = bus->ops->read(bus, devfn, pos, len, &data); \ -+ *value = (type)data; \ -+ spin_unlock_irqrestore(&pci_lock, flags); \ -+ return res; \ -+} -+#endif - #define PCI_OP_WRITE(size,type,len) \ - int pci_bus_write_config_##size \ - (struct pci_bus *bus, unsigned int devfn, int pos, type value) \ diff -Nur linux-2.6.15/include/asm-mips/bootinfo.h linux-2.6.15-openwrt/include/asm-mips/bootinfo.h --- linux-2.6.15/include/asm-mips/bootinfo.h 2006-01-03 04:21:10.000000000 +0100 +++ linux-2.6.15-openwrt/include/asm-mips/bootinfo.h 2006-01-10 00:32:33.000000000 +0100 diff --git a/openwrt/target/linux/aruba-2.6/patches/001-flash.patch b/openwrt/target/linux/aruba-2.6/patches/001-flash.patch new file mode 100644 index 0000000000..f0b951370d --- /dev/null +++ b/openwrt/target/linux/aruba-2.6/patches/001-flash.patch @@ -0,0 +1,159 @@ +diff -Nur linux-2.6.15/arch/mips/aruba/flash_lock.c linux-2.6.15-openwrt/arch/mips/aruba/flash_lock.c +--- linux-2.6.15/arch/mips/aruba/flash_lock.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.15-openwrt/arch/mips/aruba/flash_lock.c 2006-01-10 00:32:32.000000000 +0100 +@@ -0,0 +1,27 @@ ++#include ++#include ++#include ++ ++#define AP70_PROT_ADDR 0xb8010008 ++#define AP70_PROT_DATA 0x8 ++#define AP60_PROT_ADDR 0xB8400000 ++#define AP60_PROT_DATA 0x04000000 ++ ++void unlock_ap60_70_flash(void) ++{ ++ volatile __u32 val; ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ val = *(volatile __u32 *)AP70_PROT_ADDR; ++ val &= ~(AP70_PROT_DATA); ++ *(volatile __u32 *)AP70_PROT_ADDR = val; ++ break; ++ case MACH_ARUBA_AP65: ++ case MACH_ARUBA_AP60: ++ default: ++ val = *(volatile __u32 *)AP60_PROT_ADDR; ++ val &= ~(AP60_PROT_DATA); ++ *(volatile __u32 *)AP60_PROT_ADDR = val; ++ break; ++ } ++} +diff -Nur linux-2.6.15/drivers/mtd/chips/cfi_probe.c linux-2.6.15-openwrt/drivers/mtd/chips/cfi_probe.c +--- linux-2.6.15/drivers/mtd/chips/cfi_probe.c 2006-01-03 04:21:10.000000000 +0100 ++++ linux-2.6.15-openwrt/drivers/mtd/chips/cfi_probe.c 2006-01-10 00:32:32.000000000 +0100 +@@ -26,6 +26,74 @@ + static void print_cfi_ident(struct cfi_ident *); + #endif + ++#if 1 ++ ++#define AMD_AUTOSEL_OFF1 0xAAA ++#define AMD_AUTOSEL_OFF2 0x555 ++#define AMD_MANUF_ID 0x1 ++#define AMD_DEVICE_ID1 0xF6 /* T */ ++#define AMD_DEVICE_ID2 0xF9 /* B */ ++/* Foll. are definitions for Macronix Flash Part */ ++#define MCX_MANUF_ID 0xC2 ++#define MCX_DEVICE_ID1 0xA7 ++#define MCX_DEVICE_ID2 0xA8 ++/* Foll. common to both AMD and Macronix */ ++#define FACTORY_LOCKED 0x99 ++#define USER_LOCKED 0x19 ++ ++/* NOTE: AP-70/6x use BYTE mode flash access. Therefore the ++ * lowest Addr. pin in the flash is not A0 but A-1 (A minus 1). ++ * CPU's A0 is tied to Flash's A-1, A1 to A0 and so on. This ++ * gives 4MB of byte-addressable mem. In byte mode, all addr ++ * need to be multiplied by 2 (i.e compared to word mode). ++ * NOTE: AMD_AUTOSEL_OFF1 and OFF2 are already mult. by 2 ++ * Just blindly use the addr offsets suggested in the manual ++ * for byte mode and you'll be OK. Offs. in Table 6 need to ++ * be mult by 2 (for getting autosel params) ++ */ ++void ++flash_detect(struct map_info *map, __u32 base, struct cfi_private *cfi) ++{ ++ map_word val[3]; ++ int osf = cfi->interleave * cfi->device_type; // =2 for AP70/6x ++ char *manuf, *part, *lock ; ++ ++ if (osf != 1) return ; ++ ++ cfi_send_gen_cmd(0xAA, AMD_AUTOSEL_OFF1, base, map, cfi, cfi->device_type, NULL); ++ cfi_send_gen_cmd(0x55, AMD_AUTOSEL_OFF2, base, map, cfi, cfi->device_type, NULL); ++ cfi_send_gen_cmd(0x90, AMD_AUTOSEL_OFF1, base, map, cfi, cfi->device_type, NULL); ++ val[0] = map_read(map, base) ; // manuf ID ++ val[1] = map_read(map, base+2) ; // device ID ++ val[2] = map_read(map, base+6) ; // lock indicator ++#if 0 ++printk("v1=0x%x v2=0x%x v3=0x%x\n", val[0], val[1], val[2]) ; ++#endif ++ if (val[0].x[0] == AMD_MANUF_ID) { ++ manuf = "AMD Flash" ; ++ if (val[1].x[0] == AMD_DEVICE_ID1) ++ part = "AM29LV320D (Top)" ; ++ else if (val[1].x[0] == AMD_DEVICE_ID2) ++ part = "AM29LV320D (Bot)" ; ++ else part = "Unknown" ; ++ } else if (val[0].x[0] == MCX_MANUF_ID) { ++ manuf = "Macronix Flash" ; ++ if (val[1].x[0] == MCX_DEVICE_ID1) ++ part = "MX29LV320A (Top)" ; ++ else if (val[1].x[0] == MCX_DEVICE_ID2) ++ part = "MX29LV320A (Bot)" ; ++ else part = "Unknown" ; ++ } else ++ return ; ++ if (val[2].x[0] == FACTORY_LOCKED) ++ lock = "Factory Locked" ; ++ else if (val[2].x[0] == USER_LOCKED) ++ lock = "User Locked" ; ++ else lock = "Unknown locking" ; ++ printk("%s %s (%s)\n", manuf, part, lock) ; ++} ++#endif ++ + static int cfi_probe_chip(struct map_info *map, __u32 base, + unsigned long *chip_map, struct cfi_private *cfi); + static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi); +@@ -118,6 +186,10 @@ + } + + xip_disable(); ++#if 1 ++ //cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); ++ flash_detect(map, base, cfi) ; ++#endif + cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); +diff -Nur linux-2.6.15/drivers/mtd/maps/physmap.c linux-2.6.15-openwrt/drivers/mtd/maps/physmap.c +--- linux-2.6.15/drivers/mtd/maps/physmap.c 2006-01-03 04:21:10.000000000 +0100 ++++ linux-2.6.15-openwrt/drivers/mtd/maps/physmap.c 2006-01-10 00:32:32.000000000 +0100 +@@ -34,15 +34,31 @@ + static struct mtd_partition *mtd_parts; + static int mtd_parts_nb; + +-static int num_physmap_partitions; +-static struct mtd_partition *physmap_partitions; ++static int num_physmap_partitions = 3; ++static struct mtd_partition physmap_partitions[] = { ++ { ++ name: "zImage", ++ size: 0x3f0000-0x80000, ++ offset: 0x80000, ++ }, ++ { ++ name: "JFFS2", ++ size: 0x3f0000-0x120000, ++ offset: 0x120000, ++ }, ++ { ++ name: "NVRAM", ++ size: 0x2000, ++ offset: 0x3f8000, ++ } ++}; + + static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL}; + + void physmap_set_partitions(struct mtd_partition *parts, int num_parts) + { +- physmap_partitions=parts; +- num_physmap_partitions=num_parts; ++// physmap_partitions=parts; ++// num_physmap_partitions=num_parts; + } + #endif /* CONFIG_MTD_PARTITIONS */ + diff --git a/openwrt/target/linux/aruba-2.6/patches/002-irq.patch b/openwrt/target/linux/aruba-2.6/patches/002-irq.patch new file mode 100644 index 0000000000..d789a2104b --- /dev/null +++ b/openwrt/target/linux/aruba-2.6/patches/002-irq.patch @@ -0,0 +1,488 @@ +diff -Nur linux-2.6.15/arch/mips/aruba/idtIRQ.S linux-2.6.15-openwrt/arch/mips/aruba/idtIRQ.S +--- linux-2.6.15/arch/mips/aruba/idtIRQ.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.15-openwrt/arch/mips/aruba/idtIRQ.S 2006-01-10 00:32:32.000000000 +0100 +@@ -0,0 +1,87 @@ ++/************************************************************************** ++ * ++ * BRIEF MODULE DESCRIPTION ++ * Intterrupt dispatcher code for IDT boards ++ * ++ * Copyright 2004 IDT Inc. (rischelp@idt.com) ++ * ++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * 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. ++ * ++ * ++ ************************************************************************** ++ * May 2004 rkt, neb ++ * ++ * Initial Release ++ * ++ * ++ * ++ ************************************************************************** ++ */ ++ ++ ++#include ++#include ++#include ++#include ++ ++ .text ++ .set noreorder ++ .set noat ++ .align 5 ++ NESTED(idtIRQ, PT_SIZE, sp) ++ .set noat ++ SAVE_ALL ++ CLI ++ ++ .set at ++ .set noreorder ++ ++ /* Get the pending interrupts */ ++ mfc0 t0, CP0_CAUSE ++ nop ++ ++ /* Isolate the allowed ones by anding the irq mask */ ++ mfc0 t2, CP0_STATUS ++ move a1, sp /* need a nop here, hence we anticipate */ ++ andi t0, CAUSEF_IP ++ and t0, t2 ++ ++ /* check for r4k counter/timer IRQ. */ ++ ++ andi t1, t0, CAUSEF_IP7 ++ beqz t1, 1f ++ nop ++ ++ jal aruba_timer_interrupt ++ ++ li a0, 7 ++ ++ j ret_from_irq ++ nop ++1: ++ jal aruba_irqdispatch ++ move a0, t0 ++ j ret_from_irq ++ nop ++ ++ END(idtIRQ) ++ ++ +diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/aruba/irq.c +--- linux-2.6.15/arch/mips/aruba/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.15-openwrt/arch/mips/aruba/irq.c 2006-01-10 00:32:32.000000000 +0100 +@@ -0,0 +1,393 @@ ++/************************************************************************** ++ * ++ * BRIEF MODULE DESCRIPTION ++ * Interrupt routines for IDT EB434 boards ++ * ++ * Copyright 2004 IDT Inc. (rischelp@idt.com) ++ * ++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * 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. ++ * ++ * ++ ************************************************************************** ++ * May 2004 rkt, neb ++ * ++ * Initial Release ++ * ++ * ++ * ++ ************************************************************************** ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#undef DEBUG_IRQ ++#ifdef DEBUG_IRQ ++/* note: prints function name for you */ ++#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) ++#else ++#define DPRINTK(fmt, args...) ++#endif ++ ++extern asmlinkage void idtIRQ(void); ++static unsigned int startup_irq(unsigned int irq); ++static void end_irq(unsigned int irq_nr); ++static void mask_and_ack_irq(unsigned int irq_nr); ++static void aruba_enable_irq(unsigned int irq_nr); ++static void aruba_disable_irq(unsigned int irq_nr); ++ ++extern void __init init_generic_irq(void); ++ ++typedef struct { ++ u32 mask; ++ volatile u32 *base_addr; ++} intr_group_t; ++ ++static const intr_group_t intr_group_merlot[NUM_INTR_GROUPS] = { ++ {0xffffffff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 0)}, ++}; ++ ++#define READ_PEND_MERLOT(base) (*((volatile unsigned long *)(0xbc003010))) ++#define READ_MASK_MERLOT(base) (*((volatile unsigned long *)(0xbc003010 + 4))) ++#define WRITE_MASK_MERLOT(base, val) ((*((volatile unsigned long *)((0xbc003010) + 4))) = (val)) ++ ++static const intr_group_t intr_group_muscat[NUM_INTR_GROUPS] = { ++ {0x0000efff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 0 * IC_GROUP_OFFSET)}, ++ {0x00001fff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 1 * IC_GROUP_OFFSET)}, ++ {0x00000007, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 2 * IC_GROUP_OFFSET)}, ++ {0x0003ffff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 3 * IC_GROUP_OFFSET)}, ++ {0xffffffff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 4 * IC_GROUP_OFFSET)} ++}; ++ ++#define READ_PEND_MUSCAT(base) (*(base)) ++#define READ_MASK_MUSCAT(base) (*(base + 2)) ++#define WRITE_MASK_MUSCAT(base, val) (*(base + 2) = (val)) ++ ++static inline int irq_to_group(unsigned int irq_nr) ++{ ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ return ((irq_nr - GROUP0_IRQ_BASE) >> 5); ++ case MACH_ARUBA_AP65: ++ case MACH_ARUBA_AP60: ++ default: ++ return 0; ++ } ++} ++ ++static inline int group_to_ip(unsigned int group) ++{ ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ return group + 2; ++ case MACH_ARUBA_AP65: ++ case MACH_ARUBA_AP60: ++ default: ++ return 6; ++ } ++} ++ ++static inline void enable_local_irq(unsigned int ip) ++{ ++ int ipnum = 0x100 << ip; ++ clear_c0_cause(ipnum); ++ set_c0_status(ipnum); ++} ++ ++static inline void disable_local_irq(unsigned int ip) ++{ ++ int ipnum = 0x100 << ip; ++ clear_c0_status(ipnum); ++} ++ ++static inline void ack_local_irq(unsigned int ip) ++{ ++ int ipnum = 0x100 << ip; ++ clear_c0_cause(ipnum); ++} ++ ++static void aruba_enable_irq(unsigned int irq_nr) ++{ ++ int ip = irq_nr - GROUP0_IRQ_BASE; ++ unsigned int group, intr_bit; ++ volatile unsigned int *addr; ++ if (ip < 0) { ++ enable_local_irq(irq_nr); ++ } else { ++ // calculate group ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ group = ip >> 5; ++ break; ++ case MACH_ARUBA_AP65: ++ case MACH_ARUBA_AP60: ++ default: ++ group = 0; ++ break; ++ } ++ ++ // calc interrupt bit within group ++ ip -= (group << 5); ++ intr_bit = 1 << ip; ++ ++ // first enable the IP mapped to this IRQ ++ enable_local_irq(group_to_ip(group)); ++ ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ addr = intr_group_muscat[group].base_addr; ++ // unmask intr within group ++ WRITE_MASK_MUSCAT(addr, READ_MASK_MUSCAT(addr) & ~intr_bit); ++ break; ++ case MACH_ARUBA_AP65: ++ case MACH_ARUBA_AP60: ++ default: ++ addr = intr_group_merlot[group].base_addr; ++ WRITE_MASK_MERLOT(addr, READ_MASK_MERLOT(addr) | intr_bit); ++ break; ++ } ++ } ++} ++ ++static void aruba_disable_irq(unsigned int irq_nr) ++{ ++ int ip = irq_nr - GROUP0_IRQ_BASE; ++ unsigned int group, intr_bit, mask; ++ volatile unsigned int *addr; ++ ++ // calculate group ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ group = ip >> 5; ++ break; ++ case MACH_ARUBA_AP65: ++ case MACH_ARUBA_AP60: ++ default: ++ group = 0; ++ break; ++ } ++ ++ // calc interrupt bit within group ++ ip -= group << 5; ++ intr_bit = 1 << ip; ++ ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ addr = intr_group_muscat[group].base_addr; ++ // mask intr within group ++ mask = READ_MASK_MUSCAT(addr); ++ mask |= intr_bit; ++ WRITE_MASK_MUSCAT(addr, mask); ++ ++ /* ++ if there are no more interrupts enabled in this ++ group, disable corresponding IP ++ */ ++ if (mask == intr_group_muscat[group].mask) ++ disable_local_irq(group_to_ip(group)); ++ break; ++ case MACH_ARUBA_AP65: ++ case MACH_ARUBA_AP60: ++ default: ++ addr = intr_group_merlot[group].base_addr; ++ // mask intr within group ++ mask = READ_MASK_MERLOT(addr); ++ mask &= ~intr_bit; ++ WRITE_MASK_MERLOT(addr, mask); ++ if (!mask) ++ disable_local_irq(group_to_ip(group)); ++ break; ++ } ++} ++ ++static unsigned int startup_irq(unsigned int irq_nr) ++{ ++ aruba_enable_irq(irq_nr); ++ return 0; ++} ++ ++static void shutdown_irq(unsigned int irq_nr) ++{ ++ aruba_disable_irq(irq_nr); ++ return; ++} ++ ++static void mask_and_ack_irq(unsigned int irq_nr) ++{ ++ aruba_disable_irq(irq_nr); ++ ack_local_irq(group_to_ip(irq_to_group(irq_nr))); ++} ++ ++static void end_irq(unsigned int irq_nr) ++{ ++ ++ int ip = irq_nr - GROUP0_IRQ_BASE; ++ unsigned int intr_bit, group; ++ volatile unsigned int *addr; ++ ++ if (irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS)) { ++ printk("warning: end_irq %d did not enable (%x)\n", ++ irq_nr, irq_desc[irq_nr].status); ++ } ++ ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ if (irq_nr == GROUP4_IRQ_BASE + 9) idt_gpio->gpioistat &= 0xfffffdff; ++ else if (irq_nr == GROUP4_IRQ_BASE + 10) idt_gpio->gpioistat &= 0xfffffbff; ++ else if (irq_nr == GROUP4_IRQ_BASE + 11) idt_gpio->gpioistat &= 0xfffff7ff; ++ else if (irq_nr == GROUP4_IRQ_BASE + 12) idt_gpio->gpioistat &= 0xffffefff; ++ ++ group = ip >> 5; ++ ++ // calc interrupt bit within group ++ ip -= (group << 5); ++ intr_bit = 1 << ip; ++ ++ // first enable the IP mapped to this IRQ ++ enable_local_irq(group_to_ip(group)); ++ ++ addr = intr_group_muscat[group].base_addr; ++ // unmask intr within group ++ WRITE_MASK_MUSCAT(addr, READ_MASK_MUSCAT(addr) & ~intr_bit); ++ break; ++ case MACH_ARUBA_AP65: ++ case MACH_ARUBA_AP60: ++ group = 0; ++ ++ // calc interrupt bit within group ++ intr_bit = 1 << ip; ++ ++ // first enable the IP mapped to this IRQ ++ enable_local_irq(group_to_ip(group)); ++ ++ addr = intr_group_merlot[group].base_addr; ++ // unmask intr within group ++ WRITE_MASK_MERLOT(addr, READ_MASK_MERLOT(addr) | intr_bit); ++ break; ++ } ++} ++ ++static struct hw_interrupt_type aruba_irq_type = { ++ .typename = "IDT434", ++ .startup = startup_irq, ++ .shutdown = shutdown_irq, ++ .enable = aruba_enable_irq, ++ .disable = aruba_disable_irq, ++ .ack = mask_and_ack_irq, ++ .end = end_irq, ++}; ++ ++void __init arch_init_irq(void) ++{ ++ int i; ++ printk("Initializing IRQ's: %d out of %d\n", RC32434_NR_IRQS, NR_IRQS); ++ memset(irq_desc, 0, sizeof(irq_desc)); ++ set_except_vector(0, idtIRQ); ++ ++ for (i = 0; i < RC32434_NR_IRQS; i++) { ++ irq_desc[i].status = IRQ_DISABLED; ++ irq_desc[i].action = NULL; ++ irq_desc[i].depth = 1; ++ irq_desc[i].handler = &aruba_irq_type; ++ spin_lock_init(&irq_desc[i].lock); ++ } ++ ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ break; ++ case MACH_ARUBA_AP65: ++ case MACH_ARUBA_AP60: ++ default: ++ WRITE_MASK_MERLOT(intr_group_merlot[0].base_addr, 0); ++ *((volatile unsigned long *)0xbc003014) = 0x10; ++ break; ++ } ++} ++ ++/* Main Interrupt dispatcher */ ++void aruba_irqdispatch(unsigned long cp0_cause, struct pt_regs *regs) ++{ ++ unsigned int pend, group, ip; ++ volatile unsigned int *addr; ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ if ((ip = (cp0_cause & 0x7c00))) { ++ group = 21 - rc32434_clz(ip); ++ ++ addr = intr_group_muscat[group].base_addr; ++ ++ pend = READ_PEND_MUSCAT(addr); ++ pend &= ~READ_MASK_MUSCAT(addr); // only unmasked interrupts ++ pend = 39 - rc32434_clz(pend); ++ do_IRQ((group << 5) + pend, regs); ++ } ++ break; ++ case MACH_ARUBA_AP65: ++ case MACH_ARUBA_AP60: ++ default: ++ if (cp0_cause & 0x4000) { ++ // Misc Interrupt ++ group = 0; ++ addr = intr_group_merlot[group].base_addr; ++ pend = READ_PEND_MERLOT(addr); ++ pend &= READ_MASK_MERLOT(addr); // only unmasked interrupts ++ /* handle one misc interrupt at a time */ ++ while (pend) { ++ unsigned int intr_bit, irq_nr; ++ intr_bit = pend ^ (pend - 1); ++ irq_nr = ((31 - rc32434_clz(pend)) + GROUP0_IRQ_BASE); ++ do_IRQ(irq_nr, regs); ++ pend &= ~intr_bit; ++ } ++ } ++ if (cp0_cause & 0x3c00) { ++ while (cp0_cause) { ++ unsigned int intr_bit, irq_nr; ++ intr_bit = cp0_cause ^ (cp0_cause - 1); ++ irq_nr = ((31 - rc32434_clz(cp0_cause)) - GROUP0_IRQ_BASE); ++ do_IRQ(irq_nr, regs); ++ cp0_cause &= ~intr_bit; ++ } ++ } ++ break; ++ } ++} diff --git a/openwrt/target/linux/aruba-2.6/patches/003-pci.patch b/openwrt/target/linux/aruba-2.6/patches/003-pci.patch new file mode 100644 index 0000000000..0cad12a087 --- /dev/null +++ b/openwrt/target/linux/aruba-2.6/patches/003-pci.patch @@ -0,0 +1,618 @@ +diff -Nur linux-2.6.15/arch/mips/pci/fixup-aruba.c linux-2.6.15-openwrt/arch/mips/pci/fixup-aruba.c +--- linux-2.6.15/arch/mips/pci/fixup-aruba.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.15-openwrt/arch/mips/pci/fixup-aruba.c 2006-01-10 00:34:41.000000000 +0100 +@@ -0,0 +1,115 @@ ++/************************************************************************** ++ * ++ * BRIEF MODULE DESCRIPTION ++ * PCI fixups for IDT EB434 board ++ * ++ * Copyright 2004 IDT Inc. (rischelp@idt.com) ++ * ++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * 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. ++ * ++ * ++ ************************************************************************** ++ * May 2004 rkt, neb ++ * ++ * Initial Release ++ * ++ * ++ * ++ ************************************************************************** ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ ++ if (dev->bus->number != 0) { ++ return 0; ++ } ++ ++ slot = PCI_SLOT(dev->devfn); ++ dev->irq = 0; ++ ++ if (slot > 0 && slot <= 15) { ++#if 1 ++ if(slot == 10) { ++ if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 9; // intA ++ } else if(slot == 11) { ++ if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 10; // intA ++ if(pin == 2) dev->irq = GROUP4_IRQ_BASE + 10; // intA ++ if(pin == 3) dev->irq = GROUP4_IRQ_BASE + 10; // intA ++ } else if(slot == 12) { ++ if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 11; // intA ++ if(pin == 2) dev->irq = GROUP4_IRQ_BASE + 12; // intB ++ } else if (slot == 13) { ++ if(pin == 1) dev->irq = GROUP4_IRQ_BASE + 12; // intA ++ if(pin == 2) dev->irq = GROUP4_IRQ_BASE + 11; // intB ++ } else { ++ dev->irq = GROUP4_IRQ_BASE + 11; ++ } ++#else ++ switch (pin) { ++ case 1: /* INTA*/ ++ dev->irq = GROUP4_IRQ_BASE + 11; ++ break; ++ case 2: /* INTB */ ++ dev->irq = GROUP4_IRQ_BASE + 11; ++ break; ++ case 3: /* INTC */ ++ dev->irq = GROUP4_IRQ_BASE + 11; ++ break; ++ case 4: /* INTD */ ++ dev->irq = GROUP4_IRQ_BASE + 11; ++ break; ++ default: ++ dev->irq = 0xff; ++ break; ++ } ++#endif ++#ifdef DEBUG ++ printk("irq fixup: slot %d, pin %d, irq %d\n", ++ slot, pin, dev->irq); ++#endif ++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE,dev->irq); ++ } ++ return (dev->irq); ++} ++ ++struct pci_fixup pcibios_fixups[] = { ++ {0} ++}; ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Nur linux-2.6.15/arch/mips/pci/Makefile linux-2.6.15-openwrt/arch/mips/pci/Makefile +--- linux-2.6.15/arch/mips/pci/Makefile 2006-01-03 04:21:10.000000000 +0100 ++++ linux-2.6.15-openwrt/arch/mips/pci/Makefile 2006-01-10 00:32:32.000000000 +0100 +@@ -56,3 +56,4 @@ + obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-tx4938.o ops-tx4938.o + obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o + obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o ++obj-$(CONFIG_MACH_ARUBA) += fixup-aruba.o ops-aruba.o pci-aruba.o +diff -Nur linux-2.6.15/arch/mips/pci/ops-aruba.c linux-2.6.15-openwrt/arch/mips/pci/ops-aruba.c +--- linux-2.6.15/arch/mips/pci/ops-aruba.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.15-openwrt/arch/mips/pci/ops-aruba.c 2006-01-10 00:32:32.000000000 +0100 +@@ -0,0 +1,204 @@ ++/************************************************************************** ++ * ++ * BRIEF MODULE DESCRIPTION ++ * pci_ops for IDT EB434 board ++ * ++ * Copyright 2004 IDT Inc. (rischelp@idt.com) ++ * ++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * 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. ++ * ++ * ++ ************************************************************************** ++ * May 2004 rkt, neb ++ * ++ * Initial Release ++ * ++ * ++ * ++ ************************************************************************** ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#define PCI_ACCESS_READ 0 ++#define PCI_ACCESS_WRITE 1 ++ ++ ++#define PCI_CFG_SET(slot,func,off) \ ++ (rc32434_pci->pcicfga = (0x80000000 | ((slot)<<11) | \ ++ ((func)<<8) | (off))) ++ ++static int config_access(unsigned char access_type, struct pci_bus *bus, ++ unsigned int devfn, unsigned char where, ++ u32 * data) ++{ ++ /* ++ * config cycles are on 4 byte boundary only ++ */ ++ unsigned int slot = PCI_SLOT(devfn); ++ u8 func = PCI_FUNC(devfn); ++ ++ if (slot < 2 || slot > 15) { ++ *data = 0xFFFFFFFF; ++ return -1; ++ } ++ /* Setup address */ ++ PCI_CFG_SET(slot, func, where); ++ rc32434_sync(); ++ ++ if (access_type == PCI_ACCESS_WRITE) { ++ rc32434_sync(); ++ rc32434_pci->pcicfgd = *data; ++ } else { ++ rc32434_sync(); ++ *data = rc32434_pci->pcicfgd; ++ } ++ ++ rc32434_sync(); ++ ++ return 0; ++} ++ ++ ++/* ++ * We can't address 8 and 16 bit words directly. Instead we have to ++ * read/write a 32bit word and mask/modify the data we actually want. ++ */ ++static int read_config_byte(struct pci_bus *bus, unsigned int devfn, ++ int where, u8 * val) ++{ ++ u32 data; ++ int ret; ++ ++ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); ++ *val = (data >> ((where & 3) << 3)) & 0xff; ++ return ret; ++} ++ ++static int read_config_word(struct pci_bus *bus, unsigned int devfn, ++ int where, u16 * val) ++{ ++ u32 data; ++ int ret; ++ ++ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); ++ *val = (data >> ((where & 3) << 3)) & 0xffff; ++ return ret; ++} ++ ++static int read_config_dword(struct pci_bus *bus, unsigned int devfn, ++ int where, u32 * val) ++{ ++ int ret; ++ ++ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val); ++ return ret; ++} ++ ++static int ++write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, ++ u8 val) ++{ ++ u32 data = 0; ++ ++ if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) ++ return -1; ++ ++ data = (data & ~(0xff << ((where & 3) << 3))) | ++ (val << ((where & 3) << 3)); ++ ++ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) ++ return -1; ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++ ++static int ++write_config_word(struct pci_bus *bus, unsigned int devfn, int where, ++ u16 val) ++{ ++ u32 data = 0; ++ ++ if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) ++ return -1; ++ ++ data = (data & ~(0xffff << ((where & 3) << 3))) | ++ (val << ((where & 3) << 3)); ++ ++ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) ++ return -1; ++ ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++ ++static int ++write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, ++ u32 val) ++{ ++ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val)) ++ return -1; ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int pci_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 pci_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); ++ } ++} ++ ++struct pci_ops rc32434_pci_ops = { ++ .read = pci_config_read, ++ .write = pci_config_write, ++}; +diff -Nur linux-2.6.15/arch/mips/pci/pci-aruba.c linux-2.6.15-openwrt/arch/mips/pci/pci-aruba.c +--- linux-2.6.15/arch/mips/pci/pci-aruba.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.15-openwrt/arch/mips/pci/pci-aruba.c 2006-01-10 00:32:32.000000000 +0100 +@@ -0,0 +1,235 @@ ++/************************************************************************** ++ * ++ * BRIEF MODULE DESCRIPTION ++ * PCI initialization for IDT EB434 board ++ * ++ * Copyright 2004 IDT Inc. (rischelp@idt.com) ++ * ++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * 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. ++ * ++ * ++ ************************************************************************** ++ * May 2004 rkt, neb ++ * ++ * Initial Release ++ * ++ * ++ * ++ ************************************************************************** ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PCI_ACCESS_READ 0 ++#define PCI_ACCESS_WRITE 1 ++ ++#undef DEBUG ++#ifdef DEBUG ++#define DBG(x...) printk(x) ++#else ++#define DBG(x...) ++#endif ++/* define an unsigned array for the PCI registers */ ++unsigned int korinaCnfgRegs[25] = { ++ KORINA_CNFG1, KORINA_CNFG2, KORINA_CNFG3, KORINA_CNFG4, ++ KORINA_CNFG5, KORINA_CNFG6, KORINA_CNFG7, KORINA_CNFG8, ++ KORINA_CNFG9, KORINA_CNFG10, KORINA_CNFG11, KORINA_CNFG12, ++ KORINA_CNFG13, KORINA_CNFG14, KORINA_CNFG15, KORINA_CNFG16, ++ KORINA_CNFG17, KORINA_CNFG18, KORINA_CNFG19, KORINA_CNFG20, ++ KORINA_CNFG21, KORINA_CNFG22, KORINA_CNFG23, KORINA_CNFG24 ++}; ++ ++static struct resource rc32434_res_pci_mem2; ++ ++static struct resource rc32434_res_pci_mem1 = { ++ .name = "PCI MEM1", ++ .start = 0x50000000, ++ .end = 0x5FFFFFFF, ++ .flags = IORESOURCE_MEM, ++ .child = &rc32434_res_pci_mem2, ++}; ++static struct resource rc32434_res_pci_mem2 = { ++ .name = "PCI MEM2", ++ .start = 0x60000000, ++ .end = 0x6FFFFFFF, ++ .flags = IORESOURCE_MEM, ++ .parent = &rc32434_res_pci_mem1, ++}; ++static struct resource rc32434_res_pci_io1 = { ++ .name = "PCI I/O1", ++ .start = 0x18800000, ++ .end = 0x188FFFFF, ++ .flags = IORESOURCE_IO, ++}; ++ ++extern struct pci_ops rc32434_pci_ops; ++ ++struct pci_controller rc32434_controller = { ++ .pci_ops = &rc32434_pci_ops, ++ .mem_resource = &rc32434_res_pci_mem1, ++ .io_resource = &rc32434_res_pci_io1, ++ .mem_offset = 0x00000000UL, ++ .io_offset = 0x00000000UL, ++}; ++ ++extern unsigned int arch_has_pci; ++ ++static int __init rc32434_pcibridge_init(void) ++{ ++ ++ unsigned int pciConfigAddr = 0;/*used for writing pci config values */ ++ int loopCount=0 ;/*used for the loop */ ++ ++ unsigned int pcicValue, pcicData=0; ++ unsigned int dummyRead, pciCntlVal = 0; ++ ++ if (!arch_has_pci) return 0; ++ ++ printk("PCI: Initializing PCI\n"); ++ ++ /* Disable the IP bus error for PCI scaning */ ++ pciCntlVal=rc32434_pci->pcic; ++ pciCntlVal &= 0xFFFFFF7; ++ rc32434_pci->pcic = pciCntlVal; ++ ++ ioport_resource.start = rc32434_res_pci_io1.start; ++ ioport_resource.end = rc32434_res_pci_io1.end; ++/* ++ iomem_resource.start = rc32434_res_pci_mem1.start; ++ iomem_resource.end = rc32434_res_pci_mem1.end; ++*/ ++ ++ pcicValue = rc32434_pci->pcic; ++ pcicValue = (pcicValue >> PCIM_SHFT) & PCIM_BIT_LEN; ++ if (!((pcicValue == PCIM_H_EA) || ++ (pcicValue == PCIM_H_IA_FIX) || ++ (pcicValue == PCIM_H_IA_RR))) { ++ /* Not in Host Mode, return ERROR */ ++ return -1; ++ } ++ ++ /* Enables the Idle Grant mode, Arbiter Parking */ ++ pcicData |=(PCIC_igm_m|PCIC_eap_m|PCIC_en_m); ++ rc32434_pci->pcic = pcicData; /* Enable the PCI bus Interface */ ++ /* Zero out the PCI status & PCI Status Mask */ ++ for(;;) { ++ pcicData = rc32434_pci->pcis; ++ if (!(pcicData & PCIS_rip_m)) ++ break; ++ } ++ ++ rc32434_pci->pcis = 0; ++ rc32434_pci->pcism = 0xFFFFFFFF; ++ /* Zero out the PCI decoupled registers */ ++ rc32434_pci->pcidac=0; /* disable PCI decoupled accesses at initialization */ ++ rc32434_pci->pcidas=0; /* clear the status */ ++ rc32434_pci->pcidasm=0x0000007F; /* Mask all the interrupts */ ++ /* Mask PCI Messaging Interrupts */ ++ rc32434_pci_msg->pciiic = 0; ++ rc32434_pci_msg->pciiim = 0xFFFFFFFF; ++ rc32434_pci_msg->pciioic = 0; ++ rc32434_pci_msg->pciioim = 0; ++ ++ /* Setup PCILB0 as Memory Window */ ++ rc32434_pci->pcilba[0].a = (unsigned int) (PCI_ADDR_START); ++ ++ /* setup the PCI map address as same as the local address */ ++ ++ rc32434_pci->pcilba[0].m = (unsigned int) (PCI_ADDR_START); ++ ++ /* Setup PCILBA1 as MEM */ ++#ifdef __MIPSEB__ ++ rc32434_pci->pcilba[0].c = ( ((SIZE_16MB & 0x1f) << PCILBAC_size_b) | PCILBAC_sb_m); ++#else ++ rc32434_pci->pcilba[0].c = ( ((SIZE_16MB & 0x1f) << PCILBAC_size_b)); ++#endif ++ dummyRead = rc32434_pci->pcilba[0].c; /* flush the CPU write Buffers */ ++ ++ rc32434_pci->pcilba[1].a = 0x60000000; ++ ++ rc32434_pci->pcilba[1].m = 0x60000000; ++ /* setup PCILBA2 as IO Window*/ ++#ifdef __MIPSEB__ ++ rc32434_pci->pcilba[1].c = ( ((SIZE_256MB & 0x1f) << PCILBAC_size_b) | PCILBAC_sb_m); ++#else ++ rc32434_pci->pcilba[1].c = ((SIZE_256MB & 0x1f) << PCILBAC_size_b); ++#endif ++ dummyRead = rc32434_pci->pcilba[1].c; /* flush the CPU write Buffers */ ++ rc32434_pci->pcilba[2].a = 0x18C00000; ++ ++ rc32434_pci->pcilba[2].m = 0x18FFFFFF; ++ /* setup PCILBA2 as IO Window*/ ++#ifdef __MIPSEB__ ++ rc32434_pci->pcilba[2].c = ( ((SIZE_4MB & 0x1f) << PCILBAC_size_b) | PCILBAC_sb_m); ++#else ++ rc32434_pci->pcilba[2].c = ((SIZE_4MB & 0x1f) << PCILBAC_size_b); ++#endif ++ ++ dummyRead = rc32434_pci->pcilba[2].c; /* flush the CPU write Buffers */ ++ ++ ++ rc32434_pci->pcilba[3].a = 0x18800000; ++ ++ rc32434_pci->pcilba[3].m = 0x18800000; ++ /* Setup PCILBA3 as IO Window */ ++ ++#ifdef __MIPSEB__ ++ rc32434_pci->pcilba[3].c = ( (((SIZE_1MB & 0x1ff) << PCILBAC_size_b) | PCILBAC_msi_m) | PCILBAC_sb_m); ++#else ++ rc32434_pci->pcilba[3].c = (((SIZE_1MB & 0x1ff) << PCILBAC_size_b) | PCILBAC_msi_m); ++#endif ++ dummyRead = rc32434_pci->pcilba[2].c; /* flush the CPU write Buffers */ ++ ++ pciConfigAddr = (unsigned int)(0x80000004); ++ for(loopCount = 0; loopCount < 24; loopCount++){ ++ rc32434_pci->pcicfga = pciConfigAddr; ++ dummyRead = rc32434_pci->pcicfga; ++ rc32434_pci->pcicfgd = korinaCnfgRegs[loopCount]; ++ dummyRead=rc32434_pci->pcicfgd; ++ pciConfigAddr += 4; ++ } ++ rc32434_pci->pcitc=(unsigned int)((PCITC_RTIMER_VAL&0xff) << PCITC_rtimer_b) | ++ ((PCITC_DTIMER_VAL&0xff)<pcic; ++ pciCntlVal &= ~(PCIC_tnr_m); ++ rc32434_pci->pcic = pciCntlVal; ++ pciCntlVal = rc32434_pci->pcic; ++ ++ register_pci_controller(&rc32434_controller); ++ ++ rc32434_sync(); ++ return 0; ++} ++ ++arch_initcall(rc32434_pcibridge_init); ++ ++/* Do platform specific device initialization at pci_enable_device() time */ ++int pcibios_plat_dev_init(struct pci_dev *dev) ++{ ++ return 0; ++} +diff -Nur linux-2.6.15/drivers/pci/access.c linux-2.6.15-openwrt/drivers/pci/access.c +--- linux-2.6.15/drivers/pci/access.c 2006-01-03 04:21:10.000000000 +0100 ++++ linux-2.6.15-openwrt/drivers/pci/access.c 2006-01-10 00:43:10.000000000 +0100 +@@ -21,6 +21,7 @@ + #define PCI_word_BAD (pos & 1) + #define PCI_dword_BAD (pos & 3) + ++#ifdef __MIPSEB__ + #define PCI_OP_READ(size,type,len) \ + int pci_bus_read_config_##size \ + (struct pci_bus *bus, unsigned int devfn, int pos, type *value) \ +@@ -31,11 +32,32 @@ + if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ + spin_lock_irqsave(&pci_lock, flags); \ + res = bus->ops->read(bus, devfn, pos, len, &data); \ ++ if (len == 1) \ ++ *value = (type)((data >> 24) & 0xff); \ ++ else if (len == 2) \ ++ *value = (type)((data >> 16) & 0xffff); \ ++ else \ + *value = (type)data; \ + spin_unlock_irqrestore(&pci_lock, flags); \ + return res; \ + } ++#else + ++#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; \ ++ u32 data = 0; \ ++ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ ++ spin_lock_irqsave(&pci_lock, flags); \ ++ res = bus->ops->read(bus, devfn, pos, len, &data); \ ++ *value = (type)data; \ ++ spin_unlock_irqrestore(&pci_lock, flags); \ ++ return res; \ ++} ++#endif + #define PCI_OP_WRITE(size,type,len) \ + int pci_bus_write_config_##size \ + (struct pci_bus *bus, unsigned int devfn, int pos, type value) \