diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-05-19 13:14:38 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-05-19 13:14:38 +0000 |
commit | 0771c0af36e37a8012a6371f77dfc753152e8a46 (patch) | |
tree | f515dda07e45a4b651f6939637e40b180954eae1 /target/linux/rb532-2.6/patches | |
parent | e6eda13dd57a5e7b685639bad110f00987f05dd9 (diff) |
convert rb532 to the new structure
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@7273 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/rb532-2.6/patches')
-rw-r--r-- | target/linux/rb532-2.6/patches/100-rb5xx_support.patch | 3415 | ||||
-rw-r--r-- | target/linux/rb532-2.6/patches/110-korina_ethernet.patch | 1347 | ||||
-rw-r--r-- | target/linux/rb532-2.6/patches/120-cf.patch | 987 | ||||
-rw-r--r-- | target/linux/rb532-2.6/patches/140-cmdline_hack.patch | 22 | ||||
-rw-r--r-- | target/linux/rb532-2.6/patches/500-Nand.patch | 142 |
5 files changed, 4 insertions, 5909 deletions
diff --git a/target/linux/rb532-2.6/patches/100-rb5xx_support.patch b/target/linux/rb532-2.6/patches/100-rb5xx_support.patch index dbea022da..5cff9b7d4 100644 --- a/target/linux/rb532-2.6/patches/100-rb5xx_support.patch +++ b/target/linux/rb532-2.6/patches/100-rb5xx_support.patch @@ -47,59 +47,6 @@ diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile # Toshiba RBTX4927 board or # Toshiba RBTX4937 board # -diff -urN linux.old/arch/mips/pci/fixup-rb500.c linux.dev/arch/mips/pci/fixup-rb500.c ---- linux.old/arch/mips/pci/fixup-rb500.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/pci/fixup-rb500.c 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,49 @@ -+/* -+ * Copyright 2001 MontaVista Software Inc. -+ * Author: MontaVista Software, Inc. -+ * stevel@mvista.com or source@mvista.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. -+ */ -+ -+#include <linux/autoconf.h> -+#include <linux/types.h> -+#include <linux/pci.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+ -+#include <asm/rc32434/rc32434.h> -+ -+static int __devinitdata irq_map[2][12] = { -+ { 0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1 }, -+ { 0, 0, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3 } -+}; -+ -+int __devinit pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -+{ -+ int irq = 0; -+ -+ if (dev->bus->number < 2 && PCI_SLOT(dev->devfn) < 12) { -+ irq = irq_map[dev->bus->number][PCI_SLOT(dev->devfn)]; -+ } -+ return irq + GROUP4_IRQ_BASE + 4; -+} -+ diff -urN linux.old/arch/mips/pci/Makefile linux.dev/arch/mips/pci/Makefile --- linux.old/arch/mips/pci/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux.dev/arch/mips/pci/Makefile 2006-12-14 04:09:50.000000000 +0100 @@ -108,1445 +55,6 @@ diff -urN linux.old/arch/mips/pci/Makefile linux.dev/arch/mips/pci/Makefile obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o +obj-$(CONFIG_MIKROTIK_RB500) += pci-rc32434.o ops-rc32434.o fixup-rb500.o -diff -urN linux.old/arch/mips/pci/ops-rc32434.c linux.dev/arch/mips/pci/ops-rc32434.c ---- linux.old/arch/mips/pci/ops-rc32434.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/pci/ops-rc32434.c 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,218 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * pci_ops for IDT EB434 board -+ * -+ * Copyright 2004 IDT Inc. (rischelp@idt.com) -+ * Copyright 2006 Felix Fietkau <nbd@openwrt.org> -+ * -+ * 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 <linux/autoconf.h> -+#include <linux/init.h> -+#include <linux/pci.h> -+#include <linux/types.h> -+#include <linux/delay.h> -+ -+#include <asm/cpu.h> -+#include <asm/io.h> -+ -+#include <asm/rc32434/rc32434.h> -+#include <asm/rc32434/pci.h> -+ -+#define PCI_ACCESS_READ 0 -+#define PCI_ACCESS_WRITE 1 -+ -+ -+#define PCI_CFG_SET(bus,slot,func,off) \ -+ (rc32434_pci->pcicfga = (0x80000000 | \ -+ ((bus) << 16) | ((slot)<<11) | \ -+ ((func)<<8) | (off))) -+ -+static inline int config_access(unsigned char access_type, struct pci_bus *bus, -+ unsigned int devfn, unsigned char where, -+ u32 * data) -+{ -+ unsigned int slot = PCI_SLOT(devfn); -+ u8 func = PCI_FUNC(devfn); -+ -+ /* Setup address */ -+ PCI_CFG_SET(bus->number, slot, func, where); -+ rc32434_sync(); -+ -+ if (access_type == PCI_ACCESS_WRITE) -+ rc32434_pci->pcicfgd = *data; -+ else -+ *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; -+ int delay = 1; -+ -+ if (bus->number == 0 && PCI_SLOT(devfn) > 21) -+ return 0; -+ -+retry: -+ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val); -+ -+ /* PCI scan: check for invalid values, device may not have -+ * finished initializing */ -+ -+ if (where == PCI_VENDOR_ID) { -+ if (ret == 0xffffffff || ret == 0x00000000 || -+ ret == 0x0000ffff || ret == 0xffff0000) { -+ -+ if (delay > 4) -+ return 0; -+ -+ delay *= 2; -+ msleep(delay); -+ goto retry; -+ } -+ } -+ -+ 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 -urN linux.old/arch/mips/pci/pci-rc32434.c linux.dev/arch/mips/pci/pci-rc32434.c ---- linux.old/arch/mips/pci/pci-rc32434.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/pci/pci-rc32434.c 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,234 @@ -+/************************************************************************** -+ * -+ * 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 <linux/autoconf.h> -+#include <linux/types.h> -+#include <linux/pci.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+ -+#include <asm/rc32434/rc32434.h> -+#include <asm/rc32434/pci.h> -+ -+#define PCI_ACCESS_READ 0 -+#define PCI_ACCESS_WRITE 1 -+ -+/* 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_mem1; -+static struct resource rc32434_res_pci_mem2; -+ -+static struct resource rc32434_res_pci_mem1 = { -+ .name = "PCI MEM1", -+ .start = 0x50000000, -+ .end = 0x5FFFFFFF, -+ .flags = IORESOURCE_MEM, -+ .parent = &rc32434_res_pci_mem1, -+ .sibling = NULL, -+ .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, -+ .sibling = NULL, -+ .child = NULL -+}; -+ -+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; -+ -+#define PCI_MEM1_START PCI_ADDR_START -+#define PCI_MEM1_END PCI_ADDR_START + CPUTOPCI_MEM_WIN - 1 -+#define PCI_MEM2_START PCI_ADDR_START + CPUTOPCI_MEM_WIN -+#define PCI_MEM2_END PCI_ADDR_START + ( 2* CPUTOPCI_MEM_WIN) - 1 -+#define PCI_IO1_START PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) -+#define PCI_IO1_END PCI_ADDR_START + (2* CPUTOPCI_MEM_WIN) + CPUTOPCI_IO_WIN -1 -+#define PCI_IO2_START PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) + CPUTOPCI_IO_WIN -+#define PCI_IO2_END PCI_ADDR_START + (2* CPUTOPCI_MEM_WIN) + (2 * CPUTOPCI_IO_WIN) -1 -+ -+ -+struct pci_controller rc32434_controller2; -+ -+struct pci_controller rc32434_controller = { -+ .pci_ops = &rc32434_pci_ops, -+ .mem_resource = &rc32434_res_pci_mem1, -+ .io_resource = &rc32434_res_pci_io1, -+ .mem_offset = 0, -+ .io_offset = 0, -+ -+}; -+ -+#ifdef __MIPSEB__ -+#define PCI_ENDIAN_FLAG PCILBAC_sb_m -+#else -+#define PCI_ENDIAN_FLAG 0 -+#endif -+ -+static int __init rc32434_pcibridge_init(void) -+{ -+ unsigned int pcicValue, pcicData = 0; -+ unsigned int dummyRead, pciCntlVal; -+ int loopCount; -+ unsigned int pciConfigAddr; -+ -+ 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))) { -+ printk("PCI init error!!!\n"); -+ /* 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 */ -+ rc32434_pci->pcilba[0].c = ( ((SIZE_256MB & 0x1f) << PCILBAC_size_b) | PCI_ENDIAN_FLAG); -+ 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*/ -+ rc32434_pci->pcilba[1].c = (((SIZE_256MB & 0x1f) << PCILBAC_size_b )| PCI_ENDIAN_FLAG); -+ 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*/ -+ rc32434_pci->pcilba[2].c = (((SIZE_4MB & 0x1f) << PCILBAC_size_b) | PCI_ENDIAN_FLAG ); -+ dummyRead = rc32434_pci->pcilba[2].c; /* flush the CPU write Buffers */ -+ -+ /* Setup PCILBA3 as IO Window */ -+ rc32434_pci->pcilba[3].a = 0x18800000; -+ rc32434_pci->pcilba[3].m = 0x18800000; -+ rc32434_pci->pcilba[3].c = ( (((SIZE_1MB & 0x1ff) << PCILBAC_size_b) | PCILBAC_msi_m) | PCI_ENDIAN_FLAG); -+ dummyRead = rc32434_pci->pcilba[3].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) << PCITC_dtimer_b); -+ -+ pciCntlVal=rc32434_pci->pcic; -+ pciCntlVal &=~(PCIC_tnr_m); -+ rc32434_pci->pcic = pciCntlVal; -+ pciCntlVal=rc32434_pci->pcic; -+ return 0; -+} -+ -+/* Do platform specific device initialization at pci_enable_device() time */ -+int pcibios_plat_dev_init(struct pci_dev *dev) -+{ -+ if (PCI_SLOT(dev->devfn) == 6 && dev->bus->number == 0) { -+ /* disable prefetched memory range */ -+ pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0); -+ pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x10); -+ -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4); -+ } -+ return 0; -+} -+ -+static int __init rc32434_pci_init(void) -+{ -+ printk("PCI: Initializing PCI\n"); -+ -+ ioport_resource.start = rc32434_res_pci_io1.start; -+ ioport_resource.end = rc32434_res_pci_io1.end; -+ -+ rc32434_pcibridge_init(); -+ -+ register_pci_controller(&rc32434_controller); -+ rc32434_sync(); -+} -+ -+arch_initcall(rc32434_pci_init); -+ -diff -urN linux.old/arch/mips/rb500/devices.c linux.dev/arch/mips/rb500/devices.c ---- linux.old/arch/mips/rb500/devices.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/rb500/devices.c 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,210 @@ -+/* -+ * RouterBoard 500 Platform devices -+ * -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ * -+ * 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. -+ * -+ * $Id$ -+ */ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/ctype.h> -+#include <linux/string.h> -+#include <linux/platform_device.h> -+#include <asm/unaligned.h> -+#include <asm/io.h> -+ -+#include <asm/rc32434/rc32434.h> -+#include <asm/rc32434/dma.h> -+#include <asm/rc32434/dma_v.h> -+#include <asm/rc32434/eth.h> -+#include <asm/rc32434/rb.h> -+ -+#define ETH0_DMA_RX_IRQ GROUP1_IRQ_BASE + 0 -+#define ETH0_DMA_TX_IRQ GROUP1_IRQ_BASE + 1 -+#define ETH0_RX_OVR_IRQ GROUP3_IRQ_BASE + 9 -+#define ETH0_TX_UND_IRQ GROUP3_IRQ_BASE + 10 -+ -+#define ETH0_RX_DMA_ADDR (DMA0_PhysicalAddress + 0*DMA_CHAN_OFFSET) -+#define ETH0_TX_DMA_ADDR (DMA0_PhysicalAddress + 1*DMA_CHAN_OFFSET) -+ -+static struct resource korina_dev0_res[] = { -+ { -+ .name = "korina_regs", -+ .start = ETH0_PhysicalAddress, -+ .end = ETH0_PhysicalAddress + sizeof(ETH_t), -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "korina_rx", -+ .start = ETH0_DMA_RX_IRQ, -+ .end = ETH0_DMA_RX_IRQ, -+ .flags = IORESOURCE_IRQ -+ }, -+ { -+ .name = "korina_tx", -+ .start = ETH0_DMA_TX_IRQ, -+ .end = ETH0_DMA_TX_IRQ, -+ .flags = IORESOURCE_IRQ -+ }, -+ { -+ .name = "korina_ovr", -+ .start = ETH0_RX_OVR_IRQ, -+ .end = ETH0_RX_OVR_IRQ, -+ .flags = IORESOURCE_IRQ -+ }, -+ { -+ .name = "korina_und", -+ .start = ETH0_TX_UND_IRQ, -+ .end = ETH0_TX_UND_IRQ, -+ .flags = IORESOURCE_IRQ -+ }, -+ { -+ .name = "korina_dma_rx", -+ .start = ETH0_RX_DMA_ADDR, -+ .end = ETH0_RX_DMA_ADDR + DMA_CHAN_OFFSET - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "korina_dma_tx", -+ .start = ETH0_TX_DMA_ADDR, -+ .end = ETH0_TX_DMA_ADDR + DMA_CHAN_OFFSET - 1, -+ .flags = IORESOURCE_MEM, -+ } -+}; -+ -+static struct korina_device korina_dev0_data = { -+ .name = "korina0", -+ .mac = { 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee } -+}; -+ -+static struct platform_device korina_dev0 = { -+ .id = 0, -+ .name = "korina", -+ .dev.platform_data = &korina_dev0_data, -+ .resource = korina_dev0_res, -+ .num_resources = ARRAY_SIZE(korina_dev0_res), -+}; -+ -+ -+#define CF_GPIO_NUM 13 -+ -+static struct resource cf_slot0_res[] = { -+ { -+ .name = "cf_membase", -+ .flags = IORESOURCE_MEM -+ }, -+ { -+ .name = "cf_irq", -+ .start = (8 + 4 * 32 + CF_GPIO_NUM), /* 149 */ -+ .end = (8 + 4 * 32 + CF_GPIO_NUM), -+ .flags = IORESOURCE_IRQ -+ } -+}; -+ -+static struct cf_device cf_slot0_data = { -+ .gpio_pin = 13 -+}; -+ -+static struct platform_device cf_slot0 = { -+ .id = 0, -+ .name = "rb500-cf", -+ .dev.platform_data = &cf_slot0_data, -+ .resource = cf_slot0_res, -+ .num_resources = ARRAY_SIZE(cf_slot0_res), -+}; -+ -+/* Resources and device for NAND. There is no data needed and no irqs, so just define the memory used. */ -+static struct resource nand_slot0_res[] = { -+ { -+ .name = "nand_membase", -+ .flags = IORESOURCE_MEM -+ } -+}; -+ -+static struct platform_device nand_slot0 = { -+ .id = 0, -+ .name = "rb500-nand", -+ .resource = nand_slot0_res, -+ .num_resources = ARRAY_SIZE(nand_slot0_res), -+}; -+ -+ -+static struct platform_device *rb500_devs[] = { -+ &korina_dev0, -+ &nand_slot0, -+ &cf_slot0 -+}; -+ -+static void __init parse_mac_addr(char* macstr) -+{ -+ int i, j; -+ unsigned char result, value; -+ -+ for (i=0; i<6; i++) { -+ result = 0; -+ if (i != 5 && *(macstr+2) != ':') { -+ return; -+ } -+ for (j=0; j<2; j++) { -+ if (isxdigit(*macstr) && (value = isdigit(*macstr) ? *macstr-'0' : -+ toupper(*macstr)-'A'+10) < 16) { -+ result = result*16 + value; -+ macstr++; -+ } -+ else return; -+ } -+ -+ macstr++; -+ korina_dev0_data.mac[i] = result; -+ } -+} -+ -+ -+/* DEVICE CONTROLLER 1 */ -+#define CFG_DC_DEV1 (void*)0xb8010010 -+#define CFG_DC_DEV2 (void*)0xb8010020 -+#define CFG_DC_DEVBASE 0x0 -+#define CFG_DC_DEVMASK 0x4 -+#define CFG_DC_DEVC 0x8 -+#define CFG_DC_DEVTC 0xC -+ -+ -+static int __init plat_setup_devices(void) -+{ -+ /* Look for the CF card reader */ -+ if (!readl(CFG_DC_DEV1 + CFG_DC_DEVMASK)) -+ rb500_devs[1] = NULL; -+ else { -+ cf_slot0_res[0].start = readl(CFG_DC_DEV1 + CFG_DC_DEVBASE); -+ cf_slot0_res[0].end = cf_slot0_res[0].start + 0x1000; -+ } -+ -+ /* There is always a NAND device */ -+ nand_slot0_res[0].start = readl( CFG_DC_DEV2 + CFG_DC_DEVBASE); -+ nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000; -+ -+ return platform_add_devices(rb500_devs, ARRAY_SIZE(rb500_devs)); -+} -+ -+static int __init setup_kmac(char *s) -+{ -+ printk("korina mac = %s\n",s); -+ parse_mac_addr(s); -+ return 0; -+} -+ -+__setup("kmac=", setup_kmac); -+arch_initcall(plat_setup_devices); -+ -+ -diff -urN linux.old/arch/mips/rb500/irq.c linux.dev/arch/mips/rb500/irq.c ---- linux.old/arch/mips/rb500/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/rb500/irq.c 2006-12-14 04:14:16.000000000 +0100 -@@ -0,0 +1,264 @@ -+/* -+ * BRIEF MODULE DESCRIPTION -+ * RC32434 interrupt routines. -+ * -+ * Copyright 2002 MontaVista Software Inc. -+ * Author: MontaVista Software, Inc. -+ * stevel@mvista.com or source@mvista.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. -+ */ -+ -+#include <linux/errno.h> -+#include <linux/init.h> -+#include <linux/kernel_stat.h> -+#include <linux/module.h> -+#include <linux/signal.h> -+#include <linux/sched.h> -+#include <linux/types.h> -+#include <linux/interrupt.h> -+#include <linux/ioport.h> -+#include <linux/timex.h> -+#include <linux/slab.h> -+#include <linux/random.h> -+#include <linux/delay.h> -+ -+#include <asm/bitops.h> -+#include <asm/bootinfo.h> -+#include <asm/io.h> -+#include <asm/irq.h> -+#include <asm/time.h> -+#include <asm/mipsregs.h> -+#include <asm/system.h> -+#include <asm/rc32434/rc32434.h> -+#include <asm/rc32434/gpio.h> -+ -+extern void set_debug_traps(void); -+extern irq_cpustat_t irq_stat [NR_CPUS]; -+unsigned int local_bh_count[NR_CPUS]; -+unsigned int local_irq_count[NR_CPUS]; -+ -+static unsigned int startup_irq(unsigned int irq); -+static void rb500_end_irq(unsigned int irq_nr); -+static void mask_and_ack_irq(unsigned int irq_nr); -+static void rb500_enable_irq(unsigned int irq_nr); -+static void rb500_disable_irq(unsigned int irq_nr); -+ -+extern void __init init_generic_irq(void); -+ -+typedef struct { -+ u32 mask; /* mask of valid bits in pending/mask registers */ -+ volatile u32 *base_addr; -+} intr_group_t; -+ -+#define RC32434_NR_IRQS (GROUP4_IRQ_BASE + 32) -+ -+#if (NR_IRQS < RC32434_NR_IRQS) -+#error Too little irqs defined. Did you override <asm/irq.h> ? -+#endif -+ -+static const intr_group_t intr_group[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(base) (*(base)) -+#define READ_MASK(base) (*(base + 2)) -+#define WRITE_MASK(base, val) (*(base + 2) = (val)) -+ -+static inline int irq_to_group(unsigned int irq_nr) -+{ -+ return ((irq_nr - GROUP0_IRQ_BASE) >> 5); -+} -+ -+static inline int group_to_ip(unsigned int group) -+{ -+ return group + 2; -+} -+ -+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 rb500_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 { -+ group = ip >> 5; -+ -+ ip &= (1<<5)-1; -+ intr_bit = 1 << ip; -+ -+ enable_local_irq(group_to_ip(group)); -+ -+ addr = intr_group[group].base_addr; -+ WRITE_MASK(addr, READ_MASK(addr) & ~intr_bit); -+ } -+} -+ -+static void rb500_disable_irq(unsigned int irq_nr) -+{ -+ int ip = irq_nr - GROUP0_IRQ_BASE; -+ unsigned int group, intr_bit, mask; -+ volatile unsigned int *addr; -+ -+ if (ip < 0) { -+ disable_local_irq(irq_nr); -+ }else{ -+ group = ip >> 5; -+ -+ ip &= (1<<5) -1; -+ intr_bit = 1 << ip; -+ addr = intr_group[group].base_addr; -+ mask = READ_MASK(addr); -+ mask |= intr_bit; -+ WRITE_MASK(addr,mask); -+ -+ /* -+ * if there are no more interrupts enabled in this -+ * group, disable corresponding IP -+ */ -+ if (mask == intr_group[group].mask) -+ disable_local_irq(group_to_ip(group)); -+ } -+} -+ -+static unsigned int startup_irq(unsigned int irq_nr) -+{ -+ rb500_enable_irq(irq_nr); -+ return 0; -+} -+ -+static void shutdown_irq(unsigned int irq_nr) -+{ -+ rb500_disable_irq(irq_nr); -+ return; -+} -+ -+static void mask_and_ack_irq(unsigned int irq_nr) -+{ -+ rb500_disable_irq(irq_nr); -+ ack_local_irq(group_to_ip(irq_to_group(irq_nr))); -+} -+ -+static void rb500_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); -+ return; -+ } -+ -+ if (ip < 0) { -+ enable_local_irq(irq_nr); -+ } else { -+ group = ip >> 5; -+ -+ ip &= (1 << 5) - 1; -+ intr_bit = 1 << ip; -+ -+ if (irq_nr >= GROUP4_IRQ_BASE && irq_nr <= (GROUP4_IRQ_BASE + 13)) { -+ gpio->gpioistat = gpio->gpioistat & ~intr_bit; -+ } -+ -+ enable_local_irq(group_to_ip(group)); -+ -+ addr = intr_group[group].base_addr; -+ WRITE_MASK(addr, READ_MASK(addr) & ~intr_bit); -+ } -+} -+ -+static struct hw_interrupt_type rc32434_irq_type = { -+ .typename = "RB500", -+ .startup = startup_irq, -+ .shutdown = shutdown_irq, -+ .enable = rb500_enable_irq, -+ .disable = rb500_disable_irq, -+ .ack = mask_and_ack_irq, -+ .end = rb500_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)); -+ -+ 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].chip = &rc32434_irq_type; -+ spin_lock_init(&irq_desc[i].lock); -+ } -+} -+ -+/* Main Interrupt dispatcher */ -+asmlinkage void plat_irq_dispatch(void) -+{ -+ unsigned int ip, pend, group; -+ volatile unsigned int *addr; -+ unsigned int cp0_cause = read_c0_cause() & read_c0_status(); -+ -+ if (cp0_cause & CAUSEF_IP7) { -+ ll_timer_interrupt(7); -+ } else if ((ip = (cp0_cause & 0x7c00))) { -+ group = 21 - rc32434_clz(ip); -+ -+ addr = intr_group[group].base_addr; -+ -+ pend = READ_PEND(addr); -+ pend &= ~READ_MASK(addr); // only unmasked interrupts -+ pend = 39 - rc32434_clz(pend); -+ do_IRQ((group << 5) + pend); -+ } -+} -diff -urN linux.old/arch/mips/rb500/Makefile linux.dev/arch/mips/rb500/Makefile ---- linux.old/arch/mips/rb500/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/rb500/Makefile 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,5 @@ -+# -+# Makefile for the RB500 board specific parts of the kernel -+# -+ -+obj-y += irq.o time.o setup.o serial.o prom.o misc.o devices.o -diff -urN linux.old/arch/mips/rb500/misc.c linux.dev/arch/mips/rb500/misc.c ---- linux.old/arch/mips/rb500/misc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/rb500/misc.c 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,56 @@ -+#include <linux/module.h> -+#include <linux/kernel.h> /* printk() */ -+#include <linux/types.h> /* size_t */ -+#include <linux/pci.h> -+#include <linux/spinlock.h> -+#include <asm/rc32434/rb.h> -+ -+#define GPIO_BADDR 0xb8050000 -+ -+ -+static volatile unsigned char *devCtl3Base = 0; -+static unsigned char latchU5State = 0; -+static spinlock_t clu5Lock = SPIN_LOCK_UNLOCKED; -+ -+void set434Reg(unsigned regOffs, unsigned bit, unsigned len, unsigned val) { -+ unsigned flags, data; -+ unsigned i = 0; -+ spin_lock_irqsave(&clu5Lock, flags); -+ data = *(volatile unsigned *) (IDT434_REG_BASE + regOffs); -+ for (i = 0; i != len; ++i) { -+ if (val & (1 << i)) data |= (1 << (i + bit)); -+ else data &= ~(1 << (i + bit)); -+ } -+ *(volatile unsigned *) (IDT434_REG_BASE + regOffs) = data; -+ spin_unlock_irqrestore(&clu5Lock, flags); -+} -+ -+void changeLatchU5(unsigned char orMask, unsigned char nandMask) { -+ unsigned flags; -+ spin_lock_irqsave(&clu5Lock, flags); -+ latchU5State = (latchU5State | orMask) & ~nandMask; -+ if( !devCtl3Base) devCtl3Base = (volatile unsigned char *) -+ KSEG1ADDR(*(volatile unsigned *) KSEG1ADDR(0x18010030)); -+ *devCtl3Base = latchU5State; -+ spin_unlock_irqrestore(&clu5Lock, flags); -+} -+ -+u32 gpio_get(gpio_func func) -+{ -+ return readl((void *) GPIO_BADDR + func); -+} -+ -+void gpio_set(gpio_func func, u32 mask, u32 value) -+{ -+ u32 val = readl((void *) GPIO_BADDR + func); -+ -+ val &= ~mask; -+ val |= value & mask; -+ -+ writel(val, (void *) GPIO_BADDR + func); -+} -+ -+EXPORT_SYMBOL(gpio_set); -+EXPORT_SYMBOL(gpio_get); -+EXPORT_SYMBOL(set434Reg); -+EXPORT_SYMBOL(changeLatchU5); -diff -urN linux.old/arch/mips/rb500/prom.c linux.dev/arch/mips/rb500/prom.c ---- linux.old/arch/mips/rb500/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/rb500/prom.c 2006-12-14 05:15:05.000000000 +0100 -@@ -0,0 +1,161 @@ -+/* -+* prom.c -+********************************************************************** -+* P . Sadik Oct 10, 2003 -+* -+* Started change log -+* idt_cpu_freq is make a kernel configuration parameter -+* idt_cpu_freq is exported so that other modules can use it. -+* Code cleanup -+********************************************************************** -+* P. Sadik Oct 20, 2003 -+* -+* Removed NVRAM code from here, since they are already available under -+* nvram directory. -+* Added serial port initialisation. -+********************************************************************** -+********************************************************************** -+* P. Sadik Oct 30, 2003 -+* -+* Added reset_cons_port -+********************************************************************** -+ -+ P.Christeas, 2005-2006 -+ Port to 2.6, add 2.6 cmdline parsing -+ -+*/ -+ -+#include <linux/autoconf.h> -+#include <linux/init.h> -+#include <linux/mm.h> -+#include <linux/module.h> -+#include <linux/string.h> -+#include <linux/console.h> -+#include <asm/bootinfo.h> -+#include <linux/bootmem.h> -+#include <linux/ioport.h> -+#include <linux/blkdev.h> -+#include <asm/rc32434/ddr.h> -+ -+#define PROM_ENTRY(x) (0xbfc00000+((x)*8)) -+extern void __init setup_serial_port(void); -+ -+unsigned int idt_cpu_freq = 132000000; -+EXPORT_SYMBOL(idt_cpu_freq); -+unsigned int board_type = 500; -+EXPORT_SYMBOL(board_type); -+unsigned int gpio_bootup_state = 0; -+EXPORT_SYMBOL(gpio_bootup_state); -+ -+ -+char mips_mac_address[18] = "08:00:06:05:40:01"; -+EXPORT_SYMBOL(mips_mac_address); -+ -+/* what to append to cmdline when button is [not] pressed */ -+#define GPIO_INIT_NOBUTTON "" -+#define GPIO_INIT_BUTTON " 2" -+ -+#ifdef CONFIG_MIKROTIK_RB500 -+unsigned soft_reboot = 0; -+EXPORT_SYMBOL(soft_reboot); -+#endif -+ -+#define SR_NMI 0x00180000 /* NMI */ -+#define SERIAL_SPEED_ENTRY 0x00000001 -+ -+#ifdef CONFIG_REMOTE_DEBUG -+extern int remote_debug; -+#endif -+ -+extern unsigned long mips_machgroup; -+extern unsigned long mips_machtype; -+ -+#define FREQ_TAG "HZ=" -+#define GPIO_TAG "gpio=" -+#define KMAC_TAG "kmac=" -+#define MEM_TAG "mem=" -+#define BOARD_TAG "board=" -+#define IGNORE_CMDLINE_MEM 1 -+#define DEBUG_DDR -+ -+void parse_soft_settings(unsigned *ptr, unsigned size); -+void parse_hard_settings(unsigned *ptr, unsigned size); -+ -+void __init prom_setup_cmdline(void); -+ -+void __init prom_init(void) -+{ -+ DDR_t ddr = (DDR_t) DDR_VirtualAddress; /* define the pointer to the DDR registers */ -+ phys_t memsize = 0-ddr->ddrmask; -+ -+ /* this should be the very first message, even before serial is properly initialized */ -+ prom_setup_cmdline(); -+ setup_serial_port(); -+ -+ mips_machgroup = MACH_GROUP_MIKROTIK; -+ soft_reboot = read_c0_status() & SR_NMI; -+ pm_power_off = NULL; -+ -+ /* -+ * give all RAM to boot allocator, -+ * except for the first 0x400 and the last 0x200 bytes -+ */ -+ add_memory_region(ddr->ddrbase + 0x400, memsize - 0x600, BOOT_MEM_RAM); -+} -+ -+void prom_free_prom_memory(void) -+{ -+ /* FIXME: STUB */ -+} -+ -+void __init prom_setup_cmdline(void){ -+ char cmd_line[CL_SIZE]; -+ char *cp; -+ int prom_argc; -+ char **prom_argv, **prom_envp; -+ int i; -+ -+ prom_argc = fw_arg0; -+ prom_argv = (char **) fw_arg1; -+ prom_envp = (char **) fw_arg2; -+ -+ cp=cmd_line; -+ /* Note: it is common that parameters start at argv[1] and not argv[0], -+ however, our elf loader starts at [0] */ -+ for(i=0;i<prom_argc;i++){ -+ if (strncmp(prom_argv[i], FREQ_TAG, sizeof(FREQ_TAG) - 1) == 0) { -+ idt_cpu_freq = simple_strtoul(prom_argv[i] + sizeof(FREQ_TAG) - 1, 0, 10); -+ continue; -+ } -+#ifdef IGNORE_CMDLINE_MEM -+ /* parses out the "mem=xx" arg */ -+ if (strncmp(prom_argv[i], MEM_TAG, sizeof(MEM_TAG) - 1) == 0) { -+ continue; -+ } -+#endif -+ if (i>0) *(cp++) = ' '; -+ if (strncmp(prom_argv[i], BOARD_TAG, sizeof(BOARD_TAG) - 1) == 0) { -+ board_type = simple_strtoul(prom_argv[i] + sizeof(BOARD_TAG) - 1, 0, 10); -+ } -+ if (strncmp(prom_argv[i], GPIO_TAG, sizeof(GPIO_TAG) - 1) == 0) { -+ gpio_bootup_state = simple_strtoul(prom_argv[i] + sizeof(GPIO_TAG) - 1, 0, 10); -+ } -+ strcpy(cp,prom_argv[i]); -+ cp+=strlen(prom_argv[i]); -+ } -+ -+ i=strlen(arcs_cmdline); -+ if (i>0){ -+ *(cp++) = ' '; -+ strcpy(cp,arcs_cmdline); -+ cp+=strlen(arcs_cmdline); -+ } -+ if (gpio_bootup_state&0x02) -+ strcpy(cp,GPIO_INIT_NOBUTTON); -+ else -+ strcpy(cp,GPIO_INIT_BUTTON); -+ cmd_line[CL_SIZE-1] = '\0'; -+ -+ strcpy(arcs_cmdline,cmd_line); -+} -+ -diff -urN linux.old/arch/mips/rb500/serial.c linux.dev/arch/mips/rb500/serial.c ---- linux.old/arch/mips/rb500/serial.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/rb500/serial.c 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,77 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * Serial port initialisation. -+ * -+ * 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 <linux/autoconf.h> -+#include <linux/init.h> -+#include <linux/sched.h> -+#include <linux/pci.h> -+#include <linux/interrupt.h> -+#include <linux/tty.h> -+#include <linux/serial.h> -+#include <linux/serial_core.h> -+ -+#include <asm/time.h> -+#include <asm/cpu.h> -+#include <asm/bootinfo.h> -+#include <asm/irq.h> -+#include <asm/serial.h> -+#include <asm/rc32434/rc32434.h> -+ -+extern unsigned int idt_cpu_freq; -+ -+static struct uart_port serial_req = { -+ .type = PORT_16550A, -+ .line = 0, -+ .irq = RC32434_UART0_IRQ, -+ .flags = STD_COM_FLAGS, -+ .iotype = UPIO_MEM, -+ .membase = (char *) KSEG1ADDR(RC32434_UART0_BASE), -+// .fifosize = 14 -+ .regshift = 2 -+}; -+ -+int __init setup_serial_port(void) -+{ -+ serial_req.uartclk = idt_cpu_freq; -+ -+ if (early_serial_setup(&serial_req)) -+ return -ENODEV; -+ -+ return(0); -+} -diff -urN linux.old/arch/mips/rb500/setup.c linux.dev/arch/mips/rb500/setup.c ---- linux.old/arch/mips/rb500/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/rb500/setup.c 2006-12-14 04:51:12.000000000 +0100 -@@ -0,0 +1,81 @@ -+/* -+ * setup.c - boot time setup code -+ */ -+ -+#include <linux/init.h> -+#include <linux/mm.h> -+#include <linux/sched.h> -+#include <linux/irq.h> -+#include <linux/ioport.h> -+#include <linux/pm.h> -+#include <asm/bootinfo.h> -+#include <asm/mipsregs.h> -+#include <asm/pgtable.h> -+#include <asm/reboot.h> -+#include <asm/addrspace.h> /* for KSEG1ADDR() */ -+#include <asm/time.h> -+#include <asm/io.h> -+#include <asm/rc32434/rc32434.h> -+#include <asm/rc32434/pci.h> -+ -+#ifdef CONFIG_PCI -+extern void *rc32434_time_init(void); -+extern int __init rc32434_pcibridge_init(void); -+#endif -+ -+#define epldMask ((volatile unsigned char *)0xB900000d) -+ -+static void rb_machine_restart(char *command) -+{ -+ /* just jump to the reset vector */ -+ * (volatile unsigned *) KSEG1ADDR(0x18008000) = 0x80000001; -+ ((void (*)(void))KSEG1ADDR(0x1FC00000u))(); -+} -+ -+static void rb_machine_halt(void) -+{ -+ for(;;) continue; -+} -+ -+#ifdef CONFIG_CPU_HAS_WB -+void (*__wbflush) (void); -+ -+static void rb_write_buffer_flush(void) -+{ -+ __asm__ __volatile__ -+ ("sync\n\t" "nop\n\t" "loop: bc0f loop\n\t" "nop\n\t"); -+} -+#endif -+ -+void __init plat_mem_setup(void) -+{ -+ unsigned int pciCntlVal; -+ -+ board_time_init = rc32434_time_init; -+ -+#ifdef CONFIG_CPU_HAS_WB -+ __wbflush = rb_write_buffer_flush; -+#endif -+ _machine_restart = rb_machine_restart; -+ _machine_halt = rb_machine_halt; -+ /*_machine_power_off = rb_machine_power_halt;*/ -+ pm_power_off = rb_machine_halt; -+ -+ set_io_port_base(KSEG1); -+ -+ pciCntlVal=rc32434_pci->pcic; -+ pciCntlVal &= 0xFFFFFF7; -+ rc32434_pci->pcic = pciCntlVal; -+ -+#ifdef CONFIG_PCI -+ /* Enable PCI interrupts in EPLD Mask register */ -+ *epldMask = 0x0; -+ *(epldMask + 1) = 0x0; -+#endif -+ write_c0_wired(0); -+} -+ -+const char *get_system_type(void) -+{ -+ return "MIPS RB500"; -+} -diff -urN linux.old/arch/mips/rb500/time.c linux.dev/arch/mips/rb500/time.c ---- linux.old/arch/mips/rb500/time.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/rb500/time.c 2006-12-14 04:48:33.000000000 +0100 -@@ -0,0 +1,93 @@ -+/* -+**************************************************************************** -+* Carsten Langgaard, carstenl@mips.com -+* Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. -+* -+*************************************************************************** -+* -+* This program is free software; you can distribute it and/or modify it -+* under the terms of the GNU General Public License (Version 2) as -+* published by the Free Software Foundation. -+* -+* This program is distributed in the hope 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. -+* -+**************************************************************************** -+* -+* Setting up the clock on the MIPS boards. -+* -+**************************************************************************** -+* P. Sadik Oct 10, 2003 -+* -+* Started change log. -+* mips_counter_frequency is now calculated at run time, based on idt_cpu_freq. -+* Code cleanup -+**************************************************************************** -+*/ -+ -+#include <linux/autoconf.h> -+#include <linux/init.h> -+#include <linux/kernel_stat.h> -+#include <linux/sched.h> -+#include <linux/spinlock.h> -+#include <linux/mc146818rtc.h> -+#include <linux/irq.h> -+#include <linux/timex.h> -+ -+#include <asm/mipsregs.h> -+#include <asm/ptrace.h> -+#include <asm/debug.h> -+#include <asm/rc32434/rc32434.h> -+ -+static unsigned long r4k_offset; /* Amount to incr compare reg each time */ -+static unsigned long r4k_cur; /* What counter should be at next timer irq */ -+extern unsigned int mips_hpt_frequency; -+extern unsigned int idt_cpu_freq; -+ -+/* -+ * Figure out the r4k offset, the amount to increment the compare -+ * register for each time tick. There is no RTC available. -+ * -+ * The RC32434 counts at half the CPU *core* speed. -+ */ -+static unsigned long __init cal_r4koff(void) -+{ -+ mips_hpt_frequency = idt_cpu_freq * IDT_CLOCK_MULT / 2; -+ return (mips_hpt_frequency / HZ); -+} -+ -+ -+void __init rc32434_time_init(void) -+{ -+ unsigned int est_freq, flags; -+ -+ local_irq_save(flags); -+ -+ printk("calculating r4koff... "); -+ r4k_offset = cal_r4koff(); -+ printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); -+ -+ est_freq = 2*r4k_offset*HZ; -+ est_freq += 5000; /* round */ -+ est_freq -= est_freq%10000; -+ printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, -+ (est_freq%1000000)*100/1000000); -+ local_irq_restore(flags); -+} -+ -+void __init plat_timer_setup(struct irqaction *irq) -+{ -+ /* we are using the cpu counter for timer interrupts */ -+ setup_irq(MIPS_CPU_TIMER_IRQ, irq); -+ -+ /* to generate the first timer interrupt */ -+ r4k_cur = (read_c0_count() + r4k_offset); -+ write_c0_compare(r4k_cur); -+} -+ diff -urN linux.old/drivers/pci/Makefile linux.dev/drivers/pci/Makefile --- linux.old/drivers/pci/Makefile 2006-11-29 22:57:37.000000000 +0100 +++ linux.dev/drivers/pci/Makefile 2006-12-14 04:09:50.000000000 +0100 @@ -1583,1927 +91,4 @@ diff -urN linux.old/include/asm-mips/cpu.h linux.dev/include/asm-mips/cpu.h /* * ISA Level encodings -diff -urN linux.old/include/asm-mips/rc32434/ddr.h linux.dev/include/asm-mips/rc32434/ddr.h ---- linux.old/include/asm-mips/rc32434/ddr.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/rc32434/ddr.h 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,173 @@ -+#ifndef __IDT_DDR_H__ -+#define __IDT_DDR_H__ -+ -+/******************************************************************************* -+ * -+ * Copyright 2002 Integrated Device Technology, Inc. -+ * All rights reserved. -+ * -+ * DDR register definition. -+ * -+ * File : $Id: ddr.h,v 1.2 2002/06/06 18:34:03 astichte Exp $ -+ * -+ * Author : ryan.holmQVist@idt.com -+ * Date : 20011005 -+ * Update : -+ * $Log: ddr.h,v $ -+ * Revision 1.2 2002/06/06 18:34:03 astichte -+ * Added XXX_PhysicalAddress and XXX_VirtualAddress -+ * -+ * Revision 1.1 2002/05/29 17:33:21 sysarch -+ * jba File moved from vcode/include/idt/acacia -+ * -+ * -+ ******************************************************************************/ -+ -+enum -+{ -+ DDR0_PhysicalAddress = 0x18018000, -+ DDR_PhysicalAddress = DDR0_PhysicalAddress, // Default -+ -+ DDR0_VirtualAddress = 0xb8018000, -+ DDR_VirtualAddress = DDR0_VirtualAddress, // Default -+} ; -+ -+typedef struct DDR_s -+{ -+ u32 ddrbase ; -+ u32 ddrmask ; -+ u32 res1; -+ u32 res2; -+ u32 ddrc ; -+ u32 ddrabase ; -+ u32 ddramask ; -+ u32 ddramap ; -+ u32 ddrcust; -+ u32 ddrrdc; -+ u32 ddrspare; -+} volatile *DDR_t ; -+ -+enum -+{ -+ DDR0BASE_baseaddr_b = 16, -+ DDR0BASE_baseaddr_m = 0xffff0000, -+ -+ DDR0MASK_mask_b = 16, -+ DDR0MASK_mask_m = 0xffff0000, -+ -+ DDR1BASE_baseaddr_b = 16, -+ DDR1BASE_baseaddr_m = 0xffff0000, -+ -+ DDR1MASK_mask_b = 16, -+ DDR1MASK_mask_m = 0xffff0000, -+ -+ DDRC_ata_b = 5, -+ DDRC_ata_m = 0x000000E0, -+ DDRC_dbw_b = 8, -+ DDRC_dbw_m = 0x00000100, -+ DDRC_wr_b = 9, -+ DDRC_wr_m = 0x00000600, -+ DDRC_ps_b = 11, -+ DDRC_ps_m = 0x00001800, -+ DDRC_dtype_b = 13, -+ DDRC_dtype_m = 0x0000e000, -+ DDRC_rfc_b = 16, -+ DDRC_rfc_m = 0x000f0000, -+ DDRC_rp_b = 20, -+ DDRC_rp_m = 0x00300000, -+ DDRC_ap_b = 22, -+ DDRC_ap_m = 0x00400000, -+ DDRC_rcd_b = 23, -+ DDRC_rcd_m = 0x01800000, -+ DDRC_cl_b = 25, -+ DDRC_cl_m = 0x06000000, -+ DDRC_dbm_b = 27, -+ DDRC_dbm_m = 0x08000000, -+ DDRC_sds_b = 28, -+ DDRC_sds_m = 0x10000000, -+ DDRC_atp_b = 29, -+ DDRC_atp_m = 0x60000000, -+ DDRC_re_b = 31, -+ DDRC_re_m = 0x80000000, -+ -+ DDRRDC_ces_b = 0, -+ DDRRDC_ces_m = 0x00000001, -+ DDRRDC_ace_b = 1, -+ DDRRDC_ace_m = 0x00000002, -+ -+ DDRABASE_baseaddr_b = 16, -+ DDRABASE_baseaddr_m = 0xffff0000, -+ -+ DDRAMASK_mask_b = 16, -+ DDRAMASK_mask_m = 0xffff0000, -+ -+ DDRAMAP_map_b = 16, -+ DDRAMAP_map_m = 0xffff0000, -+ -+ DDRCUST_cs_b = 0, -+ DDRCUST_cs_m = 0x00000003, -+ DDRCUST_we_b = 2, -+ DDRCUST_we_m = 0x00000004, -+ DDRCUST_ras_b = 3, -+ DDRCUST_ras_m = 0x00000008, -+ DDRCUST_cas_b = 4, -+ DDRCUST_cas_m = 0x00000010, -+ DDRCUST_cke_b = 5, -+ DDRCUST_cke_m = 0x00000020, -+ DDRCUST_ba_b = 6, -+ DDRCUST_ba_m = 0x000000c0, -+ -+ RCOUNT_rcount_b = 0, -+ RCOUNT_rcount_m = 0x0000ffff, -+ -+ RCOMPARE_rcompare_b = 0, -+ RCOMPARE_rcompare_m = 0x0000ffff, -+ -+ RTC_ce_b = 0, -+ RTC_ce_m = 0x00000001, -+ RTC_to_b = 1, -+ RTC_to_m = 0x00000002, -+ RTC_rqe_b = 2, -+ RTC_rqe_m = 0x00000004, -+ -+ DDRDQSC_dm_b = 0, -+ DDRDQSC_dm_m = 0x00000003, -+ DDRDQSC_dqsbs_b = 2, -+ DDRDQSC_dqsbs_m = 0x000000fc, -+ DDRDQSC_db_b = 8, -+ DDRDQSC_db_m = 0x00000100, -+ DDRDQSC_dbsp_b = 9, -+ DDRDQSC_dbsp_m = 0x01fffe00, -+ DDRDQSC_bdp_b = 25, -+ DDRDQSC_bdp_m = 0x7e000000, -+ -+ DDRDLLC_eao_b = 0, -+ DDRDLLC_eao_m = 0x00000001, -+ DDRDLLC_eo_b = 1, -+ DDRDLLC_eo_m = 0x0000003e, -+ DDRDLLC_fs_b = 6, -+ DDRDLLC_fs_m = 0x000000c0, -+ DDRDLLC_as_b = 8, -+ DDRDLLC_as_m = 0x00000700, -+ DDRDLLC_sp_b = 11, -+ DDRDLLC_sp_m = 0x001ff800, -+ -+ DDRDLLFC_men_b = 0, -+ DDRDLLFC_men_m = 0x00000001, -+ DDRDLLFC_aen_b = 1, -+ DDRDLLFC_aen_m = 0x00000002, -+ DDRDLLFC_ff_b = 2, -+ DDRDLLFC_ff_m = 0x00000004, -+ -+ DDRDLLTA_addr_b = 2, -+ DDRDLLTA_addr_m = 0xfffffffc, -+ -+ DDRDLLED_dbe_b = 0, -+ DDRDLLED_dbe_m = 0x00000001, -+ DDRDLLED_dte_b = 1, -+ DDRDLLED_dte_m = 0x00000002, -+ -+ -+} ; -+ -+#endif // __IDT_DDR_H__ -diff -urN linux.old/include/asm-mips/rc32434/dma.h linux.dev/include/asm-mips/rc32434/dma.h ---- linux.old/include/asm-mips/rc32434/dma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/rc32434/dma.h 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,168 @@ -+#ifndef __IDT_DMA_H__ -+#define __IDT_DMA_H__ -+ -+/******************************************************************************* -+ * -+ * Copyright 2002 Integrated Device Technology, Inc. -+ * All rights reserved. -+ * -+ * DMA register definition. -+ * -+ * File : $Id: dma.h,v 1.3 2002/06/06 18:34:03 astichte Exp $ -+ * -+ * Author : ryan.holmQVist@idt.com -+ * Date : 20011005 -+ * Update : -+ * $Log: dma.h,v $ -+ * Revision 1.3 2002/06/06 18:34:03 astichte -+ * Added XXX_PhysicalAddress and XXX_VirtualAddress -+ * -+ * Revision 1.2 2002/06/05 18:30:46 astichte -+ * Removed IDTField -+ * -+ * Revision 1.1 2002/05/29 17:33:21 sysarch -+ * jba File moved from vcode/include/idt/acacia -+ * -+ * -+ ******************************************************************************/ -+ -+enum -+{ -+ DMA0_PhysicalAddress = 0x18040000, -+ DMA_PhysicalAddress = DMA0_PhysicalAddress, // Default -+ -+ DMA0_VirtualAddress = 0xb8040000, -+ DMA_VirtualAddress = DMA0_VirtualAddress, // Default -+} ; -+ -+/* -+ * DMA descriptor (in physical memory). -+ */ -+ -+typedef struct DMAD_s -+{ -+ u32 control ; // Control. use DMAD_* -+ u32 ca ; // Current Address. -+ u32 devcs ; // Device control and status. -+ u32 link ; // Next descriptor in chain. -+} volatile *DMAD_t ; -+ -+enum -+{ -+ DMAD_size = sizeof (struct DMAD_s), -+ DMAD_count_b = 0, // in DMAD_t -> control -+ DMAD_count_m = 0x0003ffff, // in DMAD_t -> control -+ DMAD_ds_b = 20, // in DMAD_t -> control -+ DMAD_ds_m = 0x00300000, // in DMAD_t -> control -+ DMAD_ds_ethRcv_v = 0, -+ DMAD_ds_ethXmt_v = 0, -+ DMAD_ds_memToFifo_v = 0, -+ DMAD_ds_fifoToMem_v = 0, -+ DMAD_ds_pciToMem_v = 0, -+ DMAD_ds_memToPci_v = 0, -+ -+ DMAD_devcmd_b = 22, // in DMAD_t -> control -+ DMAD_devcmd_m = 0x01c00000, // in DMAD_t -> control -+ DMAD_devcmd_byte_v = 0, //memory-to-memory -+ DMAD_devcmd_halfword_v = 1, //memory-to-memory -+ DMAD_devcmd_word_v = 2, //memory-to-memory -+ DMAD_devcmd_2words_v = 3, //memory-to-memory -+ DMAD_devcmd_4words_v = 4, //memory-to-memory -+ DMAD_devcmd_6words_v = 5, //memory-to-memory -+ DMAD_devcmd_8words_v = 6, //memory-to-memory -+ DMAD_devcmd_16words_v = 7, //memory-to-memory -+ DMAD_cof_b = 25, // chain on finished -+ DMAD_cof_m = 0x02000000, // -+ DMAD_cod_b = 26, // chain on done -+ DMAD_cod_m = 0x04000000, // -+ DMAD_iof_b = 27, // interrupt on finished -+ DMAD_iof_m = 0x08000000, // -+ DMAD_iod_b = 28, // interrupt on done -+ DMAD_iod_m = 0x10000000, // -+ DMAD_t_b = 29, // terminated -+ DMAD_t_m = 0x20000000, // -+ DMAD_d_b = 30, // done -+ DMAD_d_m = 0x40000000, // -+ DMAD_f_b = 31, // finished -+ DMAD_f_m = 0x80000000, // -+} ; -+ -+/* -+ * DMA register (within Internal Register Map). -+ */ -+ -+struct DMA_Chan_s -+{ -+ u32 dmac ; // Control. -+ u32 dmas ; // Status. -+ u32 dmasm ; // Mask. -+ u32 dmadptr ; // Descriptor pointer. -+ u32 dmandptr ; // Next descriptor pointer. -+}; -+ -+typedef struct DMA_Chan_s volatile *DMA_Chan_t ; -+ -+//DMA_Channels use DMACH_count instead -+ -+enum -+{ -+ DMAC_run_b = 0, // -+ DMAC_run_m = 0x00000001, // -+ DMAC_dm_b = 1, // done mask -+ DMAC_dm_m = 0x00000002, // -+ DMAC_mode_b = 2, // -+ DMAC_mode_m = 0x0000000c, // -+ DMAC_mode_auto_v = 0, -+ DMAC_mode_burst_v = 1, -+ DMAC_mode_transfer_v = 2, //usually used -+ DMAC_mode_reserved_v = 3, -+ DMAC_a_b = 4, // -+ DMAC_a_m = 0x00000010, // -+ -+ DMAS_f_b = 0, // finished (sticky) -+ DMAS_f_m = 0x00000001, // -+ DMAS_d_b = 1, // done (sticky) -+ DMAS_d_m = 0x00000002, // -+ DMAS_c_b = 2, // chain (sticky) -+ DMAS_c_m = 0x00000004, // -+ DMAS_e_b = 3, // error (sticky) -+ DMAS_e_m = 0x00000008, // -+ DMAS_h_b = 4, // halt (sticky) -+ DMAS_h_m = 0x00000010, // -+ -+ DMASM_f_b = 0, // finished (1=mask) -+ DMASM_f_m = 0x00000001, // -+ DMASM_d_b = 1, // done (1=mask) -+ DMASM_d_m = 0x00000002, // -+ DMASM_c_b = 2, // chain (1=mask) -+ DMASM_c_m = 0x00000004, // -+ DMASM_e_b = 3, // error (1=mask) -+ DMASM_e_m = 0x00000008, // -+ DMASM_h_b = 4, // halt (1=mask) -+ DMASM_h_m = 0x00000010, // -+} ; -+ -+/* -+ * DMA channel definitions -+ */ -+ -+enum -+{ -+ DMACH_ethRcv = 0, -+ DMACH_ethXmt = 1, -+ DMACH_memToFifo = 2, -+ DMACH_fifoToMem = 3, -+ DMACH_pciToMem = 4, -+ DMACH_memToPci = 5, -+ -+ DMACH_count //must be last -+}; -+ -+ -+typedef struct DMAC_s -+{ -+ struct DMA_Chan_s ch [DMACH_count] ; //use ch[DMACH_] -+} volatile *DMA_t ; -+ -+#endif // __IDT_DMA_H__ -+ -diff -urN linux.old/include/asm-mips/rc32434/dma_v.h linux.dev/include/asm-mips/rc32434/dma_v.h ---- linux.old/include/asm-mips/rc32434/dma_v.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/rc32434/dma_v.h 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,72 @@ -+#ifndef __IDT_DMA_V_H__ -+#define __IDT_DMA_V_H__ -+ -+/******************************************************************************* -+ * -+ * Copyright 2002 Integrated Device Technology, Inc. -+ * All rights reserved. -+ * -+ * DMA register definition. -+ * -+ * File : $Id: dma.h,v 1.3 2002/06/06 18:34:03 astichte Exp $ -+ * -+ * Author : ryan.holmQVist@idt.com -+ * Date : 20011005 -+ * Update : -+ * $Log: dma.h,v $ -+ * Revision 1.3 2002/06/06 18:34:03 astichte -+ * Added XXX_PhysicalAddress and XXX_VirtualAddress -+ * -+ * Revision 1.2 2002/06/05 18:30:46 astichte -+ * Removed IDTField -+ * -+ * Revision 1.1 2002/05/29 17:33:21 sysarch -+ * jba File moved from vcode/include/idt/acacia -+ * -+ * -+ ******************************************************************************/ -+#include <asm/rc32434/dma.h> -+#include <asm/rc32434/rc32434.h> -+#define DMA_CHAN_OFFSET 0x14 -+#define IS_DMA_USED(X) (((X) & (DMAD_f_m | DMAD_d_m | DMAD_t_m)) != 0) -+#define DMA_COUNT(count) \ -+ ((count) & DMAD_count_m) -+ -+#define DMA_HALT_TIMEOUT 500 -+ -+ -+static inline int rc32434_halt_dma(DMA_Chan_t ch) -+{ -+ int timeout=1; -+ if (local_readl(&ch->dmac) & DMAC_run_m) { -+ local_writel(0, &ch->dmac); -+ for (timeout = DMA_HALT_TIMEOUT; timeout > 0; timeout--) { -+ if (local_readl(&ch->dmas) & DMAS_h_m) { -+ local_writel(0, &ch->dmas); -+ break; -+ } -+ } -+ } -+ -+ return timeout ? 0 : 1; -+} -+ -+static inline void rc32434_start_dma(DMA_Chan_t ch, u32 dma_addr) -+{ -+ local_writel(0, &ch->dmandptr); -+ local_writel(dma_addr, &ch->dmadptr); -+} -+ -+static inline void rc32434_chain_dma(DMA_Chan_t ch, u32 dma_addr) -+{ -+ local_writel(dma_addr, &ch->dmandptr); -+} -+ -+#endif // __IDT_DMA_V_H__ -+ -+ -+ -+ -+ -+ -+ -diff -urN linux.old/include/asm-mips/rc32434/eth.h linux.dev/include/asm-mips/rc32434/eth.h ---- linux.old/include/asm-mips/rc32434/eth.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/rc32434/eth.h 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,320 @@ -+#ifndef __IDT_ETH_H__ -+#define __IDT_ETH_H__ -+ -+/******************************************************************************* -+ * -+ * Copyright 2002 Integrated Device Technology, Inc. -+ * All rights reserved. -+ * -+ * Ethernet register definition. -+ * -+ * File : $Id: eth.h,v 1.3 2002/06/06 18:34:04 astichte Exp $ -+ * -+ * Author : Allen.Stichter@idt.com -+ * Date : 20020605 -+ * Update : -+ * $Log: eth.h,v $ -+ * Revision 1.3 2002/06/06 18:34:04 astichte -+ * Added XXX_PhysicalAddress and XXX_VirtualAddress -+ * -+ * Revision 1.2 2002/06/05 18:19:46 astichte -+ * Added -+ * -+ * Revision 1.1 2002/05/29 17:33:22 sysarch -+ * jba File moved from vcode/include/idt/acacia -+ * -+ ******************************************************************************/ -+ -+enum -+{ -+ ETH0_PhysicalAddress = 0x18060000, -+ ETH_PhysicalAddress = ETH0_PhysicalAddress, // Default -+ -+ ETH0_VirtualAddress = 0xb8060000, -+ ETH_VirtualAddress = ETH0_VirtualAddress, // Default -+} ; -+ -+typedef struct -+{ -+ u32 ethintfc ; -+ u32 ethfifott ; -+ u32 etharc ; -+ u32 ethhash0 ; -+ u32 ethhash1 ; -+ u32 ethu0 [4] ; // Reserved. -+ u32 ethpfs ; -+ u32 ethmcp ; -+ u32 eth_u1 [10] ; // Reserved. -+ u32 ethspare ; -+ u32 eth_u2 [42] ; // Reserved. -+ u32 ethsal0 ; -+ u32 ethsah0 ; -+ u32 ethsal1 ; -+ u32 ethsah1 ; -+ u32 ethsal2 ; -+ u32 ethsah2 ; -+ u32 ethsal3 ; -+ u32 ethsah3 ; -+ u32 ethrbc ; -+ u32 ethrpc ; -+ u32 ethrupc ; -+ u32 ethrfc ; -+ u32 ethtbc ; -+ u32 ethgpf ; -+ u32 eth_u9 [50] ; // Reserved. -+ u32 ethmac1 ; -+ u32 ethmac2 ; -+ u32 ethipgt ; -+ u32 ethipgr ; -+ u32 ethclrt ; -+ u32 ethmaxf ; -+ u32 eth_u10 ; // Reserved. -+ u32 ethmtest ; -+ u32 miimcfg ; -+ u32 miimcmd ; -+ u32 miimaddr ; -+ u32 miimwtd ; -+ u32 miimrdd ; -+ u32 miimind ; -+ u32 eth_u11 ; // Reserved. -+ u32 eth_u12 ; // Reserved. -+ u32 ethcfsa0 ; -+ u32 ethcfsa1 ; -+ u32 ethcfsa2 ; -+} volatile *ETH_t; -+ -+enum -+{ -+ ETHINTFC_en_b = 0, -+ ETHINTFC_en_m = 0x00000001, -+ ETHINTFC_its_b = 1, -+ ETHINTFC_its_m = 0x00000002, -+ ETHINTFC_rip_b = 2, -+ ETHINTFC_rip_m = 0x00000004, -+ ETHINTFC_jam_b = 3, -+ ETHINTFC_jam_m = 0x00000008, -+ ETHINTFC_ovr_b = 4, -+ ETHINTFC_ovr_m = 0x00000010, -+ ETHINTFC_und_b = 5, -+ ETHINTFC_und_m = 0x00000020, -+ ETHINTFC_iom_b = 6, -+ ETHINTFC_iom_m = 0x000000c0, -+ -+ ETHFIFOTT_tth_b = 0, -+ ETHFIFOTT_tth_m = 0x0000007f, -+ -+ ETHARC_pro_b = 0, -+ ETHARC_pro_m = 0x00000001, -+ ETHARC_am_b = 1, -+ ETHARC_am_m = 0x00000002, -+ ETHARC_afm_b = 2, -+ ETHARC_afm_m = 0x00000004, -+ ETHARC_ab_b = 3, -+ ETHARC_ab_m = 0x00000008, -+ -+ ETHSAL_byte5_b = 0, -+ ETHSAL_byte5_m = 0x000000ff, -+ ETHSAL_byte4_b = 8, -+ ETHSAL_byte4_m = 0x0000ff00, -+ ETHSAL_byte3_b = 16, -+ ETHSAL_byte3_m = 0x00ff0000, -+ ETHSAL_byte2_b = 24, -+ ETHSAL_byte2_m = 0xff000000, -+ -+ ETHSAH_byte1_b = 0, -+ ETHSAH_byte1_m = 0x000000ff, -+ ETHSAH_byte0_b = 8, -+ ETHSAH_byte0_m = 0x0000ff00, -+ -+ ETHGPF_ptv_b = 0, -+ ETHGPF_ptv_m = 0x0000ffff, -+ -+ ETHPFS_pfd_b = 0, -+ ETHPFS_pfd_m = 0x00000001, -+ -+ ETHCFSA0_cfsa4_b = 0, -+ ETHCFSA0_cfsa4_m = 0x000000ff, -+ ETHCFSA0_cfsa5_b = 8, -+ ETHCFSA0_cfsa5_m = 0x0000ff00, -+ -+ ETHCFSA1_cfsa2_b = 0, -+ ETHCFSA1_cfsa2_m = 0x000000ff, -+ ETHCFSA1_cfsa3_b = 8, -+ ETHCFSA1_cfsa3_m = 0x0000ff00, -+ -+ ETHCFSA2_cfsa0_b = 0, -+ ETHCFSA2_cfsa0_m = 0x000000ff, -+ ETHCFSA2_cfsa1_b = 8, -+ ETHCFSA2_cfsa1_m = 0x0000ff00, -+ -+ ETHMAC1_re_b = 0, -+ ETHMAC1_re_m = 0x00000001, -+ ETHMAC1_paf_b = 1, -+ ETHMAC1_paf_m = 0x00000002, -+ ETHMAC1_rfc_b = 2, -+ ETHMAC1_rfc_m = 0x00000004, -+ ETHMAC1_tfc_b = 3, -+ ETHMAC1_tfc_m = 0x00000008, -+ ETHMAC1_lb_b = 4, -+ ETHMAC1_lb_m = 0x00000010, -+ ETHMAC1_mr_b = 31, -+ ETHMAC1_mr_m = 0x80000000, -+ -+ ETHMAC2_fd_b = 0, -+ ETHMAC2_fd_m = 0x00000001, -+ ETHMAC2_flc_b = 1, -+ ETHMAC2_flc_m = 0x00000002, -+ ETHMAC2_hfe_b = 2, -+ ETHMAC2_hfe_m = 0x00000004, -+ ETHMAC2_dc_b = 3, -+ ETHMAC2_dc_m = 0x00000008, -+ ETHMAC2_cen_b = 4, -+ ETHMAC2_cen_m = 0x00000010, -+ ETHMAC2_pe_b = 5, -+ ETHMAC2_pe_m = 0x00000020, -+ ETHMAC2_vpe_b = 6, -+ ETHMAC2_vpe_m = 0x00000040, -+ ETHMAC2_ape_b = 7, -+ ETHMAC2_ape_m = 0x00000080, -+ ETHMAC2_ppe_b = 8, -+ ETHMAC2_ppe_m = 0x00000100, -+ ETHMAC2_lpe_b = 9, -+ ETHMAC2_lpe_m = 0x00000200, -+ ETHMAC2_nb_b = 12, -+ ETHMAC2_nb_m = 0x00001000, -+ ETHMAC2_bp_b = 13, -+ ETHMAC2_bp_m = 0x00002000, -+ ETHMAC2_ed_b = 14, -+ ETHMAC2_ed_m = 0x00004000, -+ -+ ETHIPGT_ipgt_b = 0, -+ ETHIPGT_ipgt_m = 0x0000007f, -+ -+ ETHIPGR_ipgr2_b = 0, -+ ETHIPGR_ipgr2_m = 0x0000007f, -+ ETHIPGR_ipgr1_b = 8, -+ ETHIPGR_ipgr1_m = 0x00007f00, -+ -+ ETHCLRT_maxret_b = 0, -+ ETHCLRT_maxret_m = 0x0000000f, -+ ETHCLRT_colwin_b = 8, -+ ETHCLRT_colwin_m = 0x00003f00, -+ -+ ETHMAXF_maxf_b = 0, -+ ETHMAXF_maxf_m = 0x0000ffff, -+ -+ ETHMTEST_tb_b = 2, -+ ETHMTEST_tb_m = 0x00000004, -+ -+ ETHMCP_div_b = 0, -+ ETHMCP_div_m = 0x000000ff, -+ -+ MIIMCFG_rsv_b = 0, -+ MIIMCFG_rsv_m = 0x0000000c, -+ -+ MIIMCMD_rd_b = 0, -+ MIIMCMD_rd_m = 0x00000001, -+ MIIMCMD_scn_b = 1, -+ MIIMCMD_scn_m = 0x00000002, -+ -+ MIIMADDR_regaddr_b = 0, -+ MIIMADDR_regaddr_m = 0x0000001f, -+ MIIMADDR_phyaddr_b = 8, -+ MIIMADDR_phyaddr_m = 0x00001f00, -+ -+ MIIMWTD_wdata_b = 0, -+ MIIMWTD_wdata_m = 0x0000ffff, -+ -+ MIIMRDD_rdata_b = 0, -+ MIIMRDD_rdata_m = 0x0000ffff, -+ -+ MIIMIND_bsy_b = 0, -+ MIIMIND_bsy_m = 0x00000001, -+ MIIMIND_scn_b = 1, -+ MIIMIND_scn_m = 0x00000002, -+ MIIMIND_nv_b = 2, -+ MIIMIND_nv_m = 0x00000004, -+ -+} ; -+ -+/* -+ * Values for the DEVCS field of the Ethernet DMA Rx and Tx descriptors. -+ */ -+enum -+{ -+ ETHRX_fd_b = 0, -+ ETHRX_fd_m = 0x00000001, -+ ETHRX_ld_b = 1, -+ ETHRX_ld_m = 0x00000002, -+ ETHRX_rok_b = 2, -+ ETHRX_rok_m = 0x00000004, -+ ETHRX_fm_b = 3, -+ ETHRX_fm_m = 0x00000008, -+ ETHRX_mp_b = 4, -+ ETHRX_mp_m = 0x00000010, -+ ETHRX_bp_b = 5, -+ ETHRX_bp_m = 0x00000020, -+ ETHRX_vlt_b = 6, -+ ETHRX_vlt_m = 0x00000040, -+ ETHRX_cf_b = 7, -+ ETHRX_cf_m = 0x00000080, -+ ETHRX_ovr_b = 8, -+ ETHRX_ovr_m = 0x00000100, -+ ETHRX_crc_b = 9, -+ ETHRX_crc_m = 0x00000200, -+ ETHRX_cv_b = 10, -+ ETHRX_cv_m = 0x00000400, -+ ETHRX_db_b = 11, -+ ETHRX_db_m = 0x00000800, -+ ETHRX_le_b = 12, -+ ETHRX_le_m = 0x00001000, -+ ETHRX_lor_b = 13, -+ ETHRX_lor_m = 0x00002000, -+ ETHRX_ces_b = 14, -+ ETHRX_ces_m = 0x00004000, -+ ETHRX_length_b = 16, -+ ETHRX_length_m = 0xffff0000, -+ -+ ETHTX_fd_b = 0, -+ ETHTX_fd_m = 0x00000001, -+ ETHTX_ld_b = 1, -+ ETHTX_ld_m = 0x00000002, -+ ETHTX_oen_b = 2, -+ ETHTX_oen_m = 0x00000004, -+ ETHTX_pen_b = 3, -+ ETHTX_pen_m = 0x00000008, -+ ETHTX_cen_b = 4, -+ ETHTX_cen_m = 0x00000010, -+ ETHTX_hen_b = 5, -+ ETHTX_hen_m = 0x00000020, -+ ETHTX_tok_b = 6, -+ ETHTX_tok_m = 0x00000040, -+ ETHTX_mp_b = 7, -+ ETHTX_mp_m = 0x00000080, -+ ETHTX_bp_b = 8, -+ ETHTX_bp_m = 0x00000100, -+ ETHTX_und_b = 9, -+ ETHTX_und_m = 0x00000200, -+ ETHTX_of_b = 10, -+ ETHTX_of_m = 0x00000400, -+ ETHTX_ed_b = 11, -+ ETHTX_ed_m = 0x00000800, -+ ETHTX_ec_b = 12, -+ ETHTX_ec_m = 0x00001000, -+ ETHTX_lc_b = 13, -+ ETHTX_lc_m = 0x00002000, -+ ETHTX_td_b = 14, -+ ETHTX_td_m = 0x00004000, -+ ETHTX_crc_b = 15, -+ ETHTX_crc_m = 0x00008000, -+ ETHTX_le_b = 16, -+ ETHTX_le_m = 0x00010000, -+ ETHTX_cc_b = 17, -+ ETHTX_cc_m = 0x001E0000, -+} ; -+ -+#endif // __IDT_ETH_H__ -+ -+ -+ -+ -diff -urN linux.old/include/asm-mips/rc32434/eth_v.h linux.dev/include/asm-mips/rc32434/eth_v.h ---- linux.old/include/asm-mips/rc32434/eth_v.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/rc32434/eth_v.h 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,63 @@ -+#ifndef __IDT_ETH_V_H__ -+#define __IDT_ETH_V_H__ -+ -+/******************************************************************************* -+ * -+ * Copyright 2002 Integrated Device Technology, Inc. -+ * All rights reserved. -+ * -+ * Ethernet register definition. -+ * -+ * File : $Id: eth.h,v 1.3 2002/06/06 18:34:04 astichte Exp $ -+ * -+ * Author : Allen.Stichter@idt.com -+ * Date : 20020605 -+ * Update : -+ * $Log: eth.h,v $ -+ * Revision 1.3 2002/06/06 18:34:04 astichte -+ * Added XXX_PhysicalAddress and XXX_VirtualAddress -+ * -+ * Revision 1.2 2002/06/05 18:19:46 astichte -+ * Added -+ * -+ * Revision 1.1 2002/05/29 17:33:22 sysarch -+ * jba File moved from vcode/include/idt/acacia -+ * -+ ******************************************************************************/ -+ -+#include <asm/rc32434/eth.h> -+ -+#define IS_TX_TOK(X) (((X) & (1<<ETHTX_tok_b)) >> ETHTX_tok_b ) /* Transmit Okay */ -+#define IS_TX_MP(X) (((X) & (1<<ETHTX_mp_b)) >> ETHTX_mp_b ) /* Multicast */ -+#define IS_TX_BP(X) (((X) & (1<<ETHTX_bp_b)) >> ETHTX_bp_b ) /* Broadcast */ -+#define IS_TX_UND_ERR(X) (((X) & (1<<ETHTX_und_b)) >> ETHTX_und_b ) /* Transmit FIFO Underflow */ -+#define IS_TX_OF_ERR(X) (((X) & (1<<ETHTX_of_b)) >> ETHTX_of_b ) /* Oversized frame */ -+#define IS_TX_ED_ERR(X) (((X) & (1<<ETHTX_ed_b)) >> ETHTX_ed_b ) /* Excessive deferral */ -+#define IS_TX_EC_ERR(X) (((X) & (1<<ETHTX_ec_b)) >> ETHTX_ec_b) /* Excessive collisions */ -+#define IS_TX_LC_ERR(X) (((X) & (1<<ETHTX_lc_b)) >> ETHTX_lc_b ) /* Late Collision */ -+#define IS_TX_TD_ERR(X) (((X) & (1<<ETHTX_td_b)) >> ETHTX_td_b ) /* Transmit deferred*/ -+#define IS_TX_CRC_ERR(X) (((X) & (1<<ETHTX_crc_b)) >> ETHTX_crc_b ) /* CRC Error */ -+#define IS_TX_LE_ERR(X) (((X) & (1<<ETHTX_le_b)) >> ETHTX_le_b ) /* Length Error */ -+ -+#define TX_COLLISION_COUNT(X) (((X) & ETHTX_cc_m)>>ETHTX_cc_b) /* Collision Count */ -+ -+#define IS_RCV_ROK(X) (((X) & (1<<ETHRX_rok_b)) >> ETHRX_rok_b) /* Receive Okay */ -+#define IS_RCV_FM(X) (((X) & (1<<ETHRX_fm_b)) >> ETHRX_fm_b) /* Is Filter Match */ -+#define IS_RCV_MP(X) (((X) & (1<<ETHRX_mp_b)) >> ETHRX_mp_b) /* Is it MP */ -+#define IS_RCV_BP(X) (((X) & (1<<ETHRX_bp_b)) >> ETHRX_bp_b) /* Is it BP */ -+#define IS_RCV_VLT(X) (((X) & (1<<ETHRX_vlt_b)) >> ETHRX_vlt_b) /* VLAN Tag Detect */ -+#define IS_RCV_CF(X) (((X) & (1<<ETHRX_cf_b)) >> ETHRX_cf_b) /* Control Frame */ -+#define IS_RCV_OVR_ERR(X) (((X) & (1<<ETHRX_ovr_b)) >> ETHRX_ovr_b) /* Receive Overflow */ -+#define IS_RCV_CRC_ERR(X) (((X) & (1<<ETHRX_crc_b)) >> ETHRX_crc_b) /* CRC Error */ -+#define IS_RCV_CV_ERR(X) (((X) & (1<<ETHRX_cv_b)) >> ETHRX_cv_b) /* Code Violation */ -+#define IS_RCV_DB_ERR(X) (((X) & (1<<ETHRX_db_b)) >> ETHRX_db_b) /* Dribble Bits */ -+#define IS_RCV_LE_ERR(X) (((X) & (1<<ETHRX_le_b)) >> ETHRX_le_b) /* Length error */ -+#define IS_RCV_LOR_ERR(X) (((X) & (1<<ETHRX_lor_b)) >> ETHRX_lor_b) /* Length Out of Range */ -+#define IS_RCV_CES_ERR(X) (((X) & (1<<ETHRX_ces_b)) >> ETHRX_ces_b) /* Preamble error */ -+#define RCVPKT_LENGTH(X) (((X) & ETHRX_length_m) >> ETHRX_length_b) /* Length of the received packet */ -+#endif // __IDT_ETH_V_H__ -+ -+ -+ -+ -+ -diff -urN linux.old/include/asm-mips/rc32434/gpio.h linux.dev/include/asm-mips/rc32434/gpio.h ---- linux.old/include/asm-mips/rc32434/gpio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/rc32434/gpio.h 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,181 @@ -+#ifndef __IDT_GPIO_H__ -+#define __IDT_GPIO_H__ -+ -+/******************************************************************************* -+ * -+ * Copyright 2002 Integrated Device Technology, Inc. -+ * All rights reserved. -+ * -+ * GPIO register definition. -+ * -+ * File : $Id: gpio.h,v 1.2 2002/06/06 18:34:04 astichte Exp $ -+ * -+ * Author : ryan.holmQVist@idt.com -+ * Date : 20011005 -+ * Update : -+ * $Log: gpio.h,v $ -+ * Revision 1.2 2002/06/06 18:34:04 astichte -+ * Added XXX_PhysicalAddress and XXX_VirtualAddress -+ * -+ * Revision 1.1 2002/05/29 17:33:22 sysarch -+ * jba File moved from vcode/include/idt/acacia -+ * -+ * -+ ******************************************************************************/ -+ -+enum -+{ -+ GPIO0_PhysicalAddress = 0x18050000, -+ GPIO_PhysicalAddress = GPIO0_PhysicalAddress, // Default -+ -+ GPIO0_VirtualAddress = 0xb8050000, -+ GPIO_VirtualAddress = GPIO0_VirtualAddress, // Default -+} ; -+ -+typedef struct -+{ -+ u32 gpiofunc; /* GPIO Function Register -+ * gpiofunc[x]==0 bit = gpio -+ * func[x]==1 bit = altfunc -+ */ -+ u32 gpiocfg; /* GPIO Configuration Register -+ * gpiocfg[x]==0 bit = input -+ * gpiocfg[x]==1 bit = output -+ */ -+ u32 gpiod; /* GPIO Data Register -+ * gpiod[x] read/write gpio pinX status -+ */ -+ u32 gpioilevel; /* GPIO Interrupt Status Register -+ * interrupt level (see gpioistat) -+ */ -+ u32 gpioistat; /* Gpio Interrupt Status Register -+ * istat[x] = (gpiod[x] == level[x]) -+ * cleared in ISR (STICKY bits) -+ */ -+ u32 gpionmien; /* GPIO Non-maskable Interrupt Enable Register */ -+} volatile * GPIO_t ; -+ -+typedef enum -+{ -+ GPIO_gpio_v = 0, // gpiofunc use pin as GPIO. -+ GPIO_alt_v = 1, // gpiofunc use pin as alt. -+ GPIO_input_v = 0, // gpiocfg use pin as input. -+ GPIO_output_v = 1, // gpiocfg use pin as output. -+ GPIO_pin0_b = 0, -+ GPIO_pin0_m = 0x00000001, -+ GPIO_pin1_b = 1, -+ GPIO_pin1_m = 0x00000002, -+ GPIO_pin2_b = 2, -+ GPIO_pin2_m = 0x00000004, -+ GPIO_pin3_b = 3, -+ GPIO_pin3_m = 0x00000008, -+ GPIO_pin4_b = 4, -+ GPIO_pin4_m = 0x00000010, -+ GPIO_pin5_b = 5, -+ GPIO_pin5_m = 0x00000020, -+ GPIO_pin6_b = 6, -+ GPIO_pin6_m = 0x00000040, -+ GPIO_pin7_b = 7, -+ GPIO_pin7_m = 0x00000080, -+ GPIO_pin8_b = 8, -+ GPIO_pin8_m = 0x00000100, -+ GPIO_pin9_b = 9, -+ GPIO_pin9_m = 0x00000200, -+ GPIO_pin10_b = 10, -+ GPIO_pin10_m = 0x00000400, -+ GPIO_pin11_b = 11, -+ GPIO_pin11_m = 0x00000800, -+ GPIO_pin12_b = 12, -+ GPIO_pin12_m = 0x00001000, -+ GPIO_pin13_b = 13, -+ GPIO_pin13_m = 0x00002000, -+ GPIO_pin14_b = 14, -+ GPIO_pin14_m = 0x00004000, -+ GPIO_pin15_b = 15, -+ GPIO_pin15_m = 0x00008000, -+ GPIO_pin16_b = 16, -+ GPIO_pin16_m = 0x00010000, -+ GPIO_pin17_b = 17, -+ GPIO_pin17_m = 0x00020000, -+ GPIO_pin18_b = 18, -+ GPIO_pin18_m = 0x00040000, -+ GPIO_pin19_b = 19, -+ GPIO_pin19_m = 0x00080000, -+ GPIO_pin20_b = 20, -+ GPIO_pin20_m = 0x00100000, -+ GPIO_pin21_b = 21, -+ GPIO_pin21_m = 0x00200000, -+ GPIO_pin22_b = 22, -+ GPIO_pin22_m = 0x00400000, -+ GPIO_pin23_b = 23, -+ GPIO_pin23_m = 0x00800000, -+ GPIO_pin24_b = 24, -+ GPIO_pin24_m = 0x01000000, -+ GPIO_pin25_b = 25, -+ GPIO_pin25_m = 0x02000000, -+ GPIO_pin26_b = 26, -+ GPIO_pin26_m = 0x04000000, -+ GPIO_pin27_b = 27, -+ GPIO_pin27_m = 0x08000000, -+ GPIO_pin28_b = 28, -+ GPIO_pin28_m = 0x10000000, -+ GPIO_pin29_b = 29, -+ GPIO_pin29_m = 0x20000000, -+ GPIO_pin30_b = 30, -+ GPIO_pin30_m = 0x40000000, -+ GPIO_pin31_b = 31, -+ GPIO_pin31_m = 0x80000000, -+ -+// Alternate function pins. Corrsponding gpiofunc bit set to GPIO_alt_v. -+ -+ GPIO_u0sout_b = GPIO_pin0_b, // UART 0 serial out. -+ GPIO_u0sout_m = GPIO_pin0_m, -+ GPIO_u0sout_cfg_v = GPIO_output_v, -+ GPIO_u0sinp_b = GPIO_pin1_b, // UART 0 serial in. -+ GPIO_u0sinp_m = GPIO_pin1_m, -+ GPIO_u0sinp_cfg_v = GPIO_input_v, -+ GPIO_u0rtsn_b = GPIO_pin2_b, // UART 0 req. to send. -+ GPIO_u0rtsn_m = GPIO_pin2_m, -+ GPIO_u0rtsn_cfg_v = GPIO_output_v, -+ GPIO_u0ctsn_b = GPIO_pin3_b, // UART 0 clear to send. -+ GPIO_u0ctsn_m = GPIO_pin3_m, -+ GPIO_u0ctsn_cfg_v = GPIO_input_v, -+ GPIO_maddr22_b = GPIO_pin4_b, // M&P bus bit 22. -+ GPIO_maddr22_m = GPIO_pin4_m, -+ GPIO_maddr22_cfg_v = GPIO_output_v, -+ -+ GPIO_maddr23_b = GPIO_pin5_b, // M&P bus bit 23. -+ GPIO_maddr23_m = GPIO_pin5_m, -+ GPIO_maddr23_cfg_v = GPIO_output_v, -+ -+ GPIO_maddr24_b = GPIO_pin6_b, // M&P bus bit 24. -+ GPIO_maddr24_m = GPIO_pin6_m, -+ GPIO_maddr24_cfg_v = GPIO_output_v, -+ -+ GPIO_maddr25_b = GPIO_pin7_b, // M&P bus bit 25. -+ GPIO_maddr25_m = GPIO_pin7_m, -+ GPIO_maddr25_cfg_v = GPIO_output_v, -+ -+ GPIO_cpu_b = GPIO_pin8_b, // M&P bus bit 25. -+ GPIO_cpu_m = GPIO_pin8_m, -+ GPIO_cpu_cfg_v = GPIO_output_v, -+ GPIO_afspare6_b = GPIO_pin9_b, // reserved. -+ GPIO_afspare6_m = GPIO_pin9_m, -+ GPIO_afspare6_cfg_v = GPIO_input_v, -+ GPIO_afspare4_b = GPIO_pin10_b, // reserved. -+ GPIO_afspare4_m = GPIO_pin10_m, -+ GPIO_afspare4_cfg_v = GPIO_input_v, -+ GPIO_afspare3_b = GPIO_pin11_b, // reserved. -+ GPIO_afspare3_m = GPIO_pin11_m, -+ GPIO_afspare3_cfg_v = GPIO_input_v, -+ GPIO_afspare2_b = GPIO_pin12_b, // reserved. -+ GPIO_afspare2_m = GPIO_pin12_m, -+ GPIO_afspare2_cfg_v = GPIO_input_v, -+ GPIO_pcimuintn_b = GPIO_pin13_b, // PCI messaging int. -+ GPIO_pcimuintn_m = GPIO_pin13_m, -+ GPIO_pcimuintn_cfg_v = GPIO_output_v, -+ -+} GPIO_DEFS_t; -+ -+#endif // __IDT_GPIO_H__ -+ -diff -urN linux.old/include/asm-mips/rc32434/irq.h linux.dev/include/asm-mips/rc32434/irq.h ---- linux.old/include/asm-mips/rc32434/irq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/rc32434/irq.h 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,8 @@ -+#ifndef __ASM_MACH_MIPS_IRQ_H -+#define __ASM_MACH_MIPS_IRQ_H -+ -+#include <linux/autoconf.h> -+ -+#define NR_IRQS 256 -+ -+#endif /* __ASM_MACH_MIPS_IRQ_H */ -diff -urN linux.old/include/asm-mips/rc32434/pci.h linux.dev/include/asm-mips/rc32434/pci.h ---- linux.old/include/asm-mips/rc32434/pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/rc32434/pci.h 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,692 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * PCI register definitio -+ * -+ * 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 -+ * -+ * -+ * -+ ************************************************************************** -+ */ -+ -+#ifndef __IDT_PCI_H__ -+#define __IDT_PCI_H__ -+ -+enum -+{ -+ PCI0_PhysicalAddress = 0x18080000, -+ PCI_PhysicalAddress = PCI0_PhysicalAddress, -+ -+ PCI0_VirtualAddress = 0xB8080000, -+ PCI_VirtualAddress = PCI0_VirtualAddress, -+} ; -+ -+enum -+{ -+ PCI_LbaCount = 4, // Local base addresses. -+} ; -+ -+typedef struct -+{ -+ u32 a ; // Address. -+ u32 c ; // Control. -+ u32 m ; // mapping. -+} PCI_Map_s ; -+ -+typedef struct -+{ -+ u32 pcic ; -+ u32 pcis ; -+ u32 pcism ; -+ u32 pcicfga ; -+ u32 pcicfgd ; -+ PCI_Map_s pcilba [PCI_LbaCount] ; -+ u32 pcidac ; -+ u32 pcidas ; -+ u32 pcidasm ; -+ u32 pcidad ; -+ u32 pcidma8c ; -+ u32 pcidma9c ; -+ u32 pcitc ; -+} volatile *PCI_t ; -+ -+// PCI messaging unit. -+enum -+{ -+ PCIM_Count = 2, -+} ; -+typedef struct -+{ -+ u32 pciim [PCIM_Count] ; -+ u32 pciom [PCIM_Count] ; -+ u32 pciid ; -+ u32 pciiic ; -+ u32 pciiim ; -+ u32 pciiod ; -+ u32 pciioic ; -+ u32 pciioim ; -+} volatile *PCIM_t ; -+ -+/******************************************************************************* -+ * -+ * PCI Control Register -+ * -+ ******************************************************************************/ -+enum -+{ -+ PCIC_en_b = 0, -+ PCIC_en_m = 0x00000001, -+ PCIC_tnr_b = 1, -+ PCIC_tnr_m = 0x00000002, -+ PCIC_sce_b = 2, -+ PCIC_sce_m = 0x00000004, -+ PCIC_ien_b = 3, -+ PCIC_ien_m = 0x00000008, -+ PCIC_aaa_b = 4, -+ PCIC_aaa_m = 0x00000010, -+ PCIC_eap_b = 5, -+ PCIC_eap_m = 0x00000020, -+ PCIC_pcim_b = 6, -+ PCIC_pcim_m = 0x000001c0, -+ PCIC_pcim_disabled_v = 0, -+ PCIC_pcim_tnr_v = 1, // Satellite - target not ready -+ PCIC_pcim_suspend_v = 2, // Satellite - suspended CPU. -+ PCIC_pcim_extern_v = 3, // Host - external arbiter. -+ PCIC_pcim_fixed_v = 4, // Host - fixed priority arb. -+ PCIC_pcim_roundrobin_v = 5, // Host - round robin priority. -+ PCIC_pcim_reserved6_v = 6, -+ PCIC_pcim_reserved7_v = 7, -+ PCIC_igm_b = 9, -+ PCIC_igm_m = 0x00000200, -+} ; -+ -+/******************************************************************************* -+ * -+ * PCI Status Register -+ * -+ ******************************************************************************/ -+enum { -+ PCIS_eed_b = 0, -+ PCIS_eed_m = 0x00000001, -+ PCIS_wr_b = 1, -+ PCIS_wr_m = 0x00000002, -+ PCIS_nmi_b = 2, -+ PCIS_nmi_m = 0x00000004, -+ PCIS_ii_b = 3, -+ PCIS_ii_m = 0x00000008, -+ PCIS_cwe_b = 4, -+ PCIS_cwe_m = 0x00000010, -+ PCIS_cre_b = 5, -+ PCIS_cre_m = 0x00000020, -+ PCIS_mdpe_b = 6, -+ PCIS_mdpe_m = 0x00000040, -+ PCIS_sta_b = 7, -+ PCIS_sta_m = 0x00000080, -+ PCIS_rta_b = 8, -+ PCIS_rta_m = 0x00000100, -+ PCIS_rma_b = 9, -+ PCIS_rma_m = 0x00000200, -+ PCIS_sse_b = 10, -+ PCIS_sse_m = 0x00000400, -+ PCIS_ose_b = 11, -+ PCIS_ose_m = 0x00000800, -+ PCIS_pe_b = 12, -+ PCIS_pe_m = 0x00001000, -+ PCIS_tae_b = 13, -+ PCIS_tae_m = 0x00002000, -+ PCIS_rle_b = 14, -+ PCIS_rle_m = 0x00004000, -+ PCIS_bme_b = 15, -+ PCIS_bme_m = 0x00008000, -+ PCIS_prd_b = 16, -+ PCIS_prd_m = 0x00010000, -+ PCIS_rip_b = 17, -+ PCIS_rip_m = 0x00020000, -+} ; -+ -+/******************************************************************************* -+ * -+ * PCI Status Mask Register -+ * -+ ******************************************************************************/ -+enum { -+ PCISM_eed_b = 0, -+ PCISM_eed_m = 0x00000001, -+ PCISM_wr_b = 1, -+ PCISM_wr_m = 0x00000002, -+ PCISM_nmi_b = 2, -+ PCISM_nmi_m = 0x00000004, -+ PCISM_ii_b = 3, -+ PCISM_ii_m = 0x00000008, -+ PCISM_cwe_b = 4, -+ PCISM_cwe_m = 0x00000010, -+ PCISM_cre_b = 5, -+ PCISM_cre_m = 0x00000020, -+ PCISM_mdpe_b = 6, -+ PCISM_mdpe_m = 0x00000040, -+ PCISM_sta_b = 7, -+ PCISM_sta_m = 0x00000080, -+ PCISM_rta_b = 8, -+ PCISM_rta_m = 0x00000100, -+ PCISM_rma_b = 9, -+ PCISM_rma_m = 0x00000200, -+ PCISM_sse_b = 10, -+ PCISM_sse_m = 0x00000400, -+ PCISM_ose_b = 11, -+ PCISM_ose_m = 0x00000800, -+ PCISM_pe_b = 12, -+ PCISM_pe_m = 0x00001000, -+ PCISM_tae_b = 13, -+ PCISM_tae_m = 0x00002000, -+ PCISM_rle_b = 14, -+ PCISM_rle_m = 0x00004000, -+ PCISM_bme_b = 15, -+ PCISM_bme_m = 0x00008000, -+ PCISM_prd_b = 16, -+ PCISM_prd_m = 0x00010000, -+ PCISM_rip_b = 17, -+ PCISM_rip_m = 0x00020000, -+} ; -+ -+/******************************************************************************* -+ * -+ * PCI Configuration Address Register -+ * -+ ******************************************************************************/ -+enum { -+ PCICFGA_reg_b = 2, -+ PCICFGA_reg_m = 0x000000fc, -+ PCICFGA_reg_id_v = 0x00>>2, //use PCFGID_ -+ PCICFGA_reg_04_v = 0x04>>2, //use PCFG04_ -+ PCICFGA_reg_08_v = 0x08>>2, //use PCFG08_ -+ PCICFGA_reg_0C_v = 0x0C>>2, //use PCFG0C_ -+ PCICFGA_reg_pba0_v = 0x10>>2, //use PCIPBA_ -+ PCICFGA_reg_pba1_v = 0x14>>2, //use PCIPBA_ -+ PCICFGA_reg_pba2_v = 0x18>>2, //use PCIPBA_ -+ PCICFGA_reg_pba3_v = 0x1c>>2, //use PCIPBA_ -+ PCICFGA_reg_subsystem_v = 0x2c>>2, //use PCFGSS_ -+ PCICFGA_reg_3C_v = 0x3C>>2, //use PCFG3C_ -+ PCICFGA_reg_pba0c_v = 0x44>>2, //use PCIPBAC_ -+ PCICFGA_reg_pba0m_v = 0x48>>2, -+ PCICFGA_reg_pba1c_v = 0x4c>>2, //use PCIPBAC_ -+ PCICFGA_reg_pba1m_v = 0x50>>2, -+ PCICFGA_reg_pba2c_v = 0x54>>2, //use PCIPBAC_ -+ PCICFGA_reg_pba2m_v = 0x58>>2, -+ PCICFGA_reg_pba3c_v = 0x5c>>2, //use PCIPBAC_ -+ PCICFGA_reg_pba3m_v = 0x60>>2, -+ PCICFGA_reg_pmgt_v = 0x64>>2, -+ PCICFGA_func_b = 8, -+ PCICFGA_func_m = 0x00000700, -+ PCICFGA_dev_b = 11, -+ PCICFGA_dev_m = 0x0000f800, -+ PCICFGA_dev_internal_v = 0, -+ PCICFGA_bus_b = 16, -+ PCICFGA_bus_m = 0x00ff0000, -+ PCICFGA_bus_type0_v = 0, //local bus -+ PCICFGA_en_b = 31, // read only -+ PCICFGA_en_m = 0x80000000, -+} ; -+ -+enum { -+ PCFGID_vendor_b = 0, -+ PCFGID_vendor_m = 0x0000ffff, -+ PCFGID_vendor_IDT_v = 0x111d, -+ PCFGID_device_b = 16, -+ PCFGID_device_m = 0xffff0000, -+ PCFGID_device_Korinade_v = 0x0214, -+ -+ PCFG04_command_ioena_b = 1, -+ PCFG04_command_ioena_m = 0x00000001, -+ PCFG04_command_memena_b = 2, -+ PCFG04_command_memena_m = 0x00000002, -+ PCFG04_command_bmena_b = 3, -+ PCFG04_command_bmena_m = 0x00000004, -+ PCFG04_command_mwinv_b = 5, -+ PCFG04_command_mwinv_m = 0x00000010, -+ PCFG04_command_parena_b = 7, -+ PCFG04_command_parena_m = 0x00000040, -+ PCFG04_command_serrena_b = 9, -+ PCFG04_command_serrena_m = 0x00000100, -+ PCFG04_command_fastbbena_b = 10, -+ PCFG04_command_fastbbena_m = 0x00000200, -+ PCFG04_status_b = 16, -+ PCFG04_status_m = 0xffff0000, -+ PCFG04_status_66MHz_b = 21, // 66 MHz enable -+ PCFG04_status_66MHz_m = 0x00200000, -+ PCFG04_status_fbb_b = 23, -+ PCFG04_status_fbb_m = 0x00800000, -+ PCFG04_status_mdpe_b = 24, -+ PCFG04_status_mdpe_m = 0x01000000, -+ PCFG04_status_dst_b = 25, -+ PCFG04_status_dst_m = 0x06000000, -+ PCFG04_status_sta_b = 27, -+ PCFG04_status_sta_m = 0x08000000, -+ PCFG04_status_rta_b = 28, -+ PCFG04_status_rta_m = 0x10000000, -+ PCFG04_status_rma_b = 29, -+ PCFG04_status_rma_m = 0x20000000, -+ PCFG04_status_sse_b = 30, -+ PCFG04_status_sse_m = 0x40000000, -+ PCFG04_status_pe_b = 31, -+ PCFG04_status_pe_m = 0x40000000, -+ -+ PCFG08_revId_b = 0, -+ PCFG08_revId_m = 0x000000ff, -+ PCFG08_classCode_b = 0, -+ PCFG08_classCode_m = 0xffffff00, -+ PCFG08_classCode_bridge_v = 06, -+ PCFG08_classCode_proc_v = 0x0b3000, // processor-MIPS -+ PCFG0C_cacheline_b = 0, -+ PCFG0C_cacheline_m = 0x000000ff, -+ PCFG0C_masterLatency_b = 8, -+ PCFG0C_masterLatency_m = 0x0000ff00, -+ PCFG0C_headerType_b = 16, -+ PCFG0C_headerType_m = 0x00ff0000, -+ PCFG0C_bist_b = 24, -+ PCFG0C_bist_m = 0xff000000, -+ -+ PCIPBA_msi_b = 0, -+ PCIPBA_msi_m = 0x00000001, -+ PCIPBA_p_b = 3, -+ PCIPBA_p_m = 0x00000004, -+ PCIPBA_baddr_b = 8, -+ PCIPBA_baddr_m = 0xffffff00, -+ -+ PCFGSS_vendorId_b = 0, -+ PCFGSS_vendorId_m = 0x0000ffff, -+ PCFGSS_id_b = 16, -+ PCFGSS_id_m = 0xffff0000, -+ -+ PCFG3C_interruptLine_b = 0, -+ PCFG3C_interruptLine_m = 0x000000ff, -+ PCFG3C_interruptPin_b = 8, -+ PCFG3C_interruptPin_m = 0x0000ff00, -+ PCFG3C_minGrant_b = 16, -+ PCFG3C_minGrant_m = 0x00ff0000, -+ PCFG3C_maxLat_b = 24, -+ PCFG3C_maxLat_m = 0xff000000, -+ -+ PCIPBAC_msi_b = 0, -+ PCIPBAC_msi_m = 0x00000001, -+ PCIPBAC_p_b = 1, -+ PCIPBAC_p_m = 0x00000002, -+ PCIPBAC_size_b = 2, -+ PCIPBAC_size_m = 0x0000007c, -+ PCIPBAC_sb_b = 7, -+ PCIPBAC_sb_m = 0x00000080, -+ PCIPBAC_pp_b = 8, -+ PCIPBAC_pp_m = 0x00000100, -+ PCIPBAC_mr_b = 9, -+ PCIPBAC_mr_m = 0x00000600, -+ PCIPBAC_mr_read_v =0, //no prefetching -+ PCIPBAC_mr_readLine_v =1, -+ PCIPBAC_mr_readMult_v =2, -+ PCIPBAC_mrl_b = 11, -+ PCIPBAC_mrl_m = 0x00000800, -+ PCIPBAC_mrm_b = 12, -+ PCIPBAC_mrm_m = 0x00001000, -+ PCIPBAC_trp_b = 13, -+ PCIPBAC_trp_m = 0x00002000, -+ -+ PCFG40_trdyTimeout_b = 0, -+ PCFG40_trdyTimeout_m = 0x000000ff, -+ PCFG40_retryLim_b = 8, -+ PCFG40_retryLim_m = 0x0000ff00, -+}; -+ -+/******************************************************************************* -+ * -+ * PCI Local Base Address [0|1|2|3] Register -+ * -+ ******************************************************************************/ -+enum { -+ PCILBA_baddr_b = 0, // In PCI_t -> pcilba [] .a -+ PCILBA_baddr_m = 0xffffff00, -+} ; -+/******************************************************************************* -+ * -+ * PCI Local Base Address Control Register -+ * -+ ******************************************************************************/ -+enum { -+ PCILBAC_msi_b = 0, // In pPci->pcilba[i].c -+ PCILBAC_msi_m = 0x00000001, -+ PCILBAC_msi_mem_v = 0, -+ PCILBAC_msi_io_v = 1, -+ PCILBAC_size_b = 2, // In pPci->pcilba[i].c -+ PCILBAC_size_m = 0x0000007c, -+ PCILBAC_sb_b = 7, // In pPci->pcilba[i].c -+ PCILBAC_sb_m = 0x00000080, -+ PCILBAC_rt_b = 8, // In pPci->pcilba[i].c -+ PCILBAC_rt_m = 0x00000100, -+ PCILBAC_rt_noprefetch_v = 0, // mem read -+ PCILBAC_rt_prefetch_v = 1, // mem readline -+} ; -+ -+/******************************************************************************* -+ * -+ * PCI Local Base Address [0|1|2|3] Mapping Register -+ * -+ ******************************************************************************/ -+enum { -+ PCILBAM_maddr_b = 8, -+ PCILBAM_maddr_m = 0xffffff00, -+} ; -+ -+/******************************************************************************* -+ * -+ * PCI Decoupled Access Control Register -+ * -+ ******************************************************************************/ -+enum { -+ PCIDAC_den_b = 0, -+ PCIDAC_den_m = 0x00000001, -+} ; -+ -+/******************************************************************************* -+ * -+ * PCI Decoupled Access Status Register -+ * -+ ******************************************************************************/ -+enum { -+ PCIDAS_d_b = 0, -+ PCIDAS_d_m = 0x00000001, -+ PCIDAS_b_b = 1, -+ PCIDAS_b_m = 0x00000002, -+ PCIDAS_e_b = 2, -+ PCIDAS_e_m = 0x00000004, -+ PCIDAS_ofe_b = 3, -+ PCIDAS_ofe_m = 0x00000008, -+ PCIDAS_off_b = 4, -+ PCIDAS_off_m = 0x00000010, -+ PCIDAS_ife_b = 5, -+ PCIDAS_ife_m = 0x00000020, -+ PCIDAS_iff_b = 6, -+ PCIDAS_iff_m = 0x00000040, -+} ; -+ -+/******************************************************************************* -+ * -+ * PCI DMA Channel 8 Configuration Register -+ * -+ ******************************************************************************/ -+enum -+{ -+ PCIDMA8C_mbs_b = 0, // Maximum Burst Size. -+ PCIDMA8C_mbs_m = 0x00000fff, // { pcidma8c } -+ PCIDMA8C_our_b = 12, // Optimize Unaligned Burst Reads. -+ PCIDMA8C_our_m = 0x00001000, // { pcidma8c } -+} ; -+ -+/******************************************************************************* -+ * -+ * PCI DMA Channel 9 Configuration Register -+ * -+ ******************************************************************************/ -+enum -+{ -+ PCIDMA9C_mbs_b = 0, // Maximum Burst Size. -+ PCIDMA9C_mbs_m = 0x00000fff, // { pcidma9c } -+} ; -+ -+/******************************************************************************* -+ * -+ * PCI to Memory(DMA Channel 8) AND Memory to PCI DMA(DMA Channel 9)Descriptors -+ * -+ ******************************************************************************/ -+enum { -+ PCIDMAD_pt_b = 22, // in DEVCMD field (descriptor) -+ PCIDMAD_pt_m = 0x00c00000, // preferred transaction field -+ // These are for reads (DMA channel 8) -+ PCIDMAD_devcmd_mr_v = 0, //memory read -+ PCIDMAD_devcmd_mrl_v = 1, //memory read line -+ PCIDMAD_devcmd_mrm_v = 2, //memory read multiple -+ PCIDMAD_devcmd_ior_v = 3, //I/O read -+ // These are for writes (DMA channel 9) -+ PCIDMAD_devcmd_mw_v = 0, //memory write -+ PCIDMAD_devcmd_mwi_v = 1, //memory write invalidate -+ PCIDMAD_devcmd_iow_v = 3, //I/O write -+ -+ // Swap byte field applies to both DMA channel 8 and 9 -+ PCIDMAD_sb_b = 24, // in DEVCMD field (descriptor) -+ PCIDMAD_sb_m = 0x01000000, // swap byte field -+} ; -+ -+ -+/******************************************************************************* -+ * -+ * PCI Target Control Register -+ * -+ ******************************************************************************/ -+enum -+{ -+ PCITC_rtimer_b = 0, // In PCITC_t -> pcitc -+ PCITC_rtimer_m = 0x000000ff, -+ PCITC_dtimer_b = 8, // In PCITC_t -> pcitc -+ PCITC_dtimer_m = 0x0000ff00, -+ PCITC_rdr_b = 18, // In PCITC_t -> pcitc -+ PCITC_rdr_m = 0x00040000, -+ PCITC_ddt_b = 19, // In PCITC_t -> pcitc -+ PCITC_ddt_m = 0x00080000, -+} ; -+/******************************************************************************* -+ * -+ * PCI messaging unit [applies to both inbound and outbound registers ] -+ * -+ ******************************************************************************/ -+enum -+{ -+ PCIM_m0_b = 0, // In PCIM_t -> {pci{iic,iim,ioic,ioim}} -+ PCIM_m0_m = 0x00000001, // inbound or outbound message 0 -+ PCIM_m1_b = 1, // In PCIM_t -> {pci{iic,iim,ioic,ioim}} -+ PCIM_m1_m = 0x00000002, // inbound or outbound message 1 -+ PCIM_db_b = 2, // In PCIM_t -> {pci{iic,iim,ioic,ioim}} -+ PCIM_db_m = 0x00000004, // inbound or outbound doorbell -+}; -+ -+ -+ -+ -+ -+ -+#define PCI_MSG_VirtualAddress 0xB8088010 -+#define rc32434_pci ((volatile PCI_t) PCI0_VirtualAddress) -+#define rc32434_pci_msg ((volatile PCIM_t) PCI_MSG_VirtualAddress) -+ -+#define PCIM_SHFT 0x6 -+#define PCIM_BIT_LEN 0x7 -+#define PCIM_H_EA 0x3 -+#define PCIM_H_IA_FIX 0x4 -+#define PCIM_H_IA_RR 0x5 -+ -+#define PCI_ADDR_START 0x50000000 -+ -+#define CPUTOPCI_MEM_WIN 0x02000000 -+#define CPUTOPCI_IO_WIN 0x00100000 -+#define PCILBA_SIZE_SHFT 2 -+#define PCILBA_SIZE_MASK 0x1F -+#define SIZE_256MB 0x1C -+#define SIZE_128MB 0x1B -+#define SIZE_64MB 0x1A -+#define SIZE_32MB 0x19 -+#define SIZE_16MB 0x18 -+#define SIZE_4MB 0x16 -+#define SIZE_2MB 0x15 -+#define SIZE_1MB 0x14 -+#define KORINA_CONFIG0_ADDR 0x80000000 -+#define KORINA_CONFIG1_ADDR 0x80000004 -+#define KORINA_CONFIG2_ADDR 0x80000008 -+#define KORINA_CONFIG3_ADDR 0x8000000C -+#define KORINA_CONFIG4_ADDR 0x80000010 -+#define KORINA_CONFIG5_ADDR 0x80000014 -+#define KORINA_CONFIG6_ADDR 0x80000018 -+#define KORINA_CONFIG7_ADDR 0x8000001C -+#define KORINA_CONFIG8_ADDR 0x80000020 -+#define KORINA_CONFIG9_ADDR 0x80000024 -+#define KORINA_CONFIG10_ADDR 0x80000028 -+#define KORINA_CONFIG11_ADDR 0x8000002C -+#define KORINA_CONFIG12_ADDR 0x80000030 -+#define KORINA_CONFIG13_ADDR 0x80000034 -+#define KORINA_CONFIG14_ADDR 0x80000038 -+#define KORINA_CONFIG15_ADDR 0x8000003C -+#define KORINA_CONFIG16_ADDR 0x80000040 -+#define KORINA_CONFIG17_ADDR 0x80000044 -+#define KORINA_CONFIG18_ADDR 0x80000048 -+#define KORINA_CONFIG19_ADDR 0x8000004C -+#define KORINA_CONFIG20_ADDR 0x80000050 -+#define KORINA_CONFIG21_ADDR 0x80000054 -+#define KORINA_CONFIG22_ADDR 0x80000058 -+#define KORINA_CONFIG23_ADDR 0x8000005C -+#define KORINA_CONFIG24_ADDR 0x80000060 -+#define KORINA_CONFIG25_ADDR 0x80000064 -+#define KORINA_CMD (PCFG04_command_ioena_m | \ -+ PCFG04_command_memena_m | \ -+ PCFG04_command_bmena_m | \ -+ PCFG04_command_mwinv_m | \ -+ PCFG04_command_parena_m | \ -+ PCFG04_command_serrena_m ) -+ -+#define KORINA_STAT (PCFG04_status_mdpe_m | \ -+ PCFG04_status_sta_m | \ -+ PCFG04_status_rta_m | \ -+ PCFG04_status_rma_m | \ -+ PCFG04_status_sse_m | \ -+ PCFG04_status_pe_m) -+ -+#define KORINA_CNFG1 ((KORINA_STAT<<16)|KORINA_CMD) -+ -+#define KORINA_REVID 0 -+#define KORINA_CLASS_CODE 0 -+#define KORINA_CNFG2 ((KORINA_CLASS_CODE<<8) | \ -+ KORINA_REVID) -+ -+#define KORINA_CACHE_LINE_SIZE 4 -+#define KORINA_MASTER_LAT 0x3c -+#define KORINA_HEADER_TYPE 0 -+#define KORINA_BIST 0 -+ -+#define KORINA_CNFG3 ((KORINA_BIST << 24) | \ -+ (KORINA_HEADER_TYPE<<16) | \ -+ (KORINA_MASTER_LAT<<8) | \ -+ KORINA_CACHE_LINE_SIZE ) -+ -+#define KORINA_BAR0 0x00000008 /* 128 MB Memory */ -+#define KORINA_BAR1 0x18800001 /* 1 MB IO */ -+#define KORINA_BAR2 0x18000001 /* 2 MB IO window for Korina -+ internal Registers */ -+#define KORINA_BAR3 0x48000008 /* Spare 128 MB Memory */ -+ -+#define KORINA_CNFG4 KORINA_BAR0 -+#define KORINA_CNFG5 KORINA_BAR1 -+#define KORINA_CNFG6 KORINA_BAR2 -+#define KORINA_CNFG7 KORINA_BAR3 -+ -+#define KORINA_SUBSYS_VENDOR_ID 0x011d -+#define KORINA_SUBSYSTEM_ID 0x0214 -+#define KORINA_CNFG8 0 -+#define KORINA_CNFG9 0 -+#define KORINA_CNFG10 0 -+#define KORINA_CNFG11 ((KORINA_SUBSYS_VENDOR_ID<<16) | \ -+ KORINA_SUBSYSTEM_ID) -+#define KORINA_INT_LINE 1 -+#define KORINA_INT_PIN 1 -+#define KORINA_MIN_GNT 8 -+#define KORINA_MAX_LAT 0x38 -+#define KORINA_CNFG12 0 -+#define KORINA_CNFG13 0 -+#define KORINA_CNFG14 0 -+#define KORINA_CNFG15 ((KORINA_MAX_LAT<<24) | \ -+ (KORINA_MIN_GNT<<16) | \ -+ (KORINA_INT_PIN<<8) | \ -+ KORINA_INT_LINE) -+#define KORINA_RETRY_LIMIT 0x80 -+#define KORINA_TRDY_LIMIT 0x80 -+#define KORINA_CNFG16 ((KORINA_RETRY_LIMIT<<8) | \ -+ KORINA_TRDY_LIMIT) -+#define PCI_PBAxC_R 0x0 -+#define PCI_PBAxC_RL 0x1 -+#define PCI_PBAxC_RM 0x2 -+#define SIZE_SHFT 2 -+ -+#if defined(__MIPSEB__) -+#define KORINA_PBA0C ( PCIPBAC_mrl_m | PCIPBAC_sb_m | \ -+ ((PCI_PBAxC_RM &0x3) << PCIPBAC_mr_b) | \ -+ PCIPBAC_pp_m | \ -+ (SIZE_128MB<<SIZE_SHFT) | \ -+ PCIPBAC_p_m) -+#else -+#define KORINA_PBA0C ( PCIPBAC_mrl_m | \ -+ ((PCI_PBAxC_RM &0x3) << PCIPBAC_mr_b) | \ -+ PCIPBAC_pp_m | \ -+ (SIZE_128MB<<SIZE_SHFT) | \ -+ PCIPBAC_p_m) -+#endif -+#define KORINA_CNFG17 KORINA_PBA0C -+#define KORINA_PBA0M 0x0 -+#define KORINA_CNFG18 KORINA_PBA0M -+ -+#if defined(__MIPSEB__) -+#define KORINA_PBA1C ((SIZE_1MB<<SIZE_SHFT) | PCIPBAC_sb_m | \ -+ PCIPBAC_msi_m) -+#else -+#define KORINA_PBA1C ((SIZE_1MB<<SIZE_SHFT) | \ -+ PCIPBAC_msi_m) -+#endif -+#define KORINA_CNFG19 KORINA_PBA1C -+#define KORINA_PBA1M 0x0 -+#define KORINA_CNFG20 KORINA_PBA1M -+ -+#if defined(__MIPSEB__) -+#define KORINA_PBA2C ((SIZE_2MB<<SIZE_SHFT) | PCIPBAC_sb_m | \ -+ PCIPBAC_msi_m) -+#else -+#define KORINA_PBA2C ((SIZE_2MB<<SIZE_SHFT) | \ -+ PCIPBAC_msi_m) -+#endif -+#define KORINA_CNFG21 KORINA_PBA2C -+#define KORINA_PBA2M 0x18000000 -+#define KORINA_CNFG22 KORINA_PBA2M -+#define KORINA_PBA3C 0 -+#define KORINA_CNFG23 KORINA_PBA3C -+#define KORINA_PBA3M 0 -+#define KORINA_CNFG24 KORINA_PBA3M -+ -+ -+ -+#define PCITC_DTIMER_VAL 8 -+#define PCITC_RTIMER_VAL 0x10 -+ -+ -+ -+ -+#endif // __IDT_PCI_H__ -+ -+ -+ -diff -urN linux.old/include/asm-mips/rc32434/rb.h linux.dev/include/asm-mips/rc32434/rb.h ---- linux.old/include/asm-mips/rc32434/rb.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/rc32434/rb.h 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,84 @@ -+/* -+ * Copyright (C) 2004 IDT Inc. -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ * -+ * 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. -+ * -+ */ -+#ifndef __MIPS_RB_H__ -+#define __MIPS_RB_H__ -+#include <linux/genhd.h> -+ -+#define IDT434_REG_BASE ((volatile void *) KSEG1ADDR(0x18000000)) -+#define DEV0BASE 0x010000 -+#define DEV0MASK 0x010004 -+#define DEV0C 0x010008 -+#define DEV0TC 0x01000C -+#define DEV1BASE 0x010010 -+#define DEV1MASK 0x010014 -+#define DEV1C 0x010018 -+#define DEV1TC 0x01001C -+#define DEV2BASE 0x010020 -+#define DEV2MASK 0x010024 -+#define DEV2C 0x010028 -+#define DEV2TC 0x01002C -+#define DEV3BASE 0x010030 -+#define DEV3MASK 0x010034 -+#define DEV3C 0x010038 -+#define DEV3TC 0x01003C -+#define BTCS 0x010040 -+#define BTCOMPARE 0x010044 -+#define GPIOFUNC 0x050000 -+#define GPIOCFG 0x050004 -+#define GPIOD 0x050008 -+#define GPIOILEVEL 0x05000C -+#define GPIOISTAT 0x050010 -+#define GPIONMIEN 0x050014 -+#define IMASK6 0x038038 -+ -+#define LO_WPX (1 << 0) -+#define LO_ALE (1 << 1) -+#define LO_CLE (1 << 2) -+#define LO_CEX (1 << 3) -+#define LO_FOFF (1 << 5) -+#define LO_SPICS (1 << 6) -+#define LO_ULED (1 << 7) -+ -+typedef enum { -+ FUNC = 0x00, -+ CFG = 0x04, -+ DATA = 0x08, -+ ILEVEL = 0x0c, -+ ISTAT = 0x10, -+ NMIEN = 0x14 -+} gpio_func; -+ -+extern void changeLatchU5(unsigned char orMask, unsigned char nandMask); -+extern unsigned get434Reg(unsigned regOffs); -+extern void set434Reg(unsigned regOffs, unsigned bit, unsigned len, unsigned val); -+extern void gpio_set(gpio_func func, u32 mask, u32 value); -+extern u32 gpio_get(gpio_func func); -+ -+#define get434Reg(x) (*(volatile unsigned *) (IDT434_REG_BASE + (x))) -+ -+struct korina_device { -+ char *name; -+ unsigned char mac[6]; -+ struct net_device *dev; -+}; -+ -+struct cf_device { -+ int gpio_pin; -+ void *dev; -+ struct gendisk *gd; -+}; -+ -+#endif -diff -urN linux.old/include/asm-mips/rc32434/rc32434.h linux.dev/include/asm-mips/rc32434/rc32434.h ---- linux.old/include/asm-mips/rc32434/rc32434.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/rc32434/rc32434.h 2006-12-14 04:09:50.000000000 +0100 -@@ -0,0 +1,122 @@ -+/* -+ *************************************************************************** -+ * Definitions for IDT RC323434 CPU. -+ * -+ **************************************************************************** -+ * Kiran Rao -+ * -+ * Original form -+ **************************************************************************** -+ * P. Sadik Oct 08, 2003 -+ * -+ * Started revision history -+ * Made IDT_BUS_FREQ a kernel configuration parameter -+ **************************************************************************** -+ * P. Sadik Oct 10, 2003 -+ * -+ * Removed IDT_BUS_FREQ, since this parameter is no longer required. Instead -+ * idt_cpu_freq is used everywhere -+ **************************************************************************** -+ * P. Sadik Oct 20, 2003 -+ * -+ * Removed RC32434_BASE_BAUD -+ **************************************************************************** -+*/ -+#ifndef _RC32434_H_ -+#define _RC32434_H_ -+ -+#include <linux/autoconf.h> -+#include <linux/delay.h> -+#include <asm/io.h> -+ -+#define RC32434_REG_BASE 0x18000000 -+ -+#define interrupt ((volatile INT_t ) INT0_VirtualAddress) -+#define gpio ((volatile GPIO_t) GPIO0_VirtualAddress) -+ -+ -+#define IDT_CLOCK_MULT 2 -+#define MIPS_CPU_TIMER_IRQ 7 -+/* Interrupt Controller */ -+#define IC_GROUP0_PEND (RC32434_REG_BASE + 0x38000) -+#define IC_GROUP0_MASK (RC32434_REG_BASE + 0x38008) -+#define IC_GROUP_OFFSET 0x0C -+ -+#define NUM_INTR_GROUPS 5 -+/* 16550 UARTs */ -+ -+#define GROUP0_IRQ_BASE 8 /* GRP2 IRQ numbers start here */ -+#define GROUP1_IRQ_BASE (GROUP0_IRQ_BASE + 32) /* GRP3 IRQ numbers start here */ -+#define GROUP2_IRQ_BASE (GROUP1_IRQ_BASE + 32) /* GRP4 IRQ numbers start here */ -+#define GROUP3_IRQ_BASE (GROUP2_IRQ_BASE + 32) /* GRP5 IRQ numbers start here */ -+#define GROUP4_IRQ_BASE (GROUP3_IRQ_BASE + 32) -+ -+ -+#ifdef __MIPSEB__ -+#define RC32434_UART0_BASE (RC32434_REG_BASE + 0x58003) -+#else -+#define RC32434_UART0_BASE (RC32434_REG_BASE + 0x58000) -+#endif -+ -+#define RC32434_UART0_IRQ GROUP3_IRQ_BASE + 0 -+// #define EB434_UART1_IRQ GROUP4_IRQ_BASE + 11 -+ -+#define local_readl(addr) __raw_readl(addr) -+#define local_writel(l,addr) __raw_writel(l,addr) -+ -+/* cpu pipeline flush */ -+static inline void rc32434_sync(void) -+{ -+ __asm__ volatile ("sync"); -+} -+ -+static inline void rc32434_sync_udelay(int us) -+{ -+ __asm__ volatile ("sync"); -+ udelay(us); -+} -+ -+static inline void rc32434_sync_delay(int ms) -+{ -+ __asm__ volatile ("sync"); -+ mdelay(ms); -+} -+ -+/* -+ * C access to CLZ and CLO instructions -+ * (count leading zeroes/ones). -+ */ -+static inline int rc32434_clz(unsigned long val) -+{ -+ int ret; -+ __asm__ volatile ( -+ ".set\tnoreorder\n\t" -+ ".set\tnoat\n\t" -+ ".set\tmips32\n\t" -+ "clz\t%0,%1\n\t" -+ ".set\tmips0\n\t" -+ ".set\tat\n\t" -+ ".set\treorder" -+ : "=r" (ret) -+ : "r" (val)); -+ -+ return ret; -+} -+static inline int rc32434_clo(unsigned long val) -+{ -+ int ret; -+ __asm__ volatile ( -+ ".set\tnoreorder\n\t" -+ ".set\tnoat\n\t" -+ ".set\tmips32\n\t" -+ "clo\t%0,%1\n\t" -+ ".set\tmips0\n\t" -+ ".set\tat\n\t" -+ ".set\treorder" -+ : "=r" (ret) -+ : "r" (val)); -+ -+ return ret; -+} -+ -+#endif /* _RC32434_H_ */ diff --git a/target/linux/rb532-2.6/patches/110-korina_ethernet.patch b/target/linux/rb532-2.6/patches/110-korina_ethernet.patch index 5a6bf6f5d..55b9779a8 100644 --- a/target/linux/rb532-2.6/patches/110-korina_ethernet.patch +++ b/target/linux/rb532-2.6/patches/110-korina_ethernet.patch @@ -15,1170 +15,6 @@ diff -urN linux.old/drivers/net/Kconfig linux.dev/drivers/net/Kconfig config MACE tristate "MACE (Power Mac ethernet) support" depends on NET_ETHERNET && PPC_PMAC && PPC32 -diff -urN linux.old/drivers/net/korina.c linux.dev/drivers/net/korina.c ---- linux.old/drivers/net/korina.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/korina.c 2006-12-14 03:18:45.000000000 +0100 -@@ -0,0 +1,1160 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * Driver for the IDT RC32434 on-chip ethernet controller. -+ * -+ * Copyright 2004 IDT Inc. (rischelp@idt.com) -+ * Copyright 2006 Felix Fietkau <nbd@openwrt.org> -+ * -+ * 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 -+ * -+ * Based on the driver developed by B. Maruthanayakam, H. Kou and others. -+ * -+ * Aug 2004 Sadik -+ * -+ * Added NAPI -+ * -+ ************************************************************************** -+ */ -+ -+#include <linux/autoconf.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/moduleparam.h> -+#include <linux/sched.h> -+#include <linux/ctype.h> -+#include <linux/types.h> -+#include <linux/fcntl.h> -+#include <linux/interrupt.h> -+#include <linux/ptrace.h> -+#include <linux/init.h> -+#include <linux/ioport.h> -+#include <linux/proc_fs.h> -+#include <linux/in.h> -+#include <linux/slab.h> -+#include <linux/string.h> -+#include <linux/delay.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/skbuff.h> -+#include <linux/errno.h> -+#include <linux/platform_device.h> -+#include <asm/bootinfo.h> -+#include <asm/system.h> -+#include <asm/bitops.h> -+#include <asm/pgtable.h> -+#include <asm/segment.h> -+#include <asm/io.h> -+#include <asm/dma.h> -+ -+#include <asm/rc32434/rb.h> -+#include "rc32434_eth.h" -+ -+#define DRIVER_VERSION "(mar2904)" -+ -+#define DRIVER_NAME "rc32434 Ethernet driver. " DRIVER_VERSION -+ -+#define STATION_ADDRESS_HIGH(dev) (((dev)->dev_addr[0] << 8) | \ -+ ((dev)->dev_addr[1])) -+#define STATION_ADDRESS_LOW(dev) (((dev)->dev_addr[2] << 24) | \ -+ ((dev)->dev_addr[3] << 16) | \ -+ ((dev)->dev_addr[4] << 8) | \ -+ ((dev)->dev_addr[5])) -+ -+#define MII_CLOCK 1250000 /* no more than 2.5MHz */ -+#define CONFIG_IDT_USE_NAPI 1 -+ -+ -+static inline void rc32434_abort_tx(struct net_device *dev) -+{ -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ rc32434_abort_dma(dev, lp->tx_dma_regs); -+ -+} -+ -+static inline void rc32434_abort_rx(struct net_device *dev) -+{ -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ rc32434_abort_dma(dev, lp->rx_dma_regs); -+ -+} -+ -+static inline void rc32434_start_tx(struct rc32434_local *lp, volatile DMAD_t td) -+{ -+ rc32434_start_dma(lp->tx_dma_regs, CPHYSADDR(td)); -+} -+ -+static inline void rc32434_start_rx(struct rc32434_local *lp, volatile DMAD_t rd) -+{ -+ rc32434_start_dma(lp->rx_dma_regs, CPHYSADDR(rd)); -+} -+ -+static inline void rc32434_chain_tx(struct rc32434_local *lp, volatile DMAD_t td) -+{ -+ rc32434_chain_dma(lp->tx_dma_regs, CPHYSADDR(td)); -+} -+ -+static inline void rc32434_chain_rx(struct rc32434_local *lp, volatile DMAD_t rd) -+{ -+ rc32434_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd)); -+} -+ -+#ifdef RC32434_PROC_DEBUG -+static int rc32434_read_proc(char *buf, char **start, off_t fpos, -+ int length, int *eof, void *data) -+{ -+ struct net_device *dev = (struct net_device *)data; -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ int len = 0; -+ -+ /* print out header */ -+ len += sprintf(buf + len, "\n\tKorina Ethernet Debug\n\n"); -+ len += sprintf (buf + len, -+ "DMA halt count = %10d, DMA run count = %10d\n", -+ lp->dma_halt_cnt, lp->dma_run_cnt); -+ -+ if (fpos >= len) { -+ *start = buf; -+ *eof = 1; -+ return 0; -+ } -+ *start = buf + fpos; -+ -+ if ((len -= fpos) > length) -+ return length; -+ *eof = 1; -+ -+ return len; -+ -+} -+#endif -+ -+ -+/* -+ * Restart the RC32434 ethernet controller. -+ */ -+static int rc32434_restart(struct net_device *dev) -+{ -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ -+ /* -+ * Disable interrupts -+ */ -+ disable_irq(lp->rx_irq); -+ disable_irq(lp->tx_irq); -+#ifdef RC32434_REVISION -+ disable_irq(lp->ovr_irq); -+#endif -+ disable_irq(lp->und_irq); -+ -+ /* Mask F E bit in Tx DMA */ -+ __raw_writel(__raw_readl(&lp->tx_dma_regs->dmasm) | DMASM_f_m | DMASM_e_m, &lp->tx_dma_regs->dmasm); -+ /* Mask D H E bit in Rx DMA */ -+ __raw_writel(__raw_readl(&lp->rx_dma_regs->dmasm) | DMASM_d_m | DMASM_h_m | DMASM_e_m, &lp->rx_dma_regs->dmasm); -+ -+ rc32434_init(dev); -+ rc32434_multicast_list(dev); -+ -+ enable_irq(lp->und_irq); -+#ifdef RC32434_REVISION -+ enable_irq(lp->ovr_irq); -+#endif -+ enable_irq(lp->tx_irq); -+ enable_irq(lp->rx_irq); -+ -+ return 0; -+} -+ -+static int rc32434_probe(struct platform_device *pdev) -+{ -+ struct korina_device *bif = (struct korina_device *) pdev->dev.platform_data; -+ struct rc32434_local *lp = NULL; -+ struct net_device *dev = NULL; -+ struct resource *r; -+ int i, retval,err; -+ -+ dev = alloc_etherdev(sizeof(struct rc32434_local)); -+ if(!dev) { -+ ERR("Korina_eth: alloc_etherdev failed\n"); -+ return -1; -+ } -+ -+ platform_set_drvdata(pdev, dev); -+ SET_MODULE_OWNER(dev); -+ bif->dev = dev; -+ -+ memcpy(dev->dev_addr, bif->mac, 6); -+ -+ /* Initialize the device structure. */ -+ if (dev->priv == NULL) { -+ lp = (struct rc32434_local *)kmalloc(sizeof(*lp), GFP_KERNEL); -+ memset(lp, 0, sizeof(struct rc32434_local)); -+ } -+ else { -+ lp = (struct rc32434_local *)dev->priv; -+ } -+ -+ lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx"); -+ lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx"); -+ lp->ovr_irq = platform_get_irq_byname(pdev, "korina_ovr"); -+ lp->und_irq = platform_get_irq_byname(pdev, "korina_und"); -+ -+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_regs"); -+ dev->base_addr = r->start; -+ lp->eth_regs = ioremap_nocache(r->start, r->end - r->start); -+ if (!lp->eth_regs) { -+ ERR("Can't remap eth registers\n"); -+ retval = -ENXIO; -+ goto probe_err_out; -+ } -+ -+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_rx"); -+ lp->rx_dma_regs = ioremap_nocache(r->start, r->end - r->start); -+ if (!lp->rx_dma_regs) { -+ ERR("Can't remap Rx DMA registers\n"); -+ retval = -ENXIO; -+ goto probe_err_out; -+ } -+ -+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_tx"); -+ lp->tx_dma_regs = ioremap_nocache(r->start, r->end - r->start); -+ if (!lp->tx_dma_regs) { -+ ERR("Can't remap Tx DMA registers\n"); -+ retval = -ENXIO; -+ goto probe_err_out; -+ } -+ -+#ifdef RC32434_PROC_DEBUG -+ lp->ps = create_proc_read_entry (bif->name, 0, proc_net, -+ rc32434_read_proc, dev); -+#endif -+ -+ lp->td_ring = (DMAD_t)kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL); -+ if (!lp->td_ring) { -+ ERR("Can't allocate descriptors\n"); -+ retval = -ENOMEM; -+ goto probe_err_out; -+ } -+ -+ dma_cache_inv((unsigned long)(lp->td_ring), TD_RING_SIZE + RD_RING_SIZE); -+ -+ /* now convert TD_RING pointer to KSEG1 */ -+ lp->td_ring = (DMAD_t )KSEG1ADDR(lp->td_ring); -+ lp->rd_ring = &lp->td_ring[RC32434_NUM_TDS]; -+ -+ -+ spin_lock_init(&lp->lock); -+ -+ /* just use the rx dma irq */ -+ dev->irq = lp->rx_irq; -+ -+ dev->priv = lp; -+ -+ dev->open = rc32434_open; -+ dev->stop = rc32434_close; -+ dev->hard_start_xmit = rc32434_send_packet; -+ dev->get_stats = rc32434_get_stats; -+ dev->set_multicast_list = &rc32434_multicast_list; -+ dev->tx_timeout = rc32434_tx_timeout; -+ dev->watchdog_timeo = RC32434_TX_TIMEOUT; -+ -+#ifdef CONFIG_IDT_USE_NAPI -+ dev->poll = rc32434_poll; -+ dev->weight = 64; -+ printk("Using NAPI with weight %d\n",dev->weight); -+#else -+ lp->rx_tasklet = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL); -+ tasklet_init(lp->rx_tasklet, rc32434_rx_tasklet, (unsigned long)dev); -+#endif -+ lp->tx_tasklet = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL); -+ tasklet_init(lp->tx_tasklet, rc32434_tx_tasklet, (unsigned long)dev); -+ -+ if ((err = register_netdev(dev))) { -+ printk(KERN_ERR "rc32434 ethernet. Cannot register net device %d\n", err); -+ free_netdev(dev); -+ retval = -EINVAL; -+ goto probe_err_out; -+ } -+ -+ INFO("Rx IRQ %d, Tx IRQ %d, ", lp->rx_irq, lp->tx_irq); -+ for (i = 0; i < 6; i++) { -+ printk("%2.2x", dev->dev_addr[i]); -+ if (i<5) -+ printk(":"); -+ } -+ printk("\n"); -+ -+ return 0; -+ -+ probe_err_out: -+ rc32434_cleanup_module(); -+ ERR(" failed. Returns %d\n", retval); -+ return retval; -+ -+} -+ -+static int rc32434_remove(struct platform_device *pdev) -+{ -+ struct korina_device *bif = (struct korina_device *) pdev->dev.platform_data; -+ -+ if (bif->dev != NULL) { -+ struct rc32434_local *lp = (struct rc32434_local *)bif->dev->priv; -+ if (lp != NULL) { -+ if (lp->eth_regs) -+ iounmap((void*)lp->eth_regs); -+ if (lp->rx_dma_regs) -+ iounmap((void*)lp->rx_dma_regs); -+ if (lp->tx_dma_regs) -+ iounmap((void*)lp->tx_dma_regs); -+ if (lp->td_ring) -+ kfree((void*)KSEG0ADDR(lp->td_ring)); -+ -+#ifdef RC32434_PROC_DEBUG -+ if (lp->ps) { -+ remove_proc_entry(bif->name, proc_net); -+ } -+#endif -+ kfree(lp); -+ } -+ -+ platform_set_drvdata(pdev, NULL); -+ unregister_netdev(bif->dev); -+ free_netdev(bif->dev); -+ kfree(bif->dev); -+ } -+ return 0; -+} -+ -+ -+static int rc32434_open(struct net_device *dev) -+{ -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ -+ /* Initialize */ -+ if (rc32434_init(dev)) { -+ ERR("Error: cannot open the Ethernet device\n"); -+ return -EAGAIN; -+ } -+ -+ /* Install the interrupt handler that handles the Done Finished Ovr and Und Events */ -+ if (request_irq(lp->rx_irq, &rc32434_rx_dma_interrupt, -+ SA_SHIRQ | SA_INTERRUPT, -+ "Korina ethernet Rx", dev)) { -+ ERR(": unable to get Rx DMA IRQ %d\n", -+ lp->rx_irq); -+ return -EAGAIN; -+ } -+ if (request_irq(lp->tx_irq, &rc32434_tx_dma_interrupt, -+ SA_SHIRQ | SA_INTERRUPT, -+ "Korina ethernet Tx", dev)) { -+ ERR(": unable to get Tx DMA IRQ %d\n", -+ lp->tx_irq); -+ free_irq(lp->rx_irq, dev); -+ return -EAGAIN; -+ } -+ -+#ifdef RC32434_REVISION -+ /* Install handler for overrun error. */ -+ if (request_irq(lp->ovr_irq, &rc32434_ovr_interrupt, -+ SA_SHIRQ | SA_INTERRUPT, -+ "Ethernet Overflow", dev)) { -+ ERR(": unable to get OVR IRQ %d\n", -+ lp->ovr_irq); -+ free_irq(lp->rx_irq, dev); -+ free_irq(lp->tx_irq, dev); -+ return -EAGAIN; -+ } -+#endif -+ -+ /* Install handler for underflow error. */ -+ if (request_irq(lp->und_irq, &rc32434_und_interrupt, -+ SA_SHIRQ | SA_INTERRUPT, -+ "Ethernet Underflow", dev)) { -+ ERR(": unable to get UND IRQ %d\n", -+ lp->und_irq); -+ free_irq(lp->rx_irq, dev); -+ free_irq(lp->tx_irq, dev); -+#ifdef RC32434_REVISION -+ free_irq(lp->ovr_irq, dev); -+#endif -+ return -EAGAIN; -+ } -+ -+ -+ return 0; -+} -+ -+ -+ -+ -+static int rc32434_close(struct net_device *dev) -+{ -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ u32 tmp; -+ -+ /* Disable interrupts */ -+ disable_irq(lp->rx_irq); -+ disable_irq(lp->tx_irq); -+#ifdef RC32434_REVISION -+ disable_irq(lp->ovr_irq); -+#endif -+ disable_irq(lp->und_irq); -+ -+ tmp = __raw_readl(&lp->tx_dma_regs->dmasm); -+ tmp = tmp | DMASM_f_m | DMASM_e_m; -+ __raw_writel(tmp, &lp->tx_dma_regs->dmasm); -+ -+ tmp = __raw_readl(&lp->rx_dma_regs->dmasm); -+ tmp = tmp | DMASM_d_m | DMASM_h_m | DMASM_e_m; -+ __raw_writel(tmp, &lp->rx_dma_regs->dmasm); -+ -+ free_irq(lp->rx_irq, dev); -+ free_irq(lp->tx_irq, dev); -+#ifdef RC32434_REVISION -+ free_irq(lp->ovr_irq, dev); -+#endif -+ free_irq(lp->und_irq, dev); -+ return 0; -+} -+ -+ -+/* transmit packet */ -+static int rc32434_send_packet(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ unsigned long flags; -+ u32 length; -+ DMAD_t td; -+ -+ -+ spin_lock_irqsave(&lp->lock, flags); -+ -+ td = &lp->td_ring[lp->tx_chain_tail]; -+ -+ /* stop queue when full, drop pkts if queue already full */ -+ if(lp->tx_count >= (RC32434_NUM_TDS - 2)) { -+ lp->tx_full = 1; -+ -+ if(lp->tx_count == (RC32434_NUM_TDS - 2)) { -+ netif_stop_queue(dev); -+ } -+ else { -+ lp->stats.tx_dropped++; -+ dev_kfree_skb_any(skb); -+ spin_unlock_irqrestore(&lp->lock, flags); -+ return 1; -+ } -+ } -+ -+ lp->tx_count ++; -+ -+ lp->tx_skb[lp->tx_chain_tail] = skb; -+ -+ length = skb->len; -+ -+ /* Setup the transmit descriptor. */ -+ td->ca = CPHYSADDR(skb->data); -+ -+ if(__raw_readl(&(lp->tx_dma_regs->dmandptr)) == 0) { -+ if( lp->tx_chain_status == empty ) { -+ td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m; /* Update tail */ -+ lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */ -+ __raw_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); /* Write to NDPTR */ -+ lp->tx_chain_head = lp->tx_chain_tail; /* Move head to tail */ -+ } -+ else { -+ td->control = DMA_COUNT(length) |DMAD_cof_m|DMAD_iof_m; /* Update tail */ -+ lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].control &= ~(DMAD_cof_m); /* Link to prev */ -+ lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].link = CPHYSADDR(td); /* Link to prev */ -+ lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */ -+ __raw_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); /* Write to NDPTR */ -+ lp->tx_chain_head = lp->tx_chain_tail; /* Move head to tail */ -+ lp->tx_chain_status = empty; -+ } -+ } -+ else { -+ if( lp->tx_chain_status == empty ) { -+ td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m; /* Update tail */ -+ lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */ -+ lp->tx_chain_status = filled; -+ } -+ else { -+ td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m; /* Update tail */ -+ lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].control &= ~(DMAD_cof_m); /* Link to prev */ -+ lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].link = CPHYSADDR(td); /* Link to prev */ -+ lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */ -+ } -+ } -+ -+ dev->trans_start = jiffies; -+ -+ spin_unlock_irqrestore(&lp->lock, flags); -+ -+ return 0; -+} -+ -+ -+/* Ethernet MII-PHY Handler */ -+static void rc32434_mii_handler(unsigned long data) -+{ -+ struct net_device *dev = (struct net_device *)data; -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ unsigned long flags; -+ unsigned long duplex_status; -+ int port_addr = (lp->rx_irq == 0x2c? 1:0) << 8; -+ -+ spin_lock_irqsave(&lp->lock, flags); -+ -+ /* Two ports are using the same MII, the difference is the PHY address */ -+ __raw_writel(0, &rc32434_eth0_regs->miimcfg); -+ __raw_writel(0, &rc32434_eth0_regs->miimcmd); -+ __raw_writel(port_addr |0x05, &rc32434_eth0_regs->miimaddr); -+ __raw_writel(MIIMCMD_scn_m, &rc32434_eth0_regs->miimcmd); -+ while(__raw_readl(&rc32434_eth0_regs->miimind) & MIIMIND_nv_m); -+ -+ ERR("irq:%x port_addr:%x RDD:%x\n", -+ lp->rx_irq, port_addr, __raw_readl(&rc32434_eth0_regs->miimrdd)); -+ duplex_status = (__raw_readl(&rc32434_eth0_regs->miimrdd) & 0x140)? ETHMAC2_fd_m: 0; -+ if(duplex_status != lp->duplex_mode) { -+ ERR("The MII-PHY is Auto-negotiated to %s-Duplex mode for Eth-%x\n", duplex_status? "Full":"Half", lp->rx_irq == 0x2c? 1:0); -+ lp->duplex_mode = duplex_status; -+ rc32434_restart(dev); -+ } -+ -+ lp->mii_phy_timer.expires = jiffies + 10 * HZ; -+ add_timer(&lp->mii_phy_timer); -+ -+ spin_unlock_irqrestore(&lp->lock, flags); -+ -+} -+ -+#ifdef RC32434_REVISION -+/* Ethernet Rx Overflow interrupt */ -+static irqreturn_t -+rc32434_ovr_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = (struct net_device *)dev_id; -+ struct rc32434_local *lp; -+ unsigned int ovr; -+ irqreturn_t retval = IRQ_NONE; -+ -+ ASSERT(dev != NULL); -+ -+ lp = (struct rc32434_local *)dev->priv; -+ spin_lock(&lp->lock); -+ ovr = __raw_readl(&lp->eth_regs->ethintfc); -+ -+ if(ovr & ETHINTFC_ovr_m) { -+ netif_stop_queue(dev); -+ -+ /* clear OVR bit */ -+ __raw_writel((ovr & ~ETHINTFC_ovr_m), &lp->eth_regs->ethintfc); -+ -+ /* Restart interface */ -+ rc32434_restart(dev); -+ retval = IRQ_HANDLED; -+ } -+ spin_unlock(&lp->lock); -+ -+ return retval; -+} -+ -+#endif -+ -+ -+/* Ethernet Tx Underflow interrupt */ -+static irqreturn_t -+rc32434_und_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = (struct net_device *)dev_id; -+ struct rc32434_local *lp; -+ unsigned int und; -+ irqreturn_t retval = IRQ_NONE; -+ -+ ASSERT(dev != NULL); -+ -+ lp = (struct rc32434_local *)dev->priv; -+ -+ spin_lock(&lp->lock); -+ -+ und = __raw_readl(&lp->eth_regs->ethintfc); -+ -+ if(und & ETHINTFC_und_m) { -+ netif_stop_queue(dev); -+ -+ __raw_writel((und & ~ETHINTFC_und_m), &lp->eth_regs->ethintfc); -+ -+ /* Restart interface */ -+ rc32434_restart(dev); -+ retval = IRQ_HANDLED; -+ } -+ -+ spin_unlock(&lp->lock); -+ -+ return retval; -+} -+ -+ -+/* Ethernet Rx DMA interrupt */ -+static irqreturn_t -+rc32434_rx_dma_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = (struct net_device *)dev_id; -+ struct rc32434_local* lp; -+ volatile u32 dmas,dmasm; -+ irqreturn_t retval; -+ -+ ASSERT(dev != NULL); -+ -+ lp = (struct rc32434_local *)dev->priv; -+ -+ spin_lock(&lp->lock); -+ dmas = __raw_readl(&lp->rx_dma_regs->dmas); -+ if(dmas & (DMAS_d_m|DMAS_h_m|DMAS_e_m)) { -+ /* Mask D H E bit in Rx DMA */ -+ dmasm = __raw_readl(&lp->rx_dma_regs->dmasm); -+ __raw_writel(dmasm | (DMASM_d_m | DMASM_h_m | DMASM_e_m), &lp->rx_dma_regs->dmasm); -+#ifdef CONFIG_IDT_USE_NAPI -+ if(netif_rx_schedule_prep(dev)) -+ __netif_rx_schedule(dev); -+#else -+ tasklet_hi_schedule(lp->rx_tasklet); -+#endif -+ -+ if (dmas & DMAS_e_m) -+ ERR(": DMA error\n"); -+ -+ retval = IRQ_HANDLED; -+ } -+ else -+ retval = IRQ_NONE; -+ -+ spin_unlock(&lp->lock); -+ return retval; -+} -+ -+#ifdef CONFIG_IDT_USE_NAPI -+static int rc32434_poll(struct net_device *rx_data_dev, int *budget) -+#else -+static void rc32434_rx_tasklet(unsigned long rx_data_dev) -+#endif -+{ -+ struct net_device *dev = (struct net_device *)rx_data_dev; -+ struct rc32434_local* lp = netdev_priv(dev); -+ volatile DMAD_t rd = &lp->rd_ring[lp->rx_next_done]; -+ struct sk_buff *skb, *skb_new; -+ u8* pkt_buf; -+ u32 devcs, count, pkt_len, pktuncrc_len; -+ volatile u32 dmas; -+#ifdef CONFIG_IDT_USE_NAPI -+ u32 received = 0; -+ int rx_work_limit = min(*budget,dev->quota); -+#else -+ unsigned long flags; -+ spin_lock_irqsave(&lp->lock, flags); -+#endif -+ -+ while ( (count = RC32434_RBSIZE - (u32)DMA_COUNT(rd->control)) != 0) { -+#ifdef CONFIG_IDT_USE_NAPI -+ if(--rx_work_limit <0) -+ { -+ break; -+ } -+#endif -+ /* init the var. used for the later operations within the while loop */ -+ skb_new = NULL; -+ devcs = rd->devcs; -+ pkt_len = RCVPKT_LENGTH(devcs); -+ skb = lp->rx_skb[lp->rx_next_done]; -+ -+ if (count < 64) { -+ lp->stats.rx_errors++; -+ lp->stats.rx_dropped++; -+ } -+ else if ((devcs & ( ETHRX_ld_m)) != ETHRX_ld_m) { -+ /* check that this is a whole packet */ -+ /* WARNING: DMA_FD bit incorrectly set in Rc32434 (errata ref #077) */ -+ lp->stats.rx_errors++; -+ lp->stats.rx_dropped++; -+ } -+ else if ( (devcs & ETHRX_rok_m) ) { -+ -+ { -+ /* must be the (first and) last descriptor then */ -+ pkt_buf = (u8*)lp->rx_skb[lp->rx_next_done]->data; -+ -+ pktuncrc_len = pkt_len - 4; -+ /* invalidate the cache */ -+ dma_cache_inv((unsigned long)pkt_buf, pktuncrc_len); -+ -+ /* Malloc up new buffer. */ -+ skb_new = dev_alloc_skb(RC32434_RBSIZE + 2); -+ -+ if (skb_new != NULL){ -+ /* Make room */ -+ skb_put(skb, pktuncrc_len); -+ -+ skb->protocol = eth_type_trans(skb, dev); -+ -+ /* pass the packet to upper layers */ -+#ifdef CONFIG_IDT_USE_NAPI -+ netif_receive_skb(skb); -+#else -+ netif_rx(skb); -+#endif -+ -+ dev->last_rx = jiffies; -+ lp->stats.rx_packets++; -+ lp->stats.rx_bytes += pktuncrc_len; -+ -+ if (IS_RCV_MP(devcs)) -+ lp->stats.multicast++; -+ -+ /* 16 bit align */ -+ skb_reserve(skb_new, 2); -+ -+ skb_new->dev = dev; -+ lp->rx_skb[lp->rx_next_done] = skb_new; -+ } -+ else { -+ ERR("no memory, dropping rx packet.\n"); -+ lp->stats.rx_errors++; -+ lp->stats.rx_dropped++; -+ } -+ } -+ -+ } -+ else { -+ /* This should only happen if we enable accepting broken packets */ -+ lp->stats.rx_errors++; -+ lp->stats.rx_dropped++; -+ -+ /* add statistics counters */ -+ if (IS_RCV_CRC_ERR(devcs)) { -+ DBG(2, "RX CRC error\n"); -+ lp->stats.rx_crc_errors++; -+ } -+ else if (IS_RCV_LOR_ERR(devcs)) { -+ DBG(2, "RX LOR error\n"); -+ lp->stats.rx_length_errors++; -+ } -+ else if (IS_RCV_LE_ERR(devcs)) { -+ DBG(2, "RX LE error\n"); -+ lp->stats.rx_length_errors++; -+ } -+ else if (IS_RCV_OVR_ERR(devcs)) { -+ lp->stats.rx_over_errors++; -+ } -+ else if (IS_RCV_CV_ERR(devcs)) { -+ /* code violation */ -+ DBG(2, "RX CV error\n"); -+ lp->stats.rx_frame_errors++; -+ } -+ else if (IS_RCV_CES_ERR(devcs)) { -+ DBG(2, "RX Preamble error\n"); -+ } -+ } -+ -+ rd->devcs = 0; -+ -+ /* restore descriptor's curr_addr */ -+ if(skb_new) -+ rd->ca = CPHYSADDR(skb_new->data); -+ else -+ rd->ca = CPHYSADDR(skb->data); -+ -+ rd->control = DMA_COUNT(RC32434_RBSIZE) |DMAD_cod_m |DMAD_iod_m; -+ lp->rd_ring[(lp->rx_next_done-1)& RC32434_RDS_MASK].control &= ~(DMAD_cod_m); -+ -+ lp->rx_next_done = (lp->rx_next_done + 1) & RC32434_RDS_MASK; -+ rd = &lp->rd_ring[lp->rx_next_done]; -+ __raw_writel( ~DMAS_d_m, &lp->rx_dma_regs->dmas); -+ } -+#ifdef CONFIG_IDT_USE_NAPI -+ dev->quota -= received; -+ *budget =- received; -+ if(rx_work_limit < 0) -+ goto not_done; -+#endif -+ -+ dmas = __raw_readl(&lp->rx_dma_regs->dmas); -+ -+ if(dmas & DMAS_h_m) { -+ __raw_writel( ~(DMAS_h_m | DMAS_e_m), &lp->rx_dma_regs->dmas); -+#ifdef RC32434_PROC_DEBUG -+ lp->dma_halt_cnt++; -+#endif -+ rd->devcs = 0; -+ skb = lp->rx_skb[lp->rx_next_done]; -+ rd->ca = CPHYSADDR(skb->data); -+ rc32434_chain_rx(lp,rd); -+ } -+ -+#ifdef CONFIG_IDT_USE_NAPI -+ netif_rx_complete(dev); -+#endif -+ /* Enable D H E bit in Rx DMA */ -+ __raw_writel(__raw_readl(&lp->rx_dma_regs->dmasm) & ~(DMASM_d_m | DMASM_h_m |DMASM_e_m), &lp->rx_dma_regs->dmasm); -+#ifdef CONFIG_IDT_USE_NAPI -+ return 0; -+ not_done: -+ return 1; -+#else -+ spin_unlock_irqrestore(&lp->lock, flags); -+ return; -+#endif -+ -+ -+} -+ -+ -+ -+/* Ethernet Tx DMA interrupt */ -+static irqreturn_t -+rc32434_tx_dma_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = (struct net_device *)dev_id; -+ struct rc32434_local *lp; -+ volatile u32 dmas,dmasm; -+ irqreturn_t retval; -+ -+ ASSERT(dev != NULL); -+ -+ lp = (struct rc32434_local *)dev->priv; -+ -+ spin_lock(&lp->lock); -+ -+ dmas = __raw_readl(&lp->tx_dma_regs->dmas); -+ -+ if (dmas & (DMAS_f_m | DMAS_e_m)) { -+ dmasm = __raw_readl(&lp->tx_dma_regs->dmasm); -+ /* Mask F E bit in Tx DMA */ -+ __raw_writel(dmasm | (DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm); -+ -+ tasklet_hi_schedule(lp->tx_tasklet); -+ -+ if(lp->tx_chain_status == filled && (__raw_readl(&(lp->tx_dma_regs->dmandptr)) == 0)) { -+ __raw_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); -+ lp->tx_chain_status = empty; -+ lp->tx_chain_head = lp->tx_chain_tail; -+ dev->trans_start = jiffies; -+ } -+ -+ if (dmas & DMAS_e_m) -+ ERR(": DMA error\n"); -+ -+ retval = IRQ_HANDLED; -+ } -+ else -+ retval = IRQ_NONE; -+ -+ spin_unlock(&lp->lock); -+ -+ return retval; -+} -+ -+ -+static void rc32434_tx_tasklet(unsigned long tx_data_dev) -+{ -+ struct net_device *dev = (struct net_device *)tx_data_dev; -+ struct rc32434_local* lp = (struct rc32434_local *)dev->priv; -+ volatile DMAD_t td = &lp->td_ring[lp->tx_next_done]; -+ u32 devcs; -+ unsigned long flags; -+ volatile u32 dmas; -+ -+ spin_lock_irqsave(&lp->lock, flags); -+ -+ /* process all desc that are done */ -+ while(IS_DMA_FINISHED(td->control)) { -+ if(lp->tx_full == 1) { -+ netif_wake_queue(dev); -+ lp->tx_full = 0; -+ } -+ -+ devcs = lp->td_ring[lp->tx_next_done].devcs; -+ if ((devcs & (ETHTX_fd_m | ETHTX_ld_m)) != (ETHTX_fd_m | ETHTX_ld_m)) { -+ lp->stats.tx_errors++; -+ lp->stats.tx_dropped++; -+ -+ /* should never happen */ -+ DBG(1, __FUNCTION__ ": split tx ignored\n"); -+ } -+ else if (IS_TX_TOK(devcs)) { -+ lp->stats.tx_packets++; -+ } -+ else { -+ lp->stats.tx_errors++; -+ lp->stats.tx_dropped++; -+ -+ /* underflow */ -+ if (IS_TX_UND_ERR(devcs)) -+ lp->stats.tx_fifo_errors++; -+ -+ /* oversized frame */ -+ if (IS_TX_OF_ERR(devcs)) -+ lp->stats.tx_aborted_errors++; -+ -+ /* excessive deferrals */ -+ if (IS_TX_ED_ERR(devcs)) -+ lp->stats.tx_carrier_errors++; -+ -+ /* collisions: medium busy */ -+ if (IS_TX_EC_ERR(devcs)) -+ lp->stats.collisions++; -+ -+ /* late collision */ -+ if (IS_TX_LC_ERR(devcs)) -+ lp->stats.tx_window_errors++; -+ -+ } -+ -+ /* We must always free the original skb */ -+ if (lp->tx_skb[lp->tx_next_done] != NULL) { -+ dev_kfree_skb_any(lp->tx_skb[lp->tx_next_done]); -+ lp->tx_skb[lp->tx_next_done] = NULL; -+ } -+ -+ lp->td_ring[lp->tx_next_done].control = DMAD_iof_m; -+ lp->td_ring[lp->tx_next_done].devcs = ETHTX_fd_m | ETHTX_ld_m; -+ lp->td_ring[lp->tx_next_done].link = 0; -+ lp->td_ring[lp->tx_next_done].ca = 0; -+ lp->tx_count --; -+ -+ /* go on to next transmission */ -+ lp->tx_next_done = (lp->tx_next_done + 1) & RC32434_TDS_MASK; -+ td = &lp->td_ring[lp->tx_next_done]; -+ -+ } -+ -+ dmas = __raw_readl(&lp->tx_dma_regs->dmas); -+ __raw_writel( ~dmas, &lp->tx_dma_regs->dmas); -+ -+ /* Enable F E bit in Tx DMA */ -+ __raw_writel(__raw_readl(&lp->tx_dma_regs->dmasm) & ~(DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm); -+ spin_unlock_irqrestore(&lp->lock, flags); -+ -+} -+ -+ -+static struct net_device_stats * rc32434_get_stats(struct net_device *dev) -+{ -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ return &lp->stats; -+} -+ -+ -+/* -+ * Set or clear the multicast filter for this adaptor. -+ */ -+static void rc32434_multicast_list(struct net_device *dev) -+{ -+ /* listen to broadcasts always and to treat */ -+ /* IFF bits independantly */ -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ unsigned long flags; -+ u32 recognise = ETHARC_ab_m; /* always accept broadcasts */ -+ -+ if (dev->flags & IFF_PROMISC) /* set promiscuous mode */ -+ recognise |= ETHARC_pro_m; -+ -+ if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) -+ recognise |= ETHARC_am_m; /* all multicast & bcast */ -+ else if (dev->mc_count > 0) { -+ DBG(2, __FUNCTION__ ": mc_count %d\n", dev->mc_count); -+ recognise |= ETHARC_am_m; /* for the time being */ -+ } -+ -+ spin_lock_irqsave(&lp->lock, flags); -+ __raw_writel(recognise, &lp->eth_regs->etharc); -+ spin_unlock_irqrestore(&lp->lock, flags); -+} -+ -+ -+static void rc32434_tx_timeout(struct net_device *dev) -+{ -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&lp->lock, flags); -+ rc32434_restart(dev); -+ spin_unlock_irqrestore(&lp->lock, flags); -+ -+} -+ -+ -+/* -+ * Initialize the RC32434 ethernet controller. -+ */ -+static int rc32434_init(struct net_device *dev) -+{ -+ struct rc32434_local *lp = (struct rc32434_local *)dev->priv; -+ int i, j; -+ -+ /* Disable DMA */ -+ rc32434_abort_tx(dev); -+ rc32434_abort_rx(dev); -+ -+ /* reset ethernet logic */ -+ __raw_writel(0, &lp->eth_regs->ethintfc); -+ while((__raw_readl(&lp->eth_regs->ethintfc) & ETHINTFC_rip_m)) -+ dev->trans_start = jiffies; -+ -+ /* Enable Ethernet Interface */ -+ __raw_writel(ETHINTFC_en_m, &lp->eth_regs->ethintfc); -+ -+#ifndef CONFIG_IDT_USE_NAPI -+ tasklet_disable(lp->rx_tasklet); -+#endif -+ tasklet_disable(lp->tx_tasklet); -+ -+ /* Initialize the transmit Descriptors */ -+ for (i = 0; i < RC32434_NUM_TDS; i++) { -+ lp->td_ring[i].control = DMAD_iof_m; -+ lp->td_ring[i].devcs = ETHTX_fd_m | ETHTX_ld_m; -+ lp->td_ring[i].ca = 0; -+ lp->td_ring[i].link = 0; -+ if (lp->tx_skb[i] != NULL) { -+ dev_kfree_skb_any(lp->tx_skb[i]); -+ lp->tx_skb[i] = NULL; -+ } -+ } -+ lp->tx_next_done = lp->tx_chain_head = lp->tx_chain_tail = lp->tx_full = lp->tx_count = 0; -+ lp-> tx_chain_status = empty; -+ -+ /* -+ * Initialize the receive descriptors so that they -+ * become a circular linked list, ie. let the last -+ * descriptor point to the first again. -+ */ -+ for (i=0; i<RC32434_NUM_RDS; i++) { -+ struct sk_buff *skb = lp->rx_skb[i]; -+ -+ if (lp->rx_skb[i] == NULL) { -+ skb = dev_alloc_skb(RC32434_RBSIZE + 2); -+ if (skb == NULL) { -+ ERR("No memory in the system\n"); -+ for (j = 0; j < RC32434_NUM_RDS; j ++) -+ if (lp->rx_skb[j] != NULL) -+ dev_kfree_skb_any(lp->rx_skb[j]); -+ -+ return 1; -+ } -+ else { -+ skb->dev = dev; -+ skb_reserve(skb, 2); -+ lp->rx_skb[i] = skb; -+ lp->rd_ring[i].ca = CPHYSADDR(skb->data); -+ -+ } -+ } -+ lp->rd_ring[i].control = DMAD_iod_m | DMA_COUNT(RC32434_RBSIZE); -+ lp->rd_ring[i].devcs = 0; -+ lp->rd_ring[i].ca = CPHYSADDR(skb->data); -+ lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]); -+ -+ } -+ /* loop back */ -+ lp->rd_ring[RC32434_NUM_RDS-1].link = CPHYSADDR(&lp->rd_ring[0]); -+ lp->rx_next_done = 0; -+ -+ lp->rd_ring[RC32434_NUM_RDS-1].control |= DMAD_cod_m; -+ lp->rx_chain_head = 0; -+ lp->rx_chain_tail = 0; -+ lp->rx_chain_status = empty; -+ -+ __raw_writel(0, &lp->rx_dma_regs->dmas); -+ /* Start Rx DMA */ -+ rc32434_start_rx(lp, &lp->rd_ring[0]); -+ -+ /* Enable F E bit in Tx DMA */ -+ __raw_writel(__raw_readl(&lp->tx_dma_regs->dmasm) & ~(DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm); -+ /* Enable D H E bit in Rx DMA */ -+ __raw_writel(__raw_readl(&lp->rx_dma_regs->dmasm) & ~(DMASM_d_m | DMASM_h_m | DMASM_e_m), &lp->rx_dma_regs->dmasm); -+ -+ /* Accept only packets destined for this Ethernet device address */ -+ __raw_writel(ETHARC_ab_m, &lp->eth_regs->etharc); -+ -+ /* Set all Ether station address registers to their initial values */ -+ __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal0); -+ __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah0); -+ -+ __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal1); -+ __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah1); -+ -+ __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal2); -+ __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah2); -+ -+ __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal3); -+ __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah3); -+ -+ -+ /* Frame Length Checking, Pad Enable, CRC Enable, Full Duplex set */ -+ __raw_writel(ETHMAC2_pe_m | ETHMAC2_cen_m | ETHMAC2_fd_m, &lp->eth_regs->ethmac2); -+ //ETHMAC2_flc_m ETHMAC2_fd_m lp->duplex_mode -+ -+ /* Back to back inter-packet-gap */ -+ __raw_writel(0x15, &lp->eth_regs->ethipgt); -+ /* Non - Back to back inter-packet-gap */ -+ __raw_writel(0x12, &lp->eth_regs->ethipgr); -+ -+ /* Management Clock Prescaler Divisor */ -+ /* Clock independent setting */ -+ __raw_writel(((idt_cpu_freq)/MII_CLOCK+1) & ~1, -+ &lp->eth_regs->ethmcp); -+ -+ /* don't transmit until fifo contains 48b */ -+ __raw_writel(48, &lp->eth_regs->ethfifott); -+ -+ __raw_writel(ETHMAC1_re_m, &lp->eth_regs->ethmac1); -+ -+#ifndef CONFIG_IDT_USE_NAPI -+ tasklet_enable(lp->rx_tasklet); -+#endif -+ tasklet_enable(lp->tx_tasklet); -+ -+ netif_start_queue(dev); -+ -+ return 0; -+} -+ -+static struct platform_driver korina_driver = { -+ .driver.name = "korina", -+ .probe = rc32434_probe, -+ .remove = rc32434_remove, -+}; -+ -+static int __init rc32434_init_module(void) -+{ -+ return platform_driver_register(&korina_driver); -+} -+ -+static void rc32434_cleanup_module(void) -+{ -+ return platform_driver_unregister(&korina_driver); -+} -+ -+module_init(rc32434_init_module); -+module_exit(rc32434_cleanup_module); diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile --- linux.old/drivers/net/Makefile 2006-12-14 03:13:47.000000000 +0100 +++ linux.dev/drivers/net/Makefile 2006-12-14 03:18:45.000000000 +0100 @@ -1191,185 +27,4 @@ diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile obj-$(CONFIG_ROADRUNNER) += rrunner.o obj-$(CONFIG_HAPPYMEAL) += sunhme.o -diff -urN linux.old/drivers/net/rc32434_eth.h linux.dev/drivers/net/rc32434_eth.h ---- linux.old/drivers/net/rc32434_eth.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/rc32434_eth.h 2006-12-14 03:18:45.000000000 +0100 -@@ -0,0 +1,178 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * Definitions for IDT RC32434 on-chip ethernet controller. -+ * -+ * 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 -+ * -+ * Aug 2004 -+ * -+ * Added NAPI -+ * -+ ************************************************************************** -+ */ -+ -+ -+#include <asm/rc32434/rc32434.h> -+#include <asm/rc32434/dma_v.h> -+#include <asm/rc32434/eth_v.h> -+ -+#define CONFIG_IDT_USE_NAPI 1 -+#define RC32434_DEBUG 2 -+//#define RC32434_PROC_DEBUG -+#undef RC32434_DEBUG -+ -+#ifdef RC32434_DEBUG -+ -+/* use 0 for production, 1 for verification, >2 for debug */ -+static int rc32434_debug = RC32434_DEBUG; -+#define ASSERT(expr) \ -+ if(!(expr)) { \ -+ printk( "Assertion failed! %s,%s,%s,line=%d\n", \ -+ #expr,__FILE__,__FUNCTION__,__LINE__); } -+#define DBG(lvl, format, arg...) if (rc32434_debug > lvl) printk(KERN_INFO "%s: " format, dev->name , ## arg) -+#else -+#define ASSERT(expr) do {} while (0) -+#define DBG(lvl, format, arg...) do {} while (0) -+#endif -+ -+#define INFO(format, arg...) printk(KERN_INFO "%s: " format, dev->name , ## arg) -+#define ERR(format, arg...) printk(KERN_ERR "%s: " format, dev->name , ## arg) -+#define WARN(format, arg...) printk(KERN_WARNING "%s: " format, dev->name , ## arg) -+ -+/* the following must be powers of two */ -+#ifdef CONFIG_IDT_USE_NAPI -+#define RC32434_NUM_RDS 64 /* number of receive descriptors */ -+#define RC32434_NUM_TDS 64 /* number of transmit descriptors */ -+#else -+#define RC32434_NUM_RDS 128 /* number of receive descriptors */ -+#define RC32434_NUM_TDS 128 /* number of transmit descriptors */ -+#endif -+ -+#define RC32434_RBSIZE 1536 /* size of one resource buffer = Ether MTU */ -+#define RC32434_RDS_MASK (RC32434_NUM_RDS-1) -+#define RC32434_TDS_MASK (RC32434_NUM_TDS-1) -+#define RD_RING_SIZE (RC32434_NUM_RDS * sizeof(struct DMAD_s)) -+#define TD_RING_SIZE (RC32434_NUM_TDS * sizeof(struct DMAD_s)) -+ -+#define RC32434_TX_TIMEOUT HZ * 100 -+ -+#define rc32434_eth0_regs ((ETH_t)(ETH0_VirtualAddress)) -+#define rc32434_eth1_regs ((ETH_t)(ETH1_VirtualAddress)) -+ -+enum status { filled, empty}; -+#define IS_DMA_FINISHED(X) (((X) & (DMAD_f_m)) != 0) -+#define IS_DMA_DONE(X) (((X) & (DMAD_d_m)) != 0) -+ -+ -+/* Information that need to be kept for each board. */ -+struct rc32434_local { -+ ETH_t eth_regs; -+ DMA_Chan_t rx_dma_regs; -+ DMA_Chan_t tx_dma_regs; -+ volatile DMAD_t td_ring; /* transmit descriptor ring */ -+ volatile DMAD_t rd_ring; /* receive descriptor ring */ -+ -+ struct sk_buff* tx_skb[RC32434_NUM_TDS]; /* skbuffs for pkt to trans */ -+ struct sk_buff* rx_skb[RC32434_NUM_RDS]; /* skbuffs for pkt to trans */ -+ -+#ifndef CONFIG_IDT_USE_NAPI -+ struct tasklet_struct * rx_tasklet; -+#endif -+ struct tasklet_struct * tx_tasklet; -+ -+ int rx_next_done; -+ int rx_chain_head; -+ int rx_chain_tail; -+ enum status rx_chain_status; -+ -+ int tx_next_done; -+ int tx_chain_head; -+ int tx_chain_tail; -+ enum status tx_chain_status; -+ int tx_count; -+ int tx_full; -+ -+ struct timer_list mii_phy_timer; -+ unsigned long duplex_mode; -+ -+ int rx_irq; -+ int tx_irq; -+ int ovr_irq; -+ int und_irq; -+ -+ struct net_device_stats stats; -+ spinlock_t lock; -+ -+ /* debug /proc entry */ -+ struct proc_dir_entry *ps; -+ int dma_halt_cnt; int dma_run_cnt; -+}; -+ -+extern unsigned int idt_cpu_freq; -+ -+/* Index to functions, as function prototypes. */ -+static int rc32434_open(struct net_device *dev); -+static int rc32434_send_packet(struct sk_buff *skb, struct net_device *dev); -+static void rc32434_mii_handler(unsigned long data); -+static irqreturn_t rc32434_und_interrupt(int irq, void *dev_id); -+static irqreturn_t rc32434_rx_dma_interrupt(int irq, void *dev_id); -+static irqreturn_t rc32434_tx_dma_interrupt(int irq, void *dev_id); -+#ifdef RC32434_REVISION -+static irqreturn_t rc32434_ovr_interrupt(int irq, void *dev_id); -+#endif -+static int rc32434_close(struct net_device *dev); -+static struct net_device_stats *rc32434_get_stats(struct net_device *dev); -+static void rc32434_multicast_list(struct net_device *dev); -+static int rc32434_init(struct net_device *dev); -+static void rc32434_tx_timeout(struct net_device *dev); -+ -+static void rc32434_tx_tasklet(unsigned long tx_data_dev); -+#ifdef CONFIG_IDT_USE_NAPI -+static int rc32434_poll(struct net_device *rx_data_dev, int *budget); -+#else -+static void rc32434_rx_tasklet(unsigned long rx_data_dev); -+#endif -+static void rc32434_cleanup_module(void); -+ -+ -+static inline void rc32434_abort_dma(struct net_device *dev, DMA_Chan_t ch) -+{ -+ if (__raw_readl(&ch->dmac) & DMAC_run_m) { -+ __raw_writel(0x10, &ch->dmac); -+ -+ while (!(__raw_readl(&ch->dmas) & DMAS_h_m)) -+ dev->trans_start = jiffies; -+ -+ __raw_writel(0, &ch->dmas); -+ } -+ -+ __raw_writel(0, &ch->dmadptr); -+ __raw_writel(0, &ch->dmandptr); -+} + diff --git a/target/linux/rb532-2.6/patches/120-cf.patch b/target/linux/rb532-2.6/patches/120-cf.patch index f702753c7..19395ef66 100644 --- a/target/linux/rb532-2.6/patches/120-cf.patch +++ b/target/linux/rb532-2.6/patches/120-cf.patch @@ -23,989 +23,4 @@ diff -urN linux.old/drivers/block/Makefile linux.dev/drivers/block/Makefile obj-$(CONFIG_BLK_DEV_UB) += ub.o +obj-$(CONFIG_BLK_DEV_CF_MIPS) += rb500/ -diff -urN linux.old/drivers/block/rb500/ata.c linux.dev/drivers/block/rb500/ata.c ---- linux.old/drivers/block/rb500/ata.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/block/rb500/ata.c 2006-10-26 00:11:14.000000000 +0200 -@@ -0,0 +1,485 @@ -+/* CF-mips driver -+ This is a block driver for the direct (mmaped) interface to the CF-slot, -+ found in Routerboard.com's RB532 board -+ See SDK provided from routerboard.com. -+ -+ Module adapted By P.Christeas <p_christeas@yahoo.com>, 2005-6. -+ Cleaned up and adapted to platform_device by Felix Fietkau <nbd@openwrt.org> -+ -+ This work is redistributed under the terms of the GNU General Public License. -+*/ -+ -+#include <linux/kernel.h> /* printk() */ -+#include <linux/module.h> /* module to be loadable */ -+#include <linux/delay.h> -+#include <linux/sched.h> -+#include <linux/pci.h> -+#include <linux/ioport.h> /* request_mem_region() */ -+#include <asm/unaligned.h> /* ioremap() */ -+#include <asm/io.h> /* ioremap() */ -+#include <asm/rc32434/rb.h> -+ -+#include "ata.h" -+ -+#define REQUEST_MEM_REGION 0 -+#define DEBUG 1 -+ -+#if DEBUG -+#define DEBUGP printk -+#else -+#define DEBUGP(format, args...) -+#endif -+ -+#define SECS 1000000 /* unit for wait_not_busy() is 1us */ -+ -+unsigned cf_head = 0; -+unsigned cf_cyl = 0; -+unsigned cf_spt = 0; -+unsigned cf_sectors = 0; -+static unsigned cf_block_size = 1; -+static void *baddr = 0; -+ -+#define DBUF32 ((volatile u32 *)((unsigned long)dev->baddr | ATA_DBUF_OFFSET)) -+ -+ -+static void cf_do_tasklet(unsigned long dev_l); -+ -+ -+static inline void wareg(u8 val, unsigned reg, struct cf_mips_dev* dev) -+{ -+ writeb(val, dev->baddr + ATA_REG_OFFSET + reg); -+} -+ -+static inline u8 rareg(unsigned reg, struct cf_mips_dev* dev) -+{ -+ return readb(dev->baddr + ATA_REG_OFFSET + reg); -+} -+ -+static inline int get_gpio_bit(gpio_func ofs, struct cf_mips_dev *dev) -+{ -+ return (gpio_get(ofs) >> dev->pin) & 1; -+} -+ -+static inline void set_gpio_bit(int bit, gpio_func ofs, struct cf_mips_dev *dev) -+{ -+ gpio_set(ofs, (1 << dev->pin), ((bit & 1) << dev->pin)); -+} -+ -+static inline int cfrdy(struct cf_mips_dev *dev) -+{ -+ return get_gpio_bit(DATA, dev); -+} -+ -+static inline void prepare_cf_irq(struct cf_mips_dev *dev) -+{ -+ set_gpio_bit(1, ILEVEL, dev); /* interrupt on cf ready (not busy) */ -+ set_gpio_bit(0, ISTAT, dev); /* clear interrupt status */ -+} -+ -+static inline int cf_present(struct cf_mips_dev* dev) -+{ -+ /* TODO: read and configure CIS into memory mapped mode -+ * TODO: parse CISTPL_CONFIG on CF+ cards to get base address (0x200) -+ * TODO: maybe adjust power saving setting for Hitachi Microdrive -+ */ -+ int i; -+ -+ /* setup CFRDY GPIO as input */ -+ set_gpio_bit(0, FUNC, dev); -+ set_gpio_bit(0, CFG, dev); -+ -+ for (i = 0; i < 0x10; ++i) { -+ if (rareg(i,dev) != 0xff) -+ return 1; -+ } -+ return 0; -+} -+ -+static inline int is_busy(struct cf_mips_dev *dev) -+{ -+ return !cfrdy(dev); -+} -+ -+static int wait_not_busy(int to_us, int wait_for_busy,struct cf_mips_dev *dev) -+{ -+ int us_passed = 0; -+ if (wait_for_busy && !is_busy(dev)) { -+ /* busy must appear within 400ns, -+ * but it may dissapear before we see it -+ * => must not wait for busy in a loop -+ */ -+ ndelay(400); -+ } -+ -+ do { -+ if (us_passed) -+ udelay(1); /* never reached in async mode */ -+ if (!is_busy(dev)) { -+ if (us_passed > 1 * SECS) { -+ printk(KERN_WARNING "cf-mips: not busy ok (after %dus)" -+ ", status 0x%02x\n", us_passed, (unsigned) rareg(ATA_REG_ST,dev)); -+ } -+ return CF_TRANS_OK; -+ } -+ if (us_passed == 1 * SECS) { -+ printk(KERN_WARNING "cf-mips: wait not busy %dus..\n", to_us); -+ } -+ if (dev->async_mode) { -+ dev->to_timer.expires = jiffies + (to_us * HZ / SECS); -+ dev->irq_enable_time = jiffies; -+ prepare_cf_irq(dev); -+ if (is_busy(dev)) { -+ add_timer(&dev->to_timer); -+ enable_irq(dev->irq); -+ return CF_TRANS_IN_PROGRESS; -+ } -+ continue; -+ } -+ ++us_passed; -+ } while (us_passed < to_us); -+ -+ printk(KERN_ERR "cf-mips: wait not busy timeout (%dus)" -+ ", status 0x%02x, state %d\n", -+ to_us, (unsigned) rareg(ATA_REG_ST,dev), dev->tstate); -+ return CF_TRANS_FAILED; -+} -+ -+static irqreturn_t cf_irq_handler(int irq, void *dev_id) -+{ -+ /* While tasklet has not disabled irq, irq will be retried all the time -+ * because of ILEVEL matching GPIO pin status => deadlock. -+ * To avoid this, we change ILEVEL to 0. -+ */ -+ struct cf_mips_dev *dev=dev_id; -+ -+ set_gpio_bit(0, ILEVEL, dev); -+ set_gpio_bit(0, ISTAT, dev); -+ -+ del_timer(&dev->to_timer); -+ tasklet_schedule(&dev->tasklet); -+ return IRQ_HANDLED; -+} -+ -+static int do_reset(struct cf_mips_dev *dev) -+{ -+ printk(KERN_INFO "cf-mips: resetting..\n"); -+ -+ wareg(ATA_REG_DC_SRST, ATA_REG_DC,dev); -+ udelay(1); /* FIXME: how long should we wait here? */ -+ wareg(0, ATA_REG_DC,dev); -+ -+ return wait_not_busy(30 * SECS, 1,dev); -+} -+ -+static int set_multiple(struct cf_mips_dev *dev) -+{ -+ if (dev->block_size <= 1) -+ return CF_TRANS_OK; -+ -+ wareg(dev->block_size, ATA_REG_SC,dev); -+ wareg(ATA_REG_DH_BASE | ATA_REG_DH_LBA, ATA_REG_DH,dev); -+ wareg(ATA_CMD_SET_MULTIPLE, ATA_REG_CMD,dev); -+ -+ return wait_not_busy(10 * SECS, 1,dev); -+} -+ -+static int set_cmd(struct cf_mips_dev *dev) -+{ -+ //DEBUGP(KERN_INFO "cf-mips: ata cmd 0x%02x\n", dev->tcmd); -+ // sector_count should be <=24 bits.. -+ BUG_ON(dev->tsect_start>=0x10000000); -+ // This way, it addresses 2^24 * 512 = 128G -+ -+ if (dev->tsector_count) { -+ wareg(dev->tsector_count & 0xff, ATA_REG_SC,dev); -+ wareg(dev->tsect_start & 0xff, ATA_REG_SN,dev); -+ wareg((dev->tsect_start >> 8) & 0xff, ATA_REG_CL,dev); -+ wareg((dev->tsect_start >> 16) & 0xff, ATA_REG_CH,dev); -+ } -+ wareg(((dev->tsect_start >> 24) & 0x0f) | ATA_REG_DH_BASE | ATA_REG_DH_LBA, -+ ATA_REG_DH,dev); /* select drive on all commands */ -+ wareg(dev->tcmd, ATA_REG_CMD,dev); -+ return wait_not_busy(10 * SECS, 1,dev); -+} -+ -+static int do_trans(struct cf_mips_dev *dev) -+{ -+ int res; -+ unsigned st; -+ int transfered; -+ -+ //printk("do_trans: %d sectors left\n",dev->tsectors_left); -+ while (dev->tsectors_left) { -+ transfered = 0; -+ -+ st = rareg(ATA_REG_ST,dev); -+ if (!(st & ATA_REG_ST_DRQ)) { -+ printk(KERN_ERR "cf-mips: do_trans without DRQ (status 0x%x)!\n", st); -+ if (st & ATA_REG_ST_ERR) { -+ int errId = rareg(ATA_REG_ERR,dev); -+ printk(KERN_ERR "cf-mips: %s error, status 0x%x, errid 0x%x\n", -+ (dev->tread ? "read" : "write"), st, errId); -+ } -+ return CF_TRANS_FAILED; -+ } -+ do { /* Fill/read the buffer one block */ -+ u32 *qbuf, *qend; -+ qbuf = (u32 *)dev->tbuf; -+ qend = qbuf + CF_SECT_SIZE / sizeof(u32); -+ if (dev->tread) { -+ while (qbuf!=qend) -+ put_unaligned(*DBUF32,qbuf++); -+ //*(qbuf++) = *DBUF32; -+ } -+ else { -+ while(qbuf!=qend) -+ *DBUF32 = get_unaligned(qbuf++); -+ } -+ -+ dev->tsectors_left--; -+ dev->tbuf += CF_SECT_SIZE; -+ dev->tbuf_size -= CF_SECT_SIZE; -+ transfered++; -+ } while (transfered != dev->block_size && dev->tsectors_left > 0); -+ -+ res = wait_not_busy(10 * SECS, 1,dev); -+ if (res != CF_TRANS_OK) -+ return res; -+ }; -+ -+ st = rareg(ATA_REG_ST,dev); -+ if (st & (ATA_REG_ST_DRQ | ATA_REG_ST_DWF | ATA_REG_ST_ERR)) { -+ if (st & ATA_REG_ST_DRQ) { -+ printk(KERN_ERR "cf-mips: DRQ after all %d sectors are %s" -+ ", status 0x%x\n", dev->tsector_count, (dev->tread ? "read" : "written"), st); -+ } else if (st & ATA_REG_ST_DWF) { -+ printk(KERN_ERR "cf-mips: write fault, status 0x%x\n", st); -+ } else { -+ int errId = rareg(ATA_REG_ERR,dev); -+ printk(KERN_ERR "cf-mips: %s error, status 0x%x, errid 0x%x\n", -+ (dev->tread ? "read" : "write"), st, errId); -+ } -+ return CF_TRANS_FAILED; -+ } -+ return CF_TRANS_OK; -+} -+ -+static int cf_do_state(struct cf_mips_dev *dev) -+{ -+ int res; -+ switch (dev->tstate) { /* fall through everywhere */ -+ case TS_IDLE: -+ dev->tstate = TS_READY; -+ if (is_busy(dev)) { -+ dev->tstate = TS_AFTER_RESET; -+ res = do_reset(dev); -+ if (res != CF_TRANS_OK) -+ break; -+ } -+ case TS_AFTER_RESET: -+ if (dev->tstate == TS_AFTER_RESET) { -+ dev->tstate = TS_READY; -+ res = set_multiple(dev); -+ if (res != CF_TRANS_OK) -+ break; -+ } -+ case TS_READY: -+ dev->tstate = TS_CMD; -+ res = set_cmd(dev); -+ if (res != CF_TRANS_OK) -+ break;; -+ case TS_CMD: -+ dev->tstate = TS_TRANS; -+ case TS_TRANS: -+ res = do_trans(dev); -+ break; -+ default: -+ printk(KERN_ERR "cf-mips: BUG: unknown tstate %d\n", dev->tstate); -+ return CF_TRANS_FAILED; -+ } -+ if (res != CF_TRANS_IN_PROGRESS) -+ dev->tstate = TS_IDLE; -+ return res; -+} -+ -+static void cf_do_tasklet(unsigned long dev_l) -+{ -+ struct cf_mips_dev* dev=(struct cf_mips_dev*) dev_l; -+ int res; -+ -+ disable_irq(dev->irq); -+ -+ if (dev->tstate == TS_IDLE) -+ return; /* can happen when irq is first registered */ -+ -+#if 0 -+ DEBUGP(KERN_WARNING "cf-mips: not busy ok (tasklet) status 0x%02x\n", -+ (unsigned) rareg(ATA_REG_ST,dev)); -+#endif -+ -+ res = cf_do_state(dev); -+ if (res == CF_TRANS_IN_PROGRESS) -+ return; -+ cf_async_trans_done(dev,res); -+} -+ -+static void cf_async_timeout(unsigned long dev_l) -+{ -+ struct cf_mips_dev* dev=(struct cf_mips_dev*) dev_l; -+ disable_irq(dev->irq); -+ /* Perhaps send abort to the device? */ -+ printk(KERN_ERR "cf-mips: wait not busy timeout (%lus)" -+ ", status 0x%02x, state %d\n", -+ jiffies - dev->irq_enable_time, (unsigned) rareg(ATA_REG_ST,dev), dev->tstate); -+ dev->tstate = TS_IDLE; -+ cf_async_trans_done(dev,CF_TRANS_FAILED); -+} -+ -+int cf_do_transfer(struct cf_mips_dev* dev,sector_t sector, unsigned long nsect, -+ char* buffer, int is_write) -+{ -+ BUG_ON(dev->tstate!=TS_IDLE); -+ if (nsect > ATA_MAX_SECT_PER_CMD) { -+ printk(KERN_WARNING "cf-mips: sector count %lu out of range\n",nsect); -+ return CF_TRANS_FAILED; -+ } -+ if (sector + nsect > dev->sectors) { -+ printk(KERN_WARNING "cf-mips: sector %lu out of range\n",sector); -+ return CF_TRANS_FAILED; -+ } -+ dev->tbuf = buffer; -+ dev->tbuf_size = nsect*512; -+ dev->tsect_start = sector; -+ dev->tsector_count = nsect; -+ dev->tsectors_left = dev->tsector_count; -+ dev->tread = (is_write)?0:1; -+ -+ dev->tcmd = (dev->block_size == 1 ? -+ (is_write ? ATA_CMD_WRITE_SECTORS : ATA_CMD_READ_SECTORS) : -+ (is_write ? ATA_CMD_WRITE_MULTIPLE : ATA_CMD_READ_MULTIPLE)); -+ -+ return cf_do_state(dev); -+} -+ -+static int do_identify(struct cf_mips_dev *dev) -+{ -+ u16 sbuf[CF_SECT_SIZE >> 1]; -+ int res; -+ char tstr[17]; //serial -+ BUG_ON(dev->tstate!=TS_IDLE); -+ dev->tbuf = (char *) sbuf; -+ dev->tbuf_size = CF_SECT_SIZE; -+ dev->tsect_start = 0; -+ dev->tsector_count = 0; -+ dev->tsectors_left = 1; -+ dev->tread = 1; -+ dev->tcmd = ATA_CMD_IDENTIFY_DRIVE; -+ -+ DEBUGP(KERN_INFO "cf-mips: identify drive..\n"); -+ res = cf_do_state(dev); -+ if (res == CF_TRANS_IN_PROGRESS) { -+ printk(KERN_ERR "cf-mips: BUG: async identify cmd\n"); -+ return CF_TRANS_FAILED; -+ } -+ if (res != CF_TRANS_OK) -+ return 0; -+ -+ dev->head = sbuf[3]; -+ dev->cyl = sbuf[1]; -+ dev->spt = sbuf[6]; -+ dev->sectors = ((unsigned long) sbuf[7] << 16) | sbuf[8]; -+ dev->dtype=sbuf[0]; -+ memcpy(tstr,&sbuf[12],16); -+ tstr[16]=0; -+ printk(KERN_INFO "cf-mips: %s detected, C/H/S=%d/%d/%d sectors=%u (%uMB) Serial=%s\n", -+ (sbuf[0] == 0x848A ? "CF card" : "ATA drive"), dev->cyl, dev->head, -+ dev->spt, dev->sectors, dev->sectors >> 11,tstr); -+ return 1; -+} -+ -+static void init_multiple(struct cf_mips_dev * dev) -+{ -+ int res; -+ DEBUGP(KERN_INFO "cf-mips: detecting block size\n"); -+ -+ dev->block_size = 128; /* max block size = 128 sectors (64KB) */ -+ do { -+ wareg(dev->block_size, ATA_REG_SC,dev); -+ wareg(ATA_REG_DH_BASE | ATA_REG_DH_LBA, ATA_REG_DH,dev); -+ wareg(ATA_CMD_SET_MULTIPLE, ATA_REG_CMD,dev); -+ -+ res = wait_not_busy(10 * SECS, 1,dev); -+ if (res != CF_TRANS_OK) { -+ printk(KERN_ERR "cf-mips: failed to detect block size: busy!\n"); -+ dev->block_size = 1; -+ return; -+ } -+ if ((rareg(ATA_REG_ST,dev) & ATA_REG_ST_ERR) == 0) -+ break; -+ dev->block_size /= 2; -+ } while (dev->block_size > 1); -+ -+ printk(KERN_INFO "cf-mips: multiple sectors = %d\n", dev->block_size); -+} -+ -+int cf_init(struct cf_mips_dev *dev) -+{ -+ tasklet_init(&dev->tasklet,cf_do_tasklet,(unsigned long)dev); -+ dev->baddr = ioremap_nocache((unsigned long)dev->base, CFDEV_BUF_SIZE); -+ if (!dev->baddr) { -+ printk(KERN_ERR "cf-mips: cf_init: ioremap for (%lx,%x) failed\n", -+ (unsigned long) dev->base, CFDEV_BUF_SIZE); -+ return -EBUSY; -+ } -+ -+ if (!cf_present(dev)) { -+ printk(KERN_WARNING "cf-mips: cf card not present\n"); -+ iounmap(dev->baddr); -+ return -ENODEV; -+ } -+ -+ if (do_reset(dev) != CF_TRANS_OK) { -+ printk(KERN_ERR "cf-mips: cf reset failed\n"); -+ iounmap(dev->baddr); -+ return -EBUSY; -+ } -+ -+ if (!do_identify(dev)) { -+ printk(KERN_ERR "cf-mips: cf identify failed\n"); -+ iounmap(dev->baddr); -+ return -EBUSY; -+ } -+ -+/* set_apm_level(ATA_APM_WITH_STANDBY); */ -+ init_multiple(dev); -+ -+ init_timer(&dev->to_timer); -+ dev->to_timer.function = cf_async_timeout; -+ dev->to_timer.data = (unsigned long)dev; -+ -+ prepare_cf_irq(dev); -+ if (request_irq(dev->irq, cf_irq_handler, 0, "CF Mips", dev)) { -+ printk(KERN_ERR "cf-mips: failed to get irq\n"); -+ iounmap(dev->baddr); -+ return -EBUSY; -+ } -+ /* Disable below would be odd, because request will enable, and the tasklet -+ will disable it itself */ -+ //disable_irq(dev->irq); -+ -+ dev->async_mode = 1; -+ -+ return 0; -+} -+ -+void cf_cleanup(struct cf_mips_dev *dev) -+{ -+ iounmap(dev->baddr); -+ free_irq(dev->irq, NULL); -+#if REQUEST_MEM_REGION -+ release_mem_region((unsigned long)dev->base, CFDEV_BUF_SIZE); -+#endif -+} -+ -+ -+/*eof*/ -diff -urN linux.old/drivers/block/rb500/ata.h linux.dev/drivers/block/rb500/ata.h ---- linux.old/drivers/block/rb500/ata.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/block/rb500/ata.h 2006-10-26 00:11:14.000000000 +0200 -@@ -0,0 +1,143 @@ -+/* CF-mips driver -+ This is a block driver for the direct (mmaped) interface to the CF-slot, -+ found in Routerboard.com's RB532 board -+ See SDK provided from routerboard.com. -+ -+ Module adapted By P.Christeas <p_christeas@yahoo.com>, 2005-6. -+ Cleaned up and adapted to platform_device by Felix Fietkau <nbd@openwrt.org> -+ -+ This work is redistributed under the terms of the GNU General Public License. -+*/ -+ -+#ifndef __CFMIPS_ATA_H__ -+#define __CFMIPS_ATA_H__ -+ -+#include <linux/interrupt.h> -+ -+#define CFG_DC_DEV1 (void*)0xb8010010 -+#define CFG_DC_DEVBASE 0x0 -+#define CFG_DC_DEVMASK 0x4 -+#define CFG_DC_DEVC 0x8 -+#define CFG_DC_DEVTC 0xC -+ -+#define CFDEV_BUF_SIZE 0x1000 -+#define ATA_CIS_OFFSET 0x200 -+#define ATA_REG_OFFSET 0x800 -+#define ATA_DBUF_OFFSET 0xC00 -+ -+#define ATA_REG_FEAT 0x1 -+#define ATA_REG_SC 0x2 -+#define ATA_REG_SN 0x3 -+#define ATA_REG_CL 0x4 -+#define ATA_REG_CH 0x5 -+#define ATA_REG_DH 0x6 -+#define ATA_REG_DH_BASE 0xa0 -+#define ATA_REG_DH_LBA 0x40 -+#define ATA_REG_DH_DRV 0x10 -+#define ATA_REG_CMD 0x7 -+#define ATA_REG_ST 0x7 -+#define ATA_REG_ST_BUSY 0x80 -+#define ATA_REG_ST_RDY 0x40 -+#define ATA_REG_ST_DWF 0x20 -+#define ATA_REG_ST_DSC 0x10 -+#define ATA_REG_ST_DRQ 0x08 -+#define ATA_REG_ST_CORR 0x04 -+#define ATA_REG_ST_ERR 0x01 -+#define ATA_REG_ERR 0xd -+#define ATA_REG_DC 0xe -+#define ATA_REG_DC_IEN 0x02 -+#define ATA_REG_DC_SRST 0x04 -+ -+#define ATA_CMD_READ_SECTORS 0x20 -+#define ATA_CMD_WRITE_SECTORS 0x30 -+#define ATA_CMD_EXEC_DRIVE_DIAG 0x90 -+#define ATA_CMD_READ_MULTIPLE 0xC4 -+#define ATA_CMD_WRITE_MULTIPLE 0xC5 -+#define ATA_CMD_SET_MULTIPLE 0xC6 -+#define ATA_CMD_IDENTIFY_DRIVE 0xEC -+#define ATA_CMD_SET_FEATURES 0xEF -+ -+#define ATA_FEATURE_ENABLE_APM 0x05 -+#define ATA_FEATURE_DISABLE_APM 0x85 -+#define ATA_APM_DISABLED 0x00 -+#define ATA_APM_MIN_POWER 0x01 -+#define ATA_APM_WITH_STANDBY 0x7f -+#define ATA_APM_WITHOUT_STANDBY 0x80 -+#define ATA_APM_MAX_PERFORMANCE 0xfe -+ -+#define CF_SECT_SIZE 0x200 -+/* That is the ratio CF_SECT_SIZE/512 (the kernel sector size) */ -+#define CF_KERNEL_MUL 1 -+#define ATA_MAX_SECT_PER_CMD 0x100 -+ -+#define CF_TRANS_FAILED 0 -+#define CF_TRANS_OK 1 -+#define CF_TRANS_IN_PROGRESS 2 -+ -+ -+enum trans_state { -+ TS_IDLE = 0, -+ TS_AFTER_RESET, -+ TS_READY, -+ TS_CMD, -+ TS_TRANS -+}; -+ -+// -+// #if DEBUG -+// static unsigned long busy_time; -+// #endif -+ -+/** Struct to hold the cfdev -+Actually, all the data here only has one instance. However, for -+reasons of programming conformity, it is passed around as a pointer -+*/ -+struct cf_mips_dev { -+ void *base; /* base address for I/O */ -+ void *baddr; /* remapped address */ -+ -+ int pin; /* gpio pin */ -+ int irq; /* gpio irq */ -+ -+ unsigned head; -+ unsigned cyl; -+ unsigned spt; -+ unsigned sectors; -+ -+ unsigned short block_size; -+ unsigned dtype ; // ATA or CF -+ struct request_queue *queue; -+ struct gendisk *gd; -+ -+ /* Transaction state */ -+ enum trans_state tstate; -+ char *tbuf; -+ unsigned long tbuf_size; -+ sector_t tsect_start; -+ unsigned tsector_count; -+ unsigned tsectors_left; -+ int tread; -+ unsigned tcmd; -+ int async_mode; -+ unsigned long irq_enable_time; -+ -+ struct request *active_req; /* A request is being carried out. Is that different from tstate? */ -+ int users; -+ struct timer_list to_timer; -+ struct tasklet_struct tasklet; -+ -+ /** This lock ensures that the requests to this device are all done -+ atomically. Transfers can run in parallel, requests are all queued -+ one-by-one */ -+ spinlock_t lock; -+}; -+ -+int cf_do_transfer(struct cf_mips_dev* dev,sector_t sector, unsigned long nsect, -+ char* buffer, int is_write); -+int cf_init(struct cf_mips_dev* dev); -+void cf_cleanup(struct cf_mips_dev* dev); -+ -+void cf_async_trans_done(struct cf_mips_dev* dev, int result); -+// void *cf_get_next_buf(unsigned long *buf_size); -+ -+#endif -diff -urN linux.old/drivers/block/rb500/bdev.c linux.dev/drivers/block/rb500/bdev.c ---- linux.old/drivers/block/rb500/bdev.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/block/rb500/bdev.c 2006-10-26 00:11:14.000000000 +0200 -@@ -0,0 +1,339 @@ -+/* CF-mips driver -+ This is a block driver for the direct (mmaped) interface to the CF-slot, -+ found in Routerboard.com's RB532 board -+ See SDK provided from routerboard.com. -+ -+ Module adapted By P.Christeas <p_christeas@yahoo.com>, 2005-6. -+ Cleaned up and adapted to platform_device by Felix Fietkau <nbd@openwrt.org> -+ -+ This work is redistributed under the terms of the GNU General Public License. -+*/ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/time.h> -+#include <linux/wait.h> -+#include <linux/fs.h> -+#include <linux/genhd.h> -+#include <linux/blkdev.h> -+#include <linux/blkpg.h> -+#include <linux/hdreg.h> -+#include <linux/platform_device.h> -+ -+#include <asm/uaccess.h> -+#include <asm/io.h> -+ -+#include <asm/rc32434/rb.h> -+ -+#ifdef DEBUG -+#define DEBUGP printk -+#define DLEVEL 1 -+#else -+#define DEBUGP(format, args...) -+#define DLEVEL 0 -+#endif -+ -+#define CF_MIPS_MAJOR 13 -+#define MAJOR_NR CF_MIPS_MAJOR -+#define CF_MAX_PART 16 /* max 15 partitions */ -+ -+#include "ata.h" -+ -+//extern struct block_device_operations cf_bdops; -+ -+// static struct hd_struct cf_parts[CF_MAX_PART]; -+// static int cf_part_sizes[CF_MAX_PART]; -+// static int cf_hsect_sizes[CF_MAX_PART]; -+// static int cf_max_sectors[CF_MAX_PART]; -+// static int cf_blksize_sizes[CF_MAX_PART]; -+ -+// static spinlock_t lock = SPIN_LOCK_UNLOCKED; -+ -+// volatile int cf_busy = 0; -+ -+static struct request *active_req = NULL; -+ -+static int cf_open (struct inode *, struct file *); -+static int cf_release (struct inode *, struct file *); -+static int cf_ioctl (struct inode *, struct file *, unsigned, unsigned long); -+ -+static void cf_request(request_queue_t * q); -+static int cf_transfer(const struct request *req); -+ -+/*long (*unlocked_ioctl) (struct file *, unsigned, unsigned long); -+long (*compat_ioctl) (struct file *, unsigned, unsigned long);*/ -+// int (*direct_access) (struct block_device *, sector_t, unsigned long *); -+// int (*media_changed) (struct gendisk *); -+// int (*revalidate_disk) (struct gendisk *); -+ -+static struct block_device_operations cf_bdops = { -+ .owner = THIS_MODULE, -+ .open = cf_open, -+ .release = cf_release, -+ .ioctl = cf_ioctl, -+ .media_changed = NULL, -+ .unlocked_ioctl = NULL, -+ .revalidate_disk = NULL, -+ .compat_ioctl = NULL, -+ .direct_access = NULL -+}; -+ -+ -+int cf_mips_probe(struct platform_device *pdev) -+{ -+ struct gendisk* cf_gendisk=NULL; -+ struct cf_device *cdev = (struct cf_device *) pdev->dev.platform_data; -+ struct cf_mips_dev *dev; -+ struct resource *r; -+ int reg_result; -+ -+ reg_result = register_blkdev(MAJOR_NR, "cf-mips"); -+ if (reg_result < 0) { -+ printk(KERN_WARNING "cf-mips: can't get major %d\n", MAJOR_NR); -+ return reg_result; -+ } -+ -+ dev = (struct cf_mips_dev *)kmalloc(sizeof(struct cf_mips_dev),GFP_KERNEL); -+ if (!dev) -+ goto out_err; -+ memset(dev, 0, sizeof(struct cf_mips_dev)); -+ cdev->dev = dev; -+ -+ dev->pin = cdev->gpio_pin; -+ dev->irq = platform_get_irq_byname(pdev, "cf_irq"); -+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cf_membase"); -+ dev->base = (void *) r->start; -+ -+ if (cf_init(dev)) goto out_err; -+ printk("init done"); -+ -+ spin_lock_init(&dev->lock); -+ dev->queue = blk_init_queue(cf_request,&dev->lock); -+ if (!dev->queue){ -+ printk(KERN_ERR "cf-mips: no mem for queue\n"); -+ goto out_err; -+ } -+ blk_queue_max_sectors(dev->queue,ATA_MAX_SECT_PER_CMD); -+ -+ /* For memory devices, it is always better to avoid crossing segments -+ inside the same request. */ -+/* if (dev->dtype==0x848A){ -+ printk(KERN_INFO "Setting boundary for cf to 0x%x",(dev->block_size*512)-1); -+ blk_queue_segment_boundary(dev->queue, (dev->block_size*512)-1); -+ }*/ -+ -+ dev->gd = alloc_disk(CF_MAX_PART); -+ cf_gendisk = dev->gd; -+ cdev->gd = dev->gd; -+ if (!cf_gendisk) goto out_err; /* Last of these goto's */ -+ -+ cf_gendisk->major = MAJOR_NR; -+ cf_gendisk->first_minor = 0; -+ cf_gendisk->queue=dev->queue; -+ BUG_ON(cf_gendisk->minors != CF_MAX_PART); -+ strcpy(cf_gendisk->disk_name,"cfa"); -+ cf_gendisk->fops = &cf_bdops; -+ cf_gendisk->flags = 0 ; /* is not yet GENHD_FL_REMOVABLE */ -+ cf_gendisk->private_data=dev; -+ -+ set_capacity(cf_gendisk,dev->sectors * CF_KERNEL_MUL); -+ -+ /* Let the disk go live */ -+ add_disk(cf_gendisk); -+#if 0 -+ result = cf_init(); -+ -+ /* default cfg for all partitions */ -+ memset(cf_parts, 0, sizeof (cf_parts[0]) * CF_MAX_PART); -+ memset(cf_part_sizes, 0, sizeof (cf_part_sizes[0]) * CF_MAX_PART); -+ for (i = 0; i < CF_MAX_PART; ++i) { -+ cf_hsect_sizes[i] = CF_SECT_SIZE; -+ cf_max_sectors[i] = ATA_MAX_SECT_PER_CMD; -+ cf_blksize_sizes[i] = BLOCK_SIZE; -+ } -+ -+ /* setup info for whole disk (partition 0) */ -+ cf_part_sizes[0] = cf_sectors / 2; -+ cf_parts[0].nr_sects = cf_sectors; -+ -+ blk_size[MAJOR_NR] = cf_part_sizes; -+ blksize_size[MAJOR_NR] = cf_blksize_sizes; -+ max_sectors[MAJOR_NR] = cf_max_sectors; -+ hardsect_size[MAJOR_NR] = cf_hsect_sizes; -+ read_ahead[MAJOR_NR] = 8; /* (4kB) */ -+ -+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); -+ -+ add_gendisk(&cf_gendisk); -+#endif -+// printk(KERN_INFO "cf-mips partition check: \n"); -+// register_disk(cf_gendisk, MKDEV(MAJOR_NR, 0), CF_MAX_PART, -+// &cf_bdops, dev->sectors); -+ return 0; -+ -+out_err: -+ if (dev->queue){ -+ blk_cleanup_queue(dev->queue); -+ } -+ if (reg_result) { -+ unregister_blkdev(MAJOR_NR, "cf-mips"); -+ return reg_result; -+ } -+ if (dev){ -+ cf_cleanup(dev); -+ kfree(dev); -+ } -+ return 1; -+} -+ -+static int -+cf_mips_remove(struct platform_device *pdev) -+{ -+ struct cf_device *cdev = (struct cf_device *) pdev->dev.platform_data; -+ struct cf_mips_dev *dev = (struct cf_mips_dev *) cdev->dev; -+ -+ unregister_blkdev(MAJOR_NR, "cf-mips"); -+ blk_cleanup_queue(dev->queue); -+ -+ del_gendisk(dev->gd); -+ cf_cleanup(dev); -+ return 0; -+} -+ -+ -+static struct platform_driver cf_driver = { -+ .driver.name = "rb500-cf", -+ .probe = cf_mips_probe, -+ .remove = cf_mips_remove, -+}; -+ -+static int __init cf_mips_init(void) -+{ -+ printk(KERN_INFO "cf-mips module loaded\n"); -+ return platform_driver_register(&cf_driver); -+} -+ -+static void cf_mips_cleanup(void) -+{ -+ platform_driver_unregister(&cf_driver); -+ printk(KERN_INFO "cf-mips module removed\n"); -+} -+ -+module_init(cf_mips_init); -+module_exit(cf_mips_cleanup); -+ -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS_BLOCKDEV_MAJOR(CF_MIPS_MAJOR); -+ -+ -+static int cf_open(struct inode *inode, struct file *filp) -+{ -+ struct cf_mips_dev *dev=inode->i_bdev->bd_disk->private_data; -+ int minor = MINOR(inode->i_rdev); -+ -+ if (minor >= CF_MAX_PART) -+ return -ENODEV; -+ //DEBUGP(KERN_INFO "cf-mips module opened, minor %d\n", minor); -+ spin_lock(&dev->lock); -+ dev->users++; -+ spin_unlock(&dev->lock); -+ filp->private_data=dev; -+ -+ /* dirty workaround to set CFRDY GPIO as an input when some other -+ program sets it as an output */ -+ gpio_set(CFG, (1 << dev->pin), 0); -+ return 0; /* success */ -+} -+ -+static int cf_release(struct inode *inode, struct file *filp) -+{ -+ int minor = MINOR(inode->i_rdev); -+ struct cf_mips_dev *dev=inode->i_bdev->bd_disk->private_data; -+ spin_lock(&dev->lock); -+ dev->users--; -+ spin_unlock(&dev->lock); -+ return 0; -+} -+ -+static int cf_ioctl(struct inode *inode, struct file *filp, -+ unsigned int cmd, unsigned long arg) -+{ -+ unsigned minor = MINOR(inode->i_rdev); -+ struct cf_mips_dev *dev=inode->i_bdev->bd_disk->private_data; -+ -+ DEBUGP(KERN_INFO "cf_ioctl cmd %u\n", cmd); -+ switch (cmd) { -+ case BLKRRPART: /* re-read partition table */ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ printk(KERN_INFO "cf-mips partition check: \n"); -+ register_disk(dev->gd); -+ return 0; -+ -+ case HDIO_GETGEO: -+ { -+ struct hd_geometry geo; -+ geo.cylinders = dev->cyl; -+ geo.heads = dev->head; -+ geo.sectors = dev->spt; -+ geo.start = (*dev->gd->part)[minor].start_sect; -+ if (copy_to_user((void *) arg, &geo, sizeof (geo))) -+ return -EFAULT; -+ } -+ return 0; -+ } -+ -+ return -EINVAL; /* unknown command */ -+} -+ -+static void cf_request(request_queue_t * q) -+{ -+ struct cf_mips_dev* dev; -+ -+ struct request * req; -+ int status; -+ -+ /* We could have q->queuedata = dev , but haven't yet. */ -+ if (active_req) -+ return; -+ -+ while ((req=elv_next_request(q))!=NULL){ -+ dev=req->rq_disk->private_data; -+ status=cf_transfer(req); -+ if (status==CF_TRANS_IN_PROGRESS){ -+ active_req=req; -+ return; -+ } -+ end_request(req,status); -+ } -+} -+ -+static int cf_transfer(const struct request *req) -+{ -+ struct cf_mips_dev* dev=req->rq_disk->private_data; -+ -+ if (!blk_fs_request(req)){ -+ if (printk_ratelimit()) -+ printk(KERN_WARNING "cf-mips: skipping non-fs request 0x%x\n",req->cmd[0]); -+ return CF_TRANS_FAILED; -+ } -+ -+ return cf_do_transfer(dev,req->sector,req->current_nr_sectors,req->buffer,rq_data_dir(req)); -+} -+ -+void cf_async_trans_done(struct cf_mips_dev * dev,int result) -+{ -+ struct request *req; -+ -+ spin_lock(&dev->lock); -+ req=active_req; -+ active_req=NULL; -+ end_request(req,result); -+ spin_unlock(&dev->lock); -+ -+ spin_lock(&dev->lock); -+ cf_request(dev->queue); -+ spin_unlock(&dev->lock); -+} -+ -diff -urN linux.old/drivers/block/rb500/Makefile linux.dev/drivers/block/rb500/Makefile ---- linux.old/drivers/block/rb500/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/block/rb500/Makefile 2006-10-26 00:11:14.000000000 +0200 -@@ -0,0 +1,3 @@ -+## Makefile for the RB532 CF port -+ -+obj-y += bdev.o ata.o + diff --git a/target/linux/rb532-2.6/patches/140-cmdline_hack.patch b/target/linux/rb532-2.6/patches/140-cmdline_hack.patch index 01daf3132..50c299a65 100644 --- a/target/linux/rb532-2.6/patches/140-cmdline_hack.patch +++ b/target/linux/rb532-2.6/patches/140-cmdline_hack.patch @@ -25,24 +25,4 @@ diff -ur linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S EXPORT(stext) # used for profiling EXPORT(_stext) -diff -ur linux.old/arch/mips/rb500/prom.c linux.dev/arch/mips/rb500/prom.c ---- linux.old/arch/mips/rb500/prom.c 2006-12-06 17:30:27.000000000 +0100 -+++ linux.dev/arch/mips/rb500/prom.c 2006-12-06 17:41:40.000000000 +0100 -@@ -128,6 +128,7 @@ - /* FIXME: STUB */ - } - -+extern char _image_cmdline; - void __init prom_setup_cmdline(void){ - char cmd_line[CL_SIZE]; - char *cp; -@@ -163,6 +164,9 @@ - strcpy(cp,prom_argv[i]); - cp+=strlen(prom_argv[i]); - } -+ *(cp++) = ' '; -+ strcpy(cp,(&_image_cmdline + 8)); -+ cp += strlen(&_image_cmdline); - - i=strlen(arcs_cmdline); - if (i>0){ + diff --git a/target/linux/rb532-2.6/patches/500-Nand.patch b/target/linux/rb532-2.6/patches/500-Nand.patch index f3244817c..6189ecb8e 100644 --- a/target/linux/rb532-2.6/patches/500-Nand.patch +++ b/target/linux/rb532-2.6/patches/500-Nand.patch @@ -25,144 +25,4 @@ diff -urN linux.old/drivers/mtd/nand/Makefile linux.dev/drivers/mtd/nand/Makefil obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o -diff -urN linux.old/drivers/mtd/nand/rbmipsnand.c linux.dev/drivers/mtd/nand/rbmipsnand.c ---- linux.old/drivers/mtd/nand/rbmipsnand.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/mtd/nand/rbmipsnand.c 2006-12-14 04:39:52.000000000 +0100 -@@ -0,0 +1,137 @@ -+#include <linux/init.h> -+#include <linux/mtd/nand.h> -+#include <linux/mtd/mtd.h> -+#include <linux/mtd/partitions.h> -+#include <linux/delay.h> -+#include <asm/io.h> -+#include <asm/irq.h> -+#include <asm/bootinfo.h> -+ -+#define IDT434_REG_BASE ((volatile void *) KSEG1ADDR(0x18000000)) -+ -+#define GPIOF 0x050000 -+#define GPIOC 0x050004 -+#define GPIOD 0x050008 -+ -+#define GPIO_RDY (1 << 0x08) -+#define GPIO_WPX (1 << 0x09) -+#define GPIO_ALE (1 << 0x0a) -+#define GPIO_CLE (1 << 0x0b) -+ -+#define DEV2BASE 0x010020 -+ -+#define LO_WPX (1 << 0) -+#define LO_ALE (1 << 1) -+#define LO_CLE (1 << 2) -+#define LO_CEX (1 << 3) -+#define LO_FOFF (1 << 5) -+#define LO_SPICS (1 << 6) -+#define LO_ULED (1 << 7) -+ -+#define MEM32(x) *((volatile unsigned *) (x)) -+static void __iomem *p_nand; -+ -+extern void changeLatchU5(unsigned char orMask, unsigned char nandMask); -+ -+static int rb500_dev_ready(struct mtd_info *mtd) -+{ -+ return MEM32(IDT434_REG_BASE + GPIOD) & GPIO_RDY; -+} -+ -+/* -+ * hardware specific access to control-lines -+ * -+ * ctrl: -+ * NAND_CLE: bit 2 -> bit 3 -+ * NAND_ALE: bit 3 -> bit 2 -+ */ -+static void rbmips_hwcontrol500(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ struct nand_chip *chip = mtd->priv; -+ unsigned char orbits, nandbits; -+ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ -+ orbits = (ctrl & NAND_CLE) << 1; -+ orbits |= (ctrl & NAND_ALE) >> 1; -+ -+ nandbits = (~ctrl & NAND_CLE) << 1; -+ nandbits |= (~ctrl & NAND_ALE) >> 1; -+ -+ changeLatchU5(orbits, nandbits); -+ } -+ if (cmd != NAND_CMD_NONE) -+ writeb(cmd, chip->IO_ADDR_W); -+ -+} -+ -+static struct mtd_partition partition_info[] = { -+ { -+ name:"RouterBoard NAND Boot", -+ offset:0, -+ size:4 * 1024 * 1024}, -+ { -+ name:"RouterBoard NAND Main", -+ offset:MTDPART_OFS_NXTBLK, -+ size:MTDPART_SIZ_FULL} -+}; -+ -+static struct mtd_info rmtd; -+static struct nand_chip rnand; -+ -+static unsigned init_ok = 0; -+ -+unsigned get_rbnand_block_size(void) -+{ -+ if (init_ok) -+ return rmtd.writesize; -+ else -+ return 0; -+} -+ -+EXPORT_SYMBOL(get_rbnand_block_size); -+ -+int __init rbmips_init(void) -+{ -+ int *b; -+ memset(&rmtd, 0, sizeof(rmtd)); -+ memset(&rnand, 0, sizeof(rnand)); -+ -+ printk("RB500 nand\n"); -+ changeLatchU5(LO_WPX | LO_FOFF | LO_CEX, -+ LO_ULED | LO_ALE | LO_CLE); -+ rnand.cmd_ctrl = rbmips_hwcontrol500; -+ -+ rnand.dev_ready = rb500_dev_ready; -+ rnand.IO_ADDR_W = (unsigned char *) -+ KSEG1ADDR(MEM32(IDT434_REG_BASE + DEV2BASE)); -+ rnand.IO_ADDR_R = rnand.IO_ADDR_W; -+ -+ p_nand = (void __iomem *) ioremap((void *) 0x18a20000, 0x1000); -+ if (!p_nand) { -+ printk("RBnand Unable ioremap buffer"); -+ return -ENXIO; -+ } -+ rnand.ecc.mode = NAND_ECC_SOFT; -+ rnand.chip_delay = 25; -+ rnand.options |= NAND_NO_AUTOINCR; -+ rmtd.priv = &rnand; -+ -+ b = (int *) KSEG1ADDR(0x18010020); -+ printk("dev2base 0x%08x mask 0x%08x c 0x%08x tc 0x%08x\n", b[0], -+ b[1], b[2], b[3]); -+ -+ if (nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1) -+ && nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1)) { -+ printk("RBxxx nand device not found\n"); -+ iounmap((void *) p_nand); -+ return -ENXIO; -+ } -+ -+ add_mtd_partitions(&rmtd, partition_info, 2); -+ init_ok = 1; -+ return 0; -+} -+ -+module_init(rbmips_init); + |