Submitted By: Jim Gifford (patches at jg555 dot com) Date: 2007-02-24 Initial Package Version: 2.6.20.1 Origin: Linux-MIPS Upstream Status: http://www.linux-mips.org/pub/linux/mips/kernel/v2.6/ diff -Naur linux-2.6.20.1.orig/arch/mips/Kconfig linux-2.6.20.1/arch/mips/Kconfig --- linux-2.6.20.1.orig/arch/mips/Kconfig 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/Kconfig 2007-02-20 16:47:41.000000000 -0800 @@ -140,6 +140,7 @@ select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_KGDB help The eXcite is a smart camera platform manufactured by Basler Vision Technologies AG @@ -206,6 +207,7 @@ select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_KGDB help This is an evaluation board based on the Galileo GT-64120 single-chip system controller that contains a MIPS R5000 compatible @@ -370,6 +372,7 @@ select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_KGDB help The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by Momentum Computer . @@ -387,6 +390,7 @@ select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_KGDB help The Ocelot is a MIPS-based Single Board Computer (SBC) made by Momentum Computer . @@ -476,6 +480,7 @@ select SYS_HAS_CPU_R5432 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL + select SYS_SUPPORTS_KGDB select SYS_SUPPORTS_LITTLE_ENDIAN help This enables support for the R5432-based NEC DDB Vrc-5477, @@ -504,6 +509,7 @@ select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_KGDB select SYS_SUPPORTS_SMP help Yosemite is an evaluation board for the RM9000x2 processor @@ -579,6 +585,7 @@ select SYS_HAS_CPU_R10000 select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_KGDB select SYS_SUPPORTS_NUMA select SYS_SUPPORTS_SMP select GENERIC_HARDIRQS_NO__DO_IRQ @@ -628,6 +635,7 @@ select SYS_HAS_CPU_SB1 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_KGDB select SYS_SUPPORTS_LITTLE_ENDIAN config SIBYTE_SENTOSA @@ -762,6 +770,7 @@ select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_KGDB select TOSHIBA_BOARDS select GENERIC_HARDIRQS_NO__DO_IRQ help @@ -782,6 +791,7 @@ select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_KGDB select TOSHIBA_BOARDS select GENERIC_HARDIRQS_NO__DO_IRQ help @@ -965,6 +975,7 @@ config DDB5XXX_COMMON bool + select SYS_SUPPORTS_KGDB config MIPS_BOARDS_GEN bool @@ -1012,6 +1023,7 @@ bool select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_KGDB config PNX8550 bool @@ -1024,6 +1036,7 @@ select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL select GENERIC_HARDIRQS_NO__DO_IRQ + select SYS_SUPPORTS_KGDB config SWAP_IO_SPACE bool @@ -1199,7 +1212,7 @@ select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL help - The options selects support for the NEC VR4100 series of processors. + The options selects support for the NEC VR41xx series of processors. Only choose this option if you have one of these processors as a kernel built with this option will not run on any other type of processor or vice versa. diff -Naur linux-2.6.20.1.orig/arch/mips/Kconfig.debug linux-2.6.20.1/arch/mips/Kconfig.debug --- linux-2.6.20.1.orig/arch/mips/Kconfig.debug 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/Kconfig.debug 2007-02-20 16:47:41.000000000 -0800 @@ -22,10 +22,10 @@ string "Default kernel command string" default "" help - On some platforms, there is currently no way for the boot loader to - pass arguments to the kernel. For these platforms, you can supply - some command-line options at build time by entering them here. In - other cases you can specify kernel args so that you don't have + On some platforms, there is currently no way for the boot loader to + pass arguments to the kernel. For these platforms, you can supply + some command-line options at build time by entering them here. In + other cases you can specify kernel args so that you don't have to set them up in board prom initialization routines. config DEBUG_STACK_USAGE @@ -39,7 +39,7 @@ config KGDB bool "Remote GDB kernel debugging" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && SYS_SUPPORTS_KGDB select DEBUG_INFO help If you say Y here, it will be possible to remotely debug the MIPS @@ -48,6 +48,9 @@ better 32 MB RAM to avoid excessive linking time. This is only useful for kernel hackers. If unsure, say N. +config SYS_SUPPORTS_KGDB + bool + config GDB_CONSOLE bool "Console output to GDB" depends on KGDB diff -Naur linux-2.6.20.1.orig/arch/mips/au1000/common/pci.c linux-2.6.20.1/arch/mips/au1000/common/pci.c --- linux-2.6.20.1.orig/arch/mips/au1000/common/pci.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/au1000/common/pci.c 2007-02-20 16:47:41.000000000 -0800 @@ -76,13 +76,17 @@ } #ifdef CONFIG_DMA_NONCOHERENT - /* - * Set the NC bit in controller for Au1500 pre-AC silicon - */ - u32 prid = read_c0_prid(); - if ( (prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) { - au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG); - printk("Non-coherent PCI accesses enabled\n"); + { + /* + * Set the NC bit in controller for Au1500 pre-AC silicon + */ + u32 prid = read_c0_prid(); + + if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) { + au_writel((1 << 16) | au_readl(Au1500_PCI_CFG), + Au1500_PCI_CFG); + printk("Non-coherent PCI accesses enabled\n"); + } } #endif diff -Naur linux-2.6.20.1.orig/arch/mips/au1000/common/setup.c linux-2.6.20.1/arch/mips/au1000/common/setup.c --- linux-2.6.20.1.orig/arch/mips/au1000/common/setup.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/au1000/common/setup.c 2007-02-20 16:47:41.000000000 -0800 @@ -141,17 +141,20 @@ /* This routine should be valid for all Au1x based boards */ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) { - u32 start, end; - /* Don't fixup 36 bit addresses */ - if ((phys_addr >> 32) != 0) return phys_addr; + if ((phys_addr >> 32) != 0) + return phys_addr; #ifdef CONFIG_PCI - start = (u32)Au1500_PCI_MEM_START; - end = (u32)Au1500_PCI_MEM_END; - /* check for pci memory window */ - if ((phys_addr >= start) && ((phys_addr + size) < end)) { - return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START); + { + u32 start, end; + + start = (u32)Au1500_PCI_MEM_START; + end = (u32)Au1500_PCI_MEM_END; + /* check for pci memory window */ + if ((phys_addr >= start) && ((phys_addr + size) < end)) + return (phys_t) + ((phys_addr - start) + Au1500_PCI_MEM_START); } #endif diff -Naur linux-2.6.20.1.orig/arch/mips/au1000/pb1100/board_setup.c linux-2.6.20.1/arch/mips/au1000/pb1100/board_setup.c --- linux-2.6.20.1.orig/arch/mips/au1000/pb1100/board_setup.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/au1000/pb1100/board_setup.c 2007-02-20 16:47:41.000000000 -0800 @@ -47,8 +47,7 @@ void __init board_setup(void) { - u32 pin_func; - u32 sys_freqctrl, sys_clksrc; + volatile void __iomem * base = (volatile void __iomem *) 0xac000000UL; // set AUX clock to 12MHz * 8 = 96 MHz au_writel(8, SYS_AUXPLL); @@ -56,58 +55,62 @@ udelay(100); #ifdef CONFIG_USB_OHCI - // configure pins GPIO[14:9] as GPIO - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); + { + u32 pin_func, sys_freqctrl, sys_clksrc; - /* zero and disable FREQ2 */ - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* zero and disable USBH/USBD/IrDA clock */ - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x0000001F; - au_writel(sys_clksrc, SYS_CLKSRC); - - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x0000001F; - - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* - * Route 48MHz FREQ2 into USBH/USBD/IrDA - */ - sys_clksrc |= ((4<<2) | (0<<1) | 0 ); - au_writel(sys_clksrc, SYS_CLKSRC); - - /* setup the static bus controller */ - au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ - au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ - au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ - - // get USB Functionality pin state (device vs host drive pins) - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); - // 2nd USB port is USB host - pin_func |= 0x8000; - au_writel(pin_func, SYS_PINFUNC); + // configure pins GPIO[14:9] as GPIO + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); + + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD/IrDA clock */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x0000001F; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x0000001F; + + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* + * Route 48MHz FREQ2 into USBH/USBD/IrDA + */ + sys_clksrc |= ((4<<2) | (0<<1) | 0 ); + au_writel(sys_clksrc, SYS_CLKSRC); + + /* setup the static bus controller */ + au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ + au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ + au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ + + // get USB Functionality pin state (device vs host drive pins) + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); + // 2nd USB port is USB host + pin_func |= 0x8000; + au_writel(pin_func, SYS_PINFUNC); + } #endif // defined (CONFIG_USB_OHCI) /* Enable sys bus clock divider when IDLE state or no bus activity. */ au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); // Enable the RTC if not already enabled - if (!(readb(0xac000028) & 0x20)) { - writeb(readb(0xac000028) | 0x20, 0xac000028); + if (!(readb(base + 0x28) & 0x20)) { + writeb(readb(base + 0x28) | 0x20, base + 0x28); au_sync(); } // Put the clock in BCD mode - if (readb(0xac00002C) & 0x4) { /* reg B */ - writeb(readb(0xac00002c) & ~0x4, 0xac00002c); + if (readb(base + 0x2C) & 0x4) { /* reg B */ + writeb(readb(base + 0x2c) & ~0x4, base + 0x2c); au_sync(); } } diff -Naur linux-2.6.20.1.orig/arch/mips/au1000/pb1200/irqmap.c linux-2.6.20.1/arch/mips/au1000/pb1200/irqmap.c --- linux-2.6.20.1.orig/arch/mips/au1000/pb1200/irqmap.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/au1000/pb1200/irqmap.c 2007-02-20 16:47:41.000000000 -0800 @@ -137,33 +137,20 @@ return; } -static inline void pb1200_mask_and_ack_irq(unsigned int irq_nr) -{ - pb1200_disable_irq( irq_nr ); -} - -static void pb1200_end_irq(unsigned int irq_nr) -{ - if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { - pb1200_enable_irq(irq_nr); - } -} - static struct irq_chip external_irq_type = { #ifdef CONFIG_MIPS_PB1200 - "Pb1200 Ext", + .name = "Pb1200 Ext", #endif #ifdef CONFIG_MIPS_DB1200 - "Db1200 Ext", + .name = "Db1200 Ext", #endif - pb1200_startup_irq, - pb1200_shutdown_irq, - pb1200_enable_irq, - pb1200_disable_irq, - pb1200_mask_and_ack_irq, - pb1200_end_irq, - NULL + .startup = pb1200_startup_irq, + .shutdown = pb1200_shutdown_irq, + .ack = pb1200_disable_irq, + .mask = pb1200_disable_irq, + .mask_ack = pb1200_disable_irq, + .unmask = pb1200_enable_irq, }; void _board_init_irq(void) @@ -172,7 +159,8 @@ for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++) { - irq_desc[irq_nr].chip = &external_irq_type; + set_irq_chip_and_handler(irq_nr, &external_irq_type, + handle_level_irq); pb1200_disable_irq(irq_nr); } diff -Naur linux-2.6.20.1.orig/arch/mips/dec/int-handler.S linux-2.6.20.1/arch/mips/dec/int-handler.S --- linux-2.6.20.1.orig/arch/mips/dec/int-handler.S 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/dec/int-handler.S 2007-02-20 16:47:41.000000000 -0800 @@ -264,9 +264,6 @@ srlv t3,t1,t2 handle_it: - LONG_L s0, TI_REGS($28) - LONG_S sp, TI_REGS($28) - PTR_LA ra, ret_from_irq j dec_irq_dispatch nop @@ -277,7 +274,6 @@ #endif spurious: - PTR_LA ra, _ret_from_irq j spurious_interrupt nop END(plat_irq_dispatch) diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/Makefile linux-2.6.20.1/arch/mips/kernel/Makefile --- linux-2.6.20.1.orig/arch/mips/kernel/Makefile 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/Makefile 2007-02-20 16:47:41.000000000 -0800 @@ -55,9 +55,9 @@ obj-$(CONFIG_32BIT) += scall32-o32.o obj-$(CONFIG_64BIT) += scall64-64.o obj-$(CONFIG_BINFMT_IRIX) += binfmt_irix.o -obj-$(CONFIG_MIPS32_COMPAT) += linux32.o signal32.o +obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o -obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o ptrace32.o +obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o obj-$(CONFIG_PROC_FS) += proc.o diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/cpu-probe.c linux-2.6.20.1/arch/mips/kernel/cpu-probe.c --- linux-2.6.20.1.orig/arch/mips/kernel/cpu-probe.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/cpu-probe.c 2007-02-20 16:47:41.000000000 -0800 @@ -97,7 +97,7 @@ static int __initdata nowait = 0; -int __init wait_disable(char *s) +static int __init wait_disable(char *s) { nowait = 1; diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/linux32.c linux-2.6.20.1/arch/mips/kernel/linux32.c --- linux-2.6.20.1.orig/arch/mips/kernel/linux32.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/linux32.c 2007-02-20 16:47:41.000000000 -0800 @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -780,3 +781,49 @@ return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr); } + +/* + * Implement the event wait interface for the eventpoll file. It is the kernel + * part of the user space epoll_pwait(2). + */ +asmlinkage long compat_sys_epoll_pwait(int epfd, + struct epoll_event __user *events, int maxevents, int timeout, + const compat_sigset_t __user *sigmask, size_t sigsetsize) +{ + int error; + sigset_t ksigmask, sigsaved; + + /* + * If the caller wants a certain signal mask to be set during the wait, + * we apply it here. + */ + if (sigmask) { + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + if (!access_ok(VERIFY_READ, sigmask, sizeof(ksigmask))) + return -EFAULT; + if (__copy_conv_sigset_from_user(&ksigmask, sigmask)) + return -EFAULT; + sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP)); + sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); + } + + error = sys_epoll_wait(epfd, events, maxevents, timeout); + + /* + * If we changed the signal mask, we need to restore the original one. + * In case we've got a signal while waiting, we do not restore the + * signal mask yet, and we allow do_signal() to deliver the signal on + * the way back to userspace, before the signal mask is restored. + */ + if (sigmask) { + if (error == -EINTR) { + memcpy(¤t->saved_sigmask, &sigsaved, + sizeof(sigsaved)); + set_thread_flag(TIF_RESTORE_SIGMASK); + } else + sigprocmask(SIG_SETMASK, &sigsaved, NULL); + } + + return error; +} diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/mips-mt.c linux-2.6.20.1/arch/mips/kernel/mips-mt.c --- linux-2.6.20.1.orig/arch/mips/kernel/mips-mt.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/mips-mt.c 2007-02-20 16:47:41.000000000 -0800 @@ -3,9 +3,11 @@ * Copyright (C) 2005 Mips Technologies, Inc */ +#include #include #include #include +#include #include #include @@ -96,6 +98,10 @@ goto out_unlock; } + retval = security_task_setscheduler(p, 0, NULL); + if (retval) + goto out_unlock; + /* Record new user-specified CPU set for future reference */ p->thread.user_cpus_allowed = new_mask; @@ -141,8 +147,9 @@ p = find_process_by_pid(pid); if (!p) goto out_unlock; - - retval = 0; + retval = security_task_getscheduler(p); + if (retval) + goto out_unlock; cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map); @@ -448,3 +455,20 @@ #endif /* CONFIG_MIPS_MT_SMTC */ /* FILL IN VSMP and AP/SP VERSIONS HERE */ } + +struct class *mt_class; + +static int __init mt_init(void) +{ + struct class *mtc; + + mtc = class_create(THIS_MODULE, "mt"); + if (IS_ERR(mtc)) + return PTR_ERR(mtc); + + mt_class = mtc; + + return 0; +} + +subsys_initcall(mt_init); diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/ptrace.c linux-2.6.20.1/arch/mips/kernel/ptrace.c --- linux-2.6.20.1.orig/arch/mips/kernel/ptrace.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/ptrace.c 2007-02-20 16:47:41.000000000 -0800 @@ -20,12 +20,12 @@ #include #include #include -#include #include #include #include #include -#include +#include +#include #include #include @@ -473,12 +473,16 @@ */ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) { + /* do the secure computing check first */ + secure_computing(regs->orig_eax); + if (unlikely(current->audit_context) && entryexit) audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]), regs->regs[2]); if (!(current->ptrace & PT_PTRACED)) goto out; + if (!test_thread_flag(TIF_SYSCALL_TRACE)) goto out; @@ -496,9 +500,14 @@ send_sig(current->exit_code, current, 1); current->exit_code = 0; } - out: + +out: + /* There is no ->orig_eax and that's quite intensional for now making + this work will require some work in various other place before it's + more than a placebo. */ + if (unlikely(current->audit_context) && !entryexit) - audit_syscall_entry(audit_arch(), regs->regs[2], - regs->regs[4], regs->regs[5], - regs->regs[6], regs->regs[7]); + audit_syscall_entry(audit_arch(), regs->orig_eax, + regs->regs[4], regs->regs[5], + regs->regs[6], regs->regs[7]); } diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/r4k_fpu.S linux-2.6.20.1/arch/mips/kernel/r4k_fpu.S --- linux-2.6.20.1.orig/arch/mips/kernel/r4k_fpu.S 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/r4k_fpu.S 2007-02-20 16:47:41.000000000 -0800 @@ -114,6 +114,14 @@ */ LEAF(_restore_fp_context) EX lw t0, SC_FPC_CSR(a0) + + /* Fail if the CSR has exceptions pending */ + srl t1, t0, 5 + and t1, t0 + andi t1, 0x1f << 7 + bnez t1, fault + nop + #ifdef CONFIG_64BIT EX ldc1 $f1, SC_FPREGS+8(a0) EX ldc1 $f3, SC_FPREGS+24(a0) @@ -157,6 +165,14 @@ LEAF(_restore_fp_context32) /* Restore an o32 sigcontext. */ EX lw t0, SC32_FPC_CSR(a0) + + /* Fail if the CSR has exceptions pending */ + srl t1, t0, 5 + and t1, t0 + andi t1, 0x1f << 7 + bnez t1, fault + nop + EX ldc1 $f0, SC32_FPREGS+0(a0) EX ldc1 $f2, SC32_FPREGS+16(a0) EX ldc1 $f4, SC32_FPREGS+32(a0) @@ -177,9 +193,10 @@ jr ra li v0, 0 # success END(_restore_fp_context32) - .set reorder #endif + .set reorder + .type fault@function .ent fault fault: li v0, -EFAULT # failure diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/rtlx.c linux-2.6.20.1/arch/mips/kernel/rtlx.c --- linux-2.6.20.1.orig/arch/mips/kernel/rtlx.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/rtlx.c 2007-02-20 16:47:41.000000000 -0800 @@ -17,6 +17,7 @@ * */ +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -498,7 +500,8 @@ static int rtlx_module_init(void) { - int i; + struct device *dev; + int i, err; major = register_chrdev(0, module_name, &rtlx_fops); if (major < 0) { @@ -511,6 +514,13 @@ init_waitqueue_head(&channel_wqs[i].rt_queue); init_waitqueue_head(&channel_wqs[i].lx_queue); channel_wqs[i].in_open = 0; + + dev = device_create(mt_class, NULL, MKDEV(major, i), + "%s%d", module_name, i); + if (IS_ERR(dev)) { + err = PTR_ERR(dev); + goto out_chrdev; + } } /* set up notifiers */ @@ -525,10 +535,21 @@ setup_irq(rtlx_irq_num, &rtlx_irq); return 0; + +out_chrdev: + for (i = 0; i < RTLX_CHANNELS; i++) + device_destroy(mt_class, MKDEV(major, i)); + + return err; } static void __exit rtlx_module_exit(void) { + int i; + + for (i = 0; i < RTLX_CHANNELS; i++) + device_destroy(mt_class, MKDEV(major, i)); + unregister_chrdev(major, module_name); } diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/scall64-n32.S linux-2.6.20.1/arch/mips/kernel/scall64-n32.S --- linux-2.6.20.1.orig/arch/mips/kernel/scall64-n32.S 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/scall64-n32.S 2007-02-20 16:47:41.000000000 -0800 @@ -384,7 +384,7 @@ PTR sys_readlinkat PTR sys_fchmodat PTR sys_faccessat - PTR sys_pselect6 + PTR compat_sys_pselect6 PTR sys_ppoll /* 6265 */ PTR sys_unshare PTR sys_splice @@ -396,4 +396,4 @@ PTR compat_sys_get_robust_list PTR compat_sys_kexec_load PTR sys_getcpu - PTR sys_epoll_pwait + PTR compat_sys_epoll_pwait diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/scall64-o32.S linux-2.6.20.1/arch/mips/kernel/scall64-o32.S --- linux-2.6.20.1.orig/arch/mips/kernel/scall64-o32.S 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/scall64-o32.S 2007-02-24 14:25:52.000000000 -0800 @@ -506,7 +506,7 @@ PTR sys_readlinkat PTR sys_fchmodat PTR sys_faccessat /* 4300 */ - PTR sys_pselect6 + PTR compat_sys_pselect6 PTR sys_ppoll PTR sys_unshare PTR sys_splice @@ -518,5 +518,5 @@ PTR compat_sys_get_robust_list /* 4310 */ PTR compat_sys_kexec_load PTR sys_getcpu - PTR sys_epoll_pwait + PTR compat_sys_epoll_pwait .size sys_call_table,.-sys_call_table diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/setup.c linux-2.6.20.1/arch/mips/kernel/setup.c --- linux-2.6.20.1.orig/arch/mips/kernel/setup.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/setup.c 2007-02-20 16:47:41.000000000 -0800 @@ -521,7 +521,7 @@ #endif } -int __init fpu_disable(char *s) +static int __init fpu_disable(char *s) { int i; @@ -533,7 +533,7 @@ __setup("nofpu", fpu_disable); -int __init dsp_disable(char *s) +static int __init dsp_disable(char *s) { cpu_data[0].ases &= ~MIPS_ASE_DSP; diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/signal32.c linux-2.6.20.1/arch/mips/kernel/signal32.c --- linux-2.6.20.1.orig/arch/mips/kernel/signal32.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/signal32.c 2007-02-20 16:47:41.000000000 -0800 @@ -8,6 +8,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include +#include #include #include #include @@ -108,13 +110,6 @@ /* 32-bit compatibility types */ -#define _NSIG_BPW32 32 -#define _NSIG_WORDS32 (_NSIG / _NSIG_BPW32) - -typedef struct { - unsigned int sig[_NSIG_WORDS32]; -} sigset_t32; - typedef unsigned int __sighandler32_t; typedef void (*vfptr_t)(void); @@ -136,7 +131,7 @@ s32 uc_link; stack32_t uc_stack; struct sigcontext32 uc_mcontext; - sigset_t32 uc_sigmask; /* mask last for extensibility */ + compat_sigset_t uc_sigmask; /* mask last for extensibility */ }; extern void __put_sigset_unknown_nsig(void); @@ -391,7 +386,7 @@ u32 sf_code[2]; /* signal trampoline */ #endif struct sigcontext32 sf_sc; - sigset_t sf_mask; + compat_sigset_t sf_mask; #if ICACHE_REFILLS_WORKAROUND_WAR u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ #endif @@ -473,7 +468,7 @@ frame = (struct sigframe __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; - if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) + if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask)) goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); @@ -512,7 +507,7 @@ frame = (struct rt_sigframe32 __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; - if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) + if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask)) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); @@ -658,7 +653,8 @@ flush_cache_sigtramp((unsigned long) frame->sf_code); err |= setup_sigcontext32(regs, &frame->sf_sc); - err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); + err |= __copy_conv_sigset_to_user(&frame->sf_mask, set); + if (err) goto give_sigsegv; @@ -728,7 +724,7 @@ err |= __put_user(current->sas_ss_size, &frame->rs_uc.uc_stack.ss_size); err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext); - err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); + err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set); if (err) goto give_sigsegv; diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/signal_n32.c linux-2.6.20.1/arch/mips/kernel/signal_n32.c --- linux-2.6.20.1.orig/arch/mips/kernel/signal_n32.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/signal_n32.c 2007-02-20 16:47:41.000000000 -0800 @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -63,7 +64,7 @@ s32 uc_link; stack32_t uc_stack; struct sigcontext uc_mcontext; - sigset_t uc_sigmask; /* mask last for extensibility */ + compat_sigset_t uc_sigmask; /* mask last for extensibility */ }; struct rt_sigframe_n32 { @@ -126,7 +127,7 @@ frame = (struct rt_sigframe_n32 __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; - if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) + if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask)) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); @@ -192,7 +193,7 @@ err |= __put_user(current->sas_ss_size, &frame->rs_uc.uc_stack.ss_size); err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); - err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); + err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set); if (err) goto give_sigsegv; diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/smp.c linux-2.6.20.1/arch/mips/kernel/smp.c --- linux-2.6.20.1.orig/arch/mips/kernel/smp.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/smp.c 2007-02-20 16:47:41.000000000 -0800 @@ -51,31 +51,14 @@ EXPORT_SYMBOL(phys_cpu_present_map); EXPORT_SYMBOL(cpu_online_map); +/* This happens early in bootup, can't really do it better */ static void smp_tune_scheduling (void) { struct cache_desc *cd = ¤t_cpu_data.scache; - unsigned long cachesize; /* kB */ - unsigned long cpu_khz; + unsigned long cachesize = cd->linesz * cd->sets * cd->ways; - /* - * Crude estimate until we actually meassure ... - */ - cpu_khz = loops_per_jiffy * 2 * HZ / 1000; - - /* - * Rough estimation for SMP scheduling, this is the number of - * cycles it takes for a fully memory-limited process to flush - * the SMP-local cache. - * - * (For a P5 this pretty much means we will choose another idle - * CPU almost always at wakeup time (this is due to the small - * L1 cache), on PIIs it's around 50-100 usecs, depending on - * the cache size) - */ - if (!cpu_khz) - return; - - cachesize = cd->linesz * cd->sets * cd->ways; + if (cachesize > max_cache_size) + max_cache_size = cachesize; } extern void __init calibrate_delay(void); diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/traps.c linux-2.6.20.1/arch/mips/kernel/traps.c --- linux-2.6.20.1.orig/arch/mips/kernel/traps.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/traps.c 2007-02-20 16:47:41.000000000 -0800 @@ -708,6 +708,7 @@ die_if_kernel("Break instruction in kernel code", regs); force_sig(SIGTRAP, current); } + return; out_sigsegv: force_sig(SIGSEGV, current); @@ -751,6 +752,7 @@ die_if_kernel("Trap instruction in kernel code", regs); force_sig(SIGTRAP, current); } + return; out_sigsegv: force_sig(SIGSEGV, current); diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/vpe.c linux-2.6.20.1/arch/mips/kernel/vpe.c --- linux-2.6.20.1.orig/arch/mips/kernel/vpe.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/kernel/vpe.c 2007-02-20 16:47:41.000000000 -0800 @@ -29,6 +29,7 @@ */ #include +#include #include #include #include @@ -48,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +66,7 @@ static char module_name[] = "vpe"; static int major; +static const int minor = 1; /* fixed for now */ #ifdef CONFIG_MIPS_APSP_KSPD static struct kspd_notifications kspd_events; @@ -1365,12 +1368,15 @@ } #endif +static struct device *vpe_dev; + static int __init vpe_module_init(void) { struct vpe *v = NULL; + struct device *dev; struct tc *t; unsigned long val; - int i; + int i, err; if (!cpu_has_mipsmt) { printk("VPE loader: not a MIPS MT capable processor\n"); @@ -1383,6 +1389,14 @@ return major; } + dev = device_create(mt_class, NULL, MKDEV(major, minor), + "tc%d", minor); + if (IS_ERR(dev)) { + err = PTR_ERR(dev); + goto out_chrdev; + } + vpe_dev = dev; + dmt(); dvpe(); @@ -1478,6 +1492,11 @@ kspd_events.kspd_sp_exit = kspd_sp_exit; #endif return 0; + +out_chrdev: + unregister_chrdev(major, module_name); + + return err; } static void __exit vpe_module_exit(void) @@ -1490,6 +1509,7 @@ } } + device_destroy(mt_class, MKDEV(major, minor)); unregister_chrdev(major, module_name); } diff -Naur linux-2.6.20.1.orig/arch/mips/lib/Makefile linux-2.6.20.1/arch/mips/lib/Makefile --- linux-2.6.20.1.orig/arch/mips/lib/Makefile 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/lib/Makefile 2007-02-20 16:47:41.000000000 -0800 @@ -2,10 +2,11 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial.o memcpy.o promlib.o \ +lib-y += csum_partial.o memcpy.o memcpy-inatomic.o promlib.o \ strlen_user.o strncpy_user.o strnlen_user.o uncached.o -obj-y += iomap.o +obj-y += iomap.o +obj-$(CONFIG_PCI) += iomap-pci.o # libgcc-style stuff needed in the kernel lib-y += ashldi3.o ashrdi3.o lshrdi3.o diff -Naur linux-2.6.20.1.orig/arch/mips/lib/iomap-pci.c linux-2.6.20.1/arch/mips/lib/iomap-pci.c --- linux-2.6.20.1.orig/arch/mips/lib/iomap-pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.20.1/arch/mips/lib/iomap-pci.c 2007-02-20 16:47:41.000000000 -0800 @@ -0,0 +1,74 @@ +/* + * Implement the default iomap interfaces + * + * (C) Copyright 2004 Linus Torvalds + * (C) Copyright 2006 Ralf Baechle + * (C) Copyright 2007 MIPS Technologies, Inc. + * written by Ralf Baechle + */ +#include +#include +#include + +static void __iomem *ioport_map_pci(struct pci_dev *dev, + unsigned long port, unsigned int nr) +{ + struct pci_controller *ctrl = dev->bus->sysdata; + unsigned long base = ctrl->io_map_base; + + /* This will eventually become a BUG_ON but for now be gentle */ + if (unlikely(!ctrl->io_map_base)) { + struct pci_bus *bus = dev->bus; + char name[8]; + + while (bus->parent) + bus = bus->parent; + + ctrl->io_map_base = base = mips_io_port_base; + + sprintf(name, "%04x:%02x", pci_domain_nr(bus), bus->number); + printk(KERN_WARNING "io_map_base of root PCI bus %s unset. " + "Trying to continue but you better\nfix this issue or " + "report it to linux-mips@linux-mips.org or your " + "vendor.\n", name); +#ifdef CONFIG_PCI_DOMAINS + panic("To avoid data corruption io_map_base MUST be set with " + "multiple PCI domains."); +#endif + } + + return (void __iomem *) (ctrl->io_map_base + port); +} + +/* + * Create a virtual mapping cookie for a PCI BAR (memory or IO) + */ +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + unsigned long start = pci_resource_start(dev, bar); + unsigned long len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (!len || !start) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + if (flags & IORESOURCE_IO) + return ioport_map_pci(dev, start, len); + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_CACHEABLE) + return ioremap(start, len); + return ioremap_nocache(start, len); + } + /* What? */ + return NULL; +} + +EXPORT_SYMBOL(pci_iomap); + +void pci_iounmap(struct pci_dev *dev, void __iomem * addr) +{ + iounmap(addr); +} + +EXPORT_SYMBOL(pci_iounmap); diff -Naur linux-2.6.20.1.orig/arch/mips/lib/iomap.c linux-2.6.20.1/arch/mips/lib/iomap.c --- linux-2.6.20.1.orig/arch/mips/lib/iomap.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/lib/iomap.c 2007-02-20 16:47:41.000000000 -0800 @@ -1,78 +1,227 @@ /* - * iomap.c, Memory Mapped I/O routines for MIPS architecture. + * Implement the default iomap interfaces * - * This code is based on lib/iomap.c, by Linus Torvalds. - * - * Copyright (C) 2004-2005 Yoichi Yuasa - * - * 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. + * (C) Copyright 2004 Linus Torvalds + * (C) Copyright 2006 Ralf Baechle + * (C) Copyright 2007 MIPS Technologies, Inc. + * written by Ralf Baechle + */ +#include +#include +#include + +/* + * Read/write from/to an (offsettable) iomem cookie. It might be a PIO + * access or a MMIO access, these functions don't care. The info is + * encoded in the hardware mapping set up by the mapping functions + * (or the cookie itself, depending on implementation and hw). * - * 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. + * The generic routines don't assume any hardware mappings, and just + * encode the PIO/MMIO as part of the cookie. They coldly assume that + * the MMIO IO mappings are not in the low address range. * - * 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 + * Architectures for which this is not true can't use this generic + * implementation and should do their own copy. */ -#include -#include -#include -#include +#define PIO_MASK 0x0ffffUL -void __iomem *ioport_map(unsigned long port, unsigned int nr) +unsigned int ioread8(void __iomem *addr) { - unsigned long end; + return readb(addr); +} - end = port + nr - 1UL; - if (ioport_resource.start > port || - ioport_resource.end < end || port > end) - return NULL; +EXPORT_SYMBOL(ioread8); - return (void __iomem *)(mips_io_port_base + port); +unsigned int ioread16(void __iomem *addr) +{ + return readw(addr); } -void ioport_unmap(void __iomem *addr) +EXPORT_SYMBOL(ioread16); + +unsigned int ioread16be(void __iomem *addr) { + return be16_to_cpu(__raw_readw(addr)); } -EXPORT_SYMBOL(ioport_map); -EXPORT_SYMBOL(ioport_unmap); -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +EXPORT_SYMBOL(ioread16be); + +unsigned int ioread32(void __iomem *addr) { - unsigned long start, len, flags; + return readl(addr); +} - if (dev == NULL) - return NULL; +EXPORT_SYMBOL(ioread32); - start = pci_resource_start(dev, bar); - len = pci_resource_len(dev, bar); - if (!start || !len) - return NULL; +unsigned int ioread32be(void __iomem *addr) +{ + return be32_to_cpu(__raw_readl(addr)); +} - if (maxlen != 0 && len > maxlen) - len = maxlen; +EXPORT_SYMBOL(ioread32be); + +void iowrite8(u8 val, void __iomem *addr) +{ + writeb(val, addr); +} - flags = pci_resource_flags(dev, bar); - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap_cachable(start, len); - return ioremap_nocache(start, len); +EXPORT_SYMBOL(iowrite8); + +void iowrite16(u16 val, void __iomem *addr) +{ + writew(val, addr); +} + +EXPORT_SYMBOL(iowrite16); + +void iowrite16be(u16 val, void __iomem *addr) +{ + __raw_writew(cpu_to_be16(val), addr); +} + +EXPORT_SYMBOL(iowrite16be); + +void iowrite32(u32 val, void __iomem *addr) +{ + writel(val, addr); +} + +EXPORT_SYMBOL(iowrite32); + +void iowrite32be(u32 val, void __iomem *addr) +{ + __raw_writel(cpu_to_be32(val), addr); +} + +EXPORT_SYMBOL(iowrite32be); + +/* + * These are the "repeat MMIO read/write" functions. + * Note the "__raw" accesses, since we don't want to + * convert to CPU byte order. We write in "IO byte + * order" (we also don't have IO barriers). + */ +static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) +{ + while (--count >= 0) { + u8 data = __raw_readb(addr); + *dst = data; + dst++; } +} - return NULL; +static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) +{ + while (--count >= 0) { + u16 data = __raw_readw(addr); + *dst = data; + dst++; + } } -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) { - iounmap(addr); + while (--count >= 0) { + u32 data = __raw_readl(addr); + *dst = data; + dst++; + } } -EXPORT_SYMBOL(pci_iomap); -EXPORT_SYMBOL(pci_iounmap); + +static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) +{ + while (--count >= 0) { + __raw_writeb(*src, addr); + src++; + } +} + +static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) +{ + while (--count >= 0) { + __raw_writew(*src, addr); + src++; + } +} + +static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) +{ + while (--count >= 0) { + __raw_writel(*src, addr); + src++; + } +} + +void ioread8_rep(void __iomem *addr, void *dst, unsigned long count) +{ + mmio_insb(addr, dst, count); +} + +EXPORT_SYMBOL(ioread8_rep); + +void ioread16_rep(void __iomem *addr, void *dst, unsigned long count) +{ + mmio_insw(addr, dst, count); +} + +EXPORT_SYMBOL(ioread16_rep); + +void ioread32_rep(void __iomem *addr, void *dst, unsigned long count) +{ + mmio_insl(addr, dst, count); +} + +EXPORT_SYMBOL(ioread32_rep); + +void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) +{ + mmio_outsb(addr, src, count); +} + +EXPORT_SYMBOL(iowrite8_rep); + +void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) +{ + mmio_outsw(addr, src, count); +} + +EXPORT_SYMBOL(iowrite16_rep); + +void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) +{ + mmio_outsl(addr, src, count); +} + +EXPORT_SYMBOL(iowrite32_rep); + +/* + * Create a virtual mapping cookie for an IO port range + * + * This uses the same mapping are as the in/out family which has to be setup + * by the platform initialization code. + * + * Just to make matters somewhat more interesting on MIPS systems with + * multiple host bridge each will have it's own ioport address space. + */ +static void __iomem *ioport_map_legacy(unsigned long port, unsigned int nr) +{ + return (void __iomem *) (mips_io_port_base + port); +} + +void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + if (port > PIO_MASK) + return NULL; + + return ioport_map_legacy(port, nr); +} + +EXPORT_SYMBOL(ioport_map); + +void ioport_unmap(void __iomem *addr) +{ + /* Nothing to do */ +} + +EXPORT_SYMBOL(ioport_unmap); diff -Naur linux-2.6.20.1.orig/arch/mips/lib/memcpy-inatomic.S linux-2.6.20.1/arch/mips/lib/memcpy-inatomic.S --- linux-2.6.20.1.orig/arch/mips/lib/memcpy-inatomic.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.20.1/arch/mips/lib/memcpy-inatomic.S 2007-02-20 16:47:41.000000000 -0800 @@ -0,0 +1,436 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Unified implementation of memcpy, memmove and the __copy_user backend. + * + * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. + * Copyright (C) 2002 Broadcom, Inc. + * memcpy/copy_user author: Mark Vandevoorde + * + * Mnemonic names for arguments to memcpy/__copy_user + */ + +/* + * Hack to resolve longstanding prefetch issue + * + * Prefetching may be fatal on some systems if we're prefetching beyond the + * end of memory on some systems. It's also a seriously bad idea on non + * dma-coherent systems. + */ +#if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27) +#undef CONFIG_CPU_HAS_PREFETCH +#endif +#ifdef CONFIG_MIPS_MALTA +#undef CONFIG_CPU_HAS_PREFETCH +#endif + +#include +#include +#include + +#define dst a0 +#define src a1 +#define len a2 + +/* + * Spec + * + * memcpy copies len bytes from src to dst and sets v0 to dst. + * It assumes that + * - src and dst don't overlap + * - src is readable + * - dst is writable + * memcpy uses the standard calling convention + * + * __copy_user copies up to len bytes from src to dst and sets a2 (len) to + * the number of uncopied bytes due to an exception caused by a read or write. + * __copy_user assumes that src and dst don't overlap, and that the call is + * implementing one of the following: + * copy_to_user + * - src is readable (no exceptions when reading src) + * copy_from_user + * - dst is writable (no exceptions when writing dst) + * __copy_user uses a non-standard calling convention; see + * include/asm-mips/uaccess.h + * + * When an exception happens on a load, the handler must + # ensure that all of the destination buffer is overwritten to prevent + * leaking information to user mode programs. + */ + +/* + * Implementation + */ + +/* + * The exception handler for loads requires that: + * 1- AT contain the address of the byte just past the end of the source + * of the copy, + * 2- src_entry <= src < AT, and + * 3- (dst - src) == (dst_entry - src_entry), + * The _entry suffix denotes values when __copy_user was called. + * + * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user + * (2) is met by incrementing src by the number of bytes copied + * (3) is met by not doing loads between a pair of increments of dst and src + * + * The exception handlers for stores adjust len (if necessary) and return. + * These handlers do not need to overwrite any data. + * + * For __rmemcpy and memmove an exception is always a kernel bug, therefore + * they're not protected. + */ + +#define EXC(inst_reg,addr,handler) \ +9: inst_reg, addr; \ + .section __ex_table,"a"; \ + PTR 9b, handler; \ + .previous + +/* + * Only on the 64-bit kernel we can made use of 64-bit registers. + */ +#ifdef CONFIG_64BIT +#define USE_DOUBLE +#endif + +#ifdef USE_DOUBLE + +#define LOAD ld +#define LOADL ldl +#define LOADR ldr +#define STOREL sdl +#define STORER sdr +#define STORE sd +#define ADD daddu +#define SUB dsubu +#define SRL dsrl +#define SRA dsra +#define SLL dsll +#define SLLV dsllv +#define SRLV dsrlv +#define NBYTES 8 +#define LOG_NBYTES 3 + +/* + * As we are sharing code base with the mips32 tree (which use the o32 ABI + * register definitions). We need to redefine the register definitions from + * the n64 ABI register naming to the o32 ABI register naming. + */ +#undef t0 +#undef t1 +#undef t2 +#undef t3 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 + +#else + +#define LOAD lw +#define LOADL lwl +#define LOADR lwr +#define STOREL swl +#define STORER swr +#define STORE sw +#define ADD addu +#define SUB subu +#define SRL srl +#define SLL sll +#define SRA sra +#define SLLV sllv +#define SRLV srlv +#define NBYTES 4 +#define LOG_NBYTES 2 + +#endif /* USE_DOUBLE */ + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +#define LDFIRST LOADR +#define LDREST LOADL +#define STFIRST STORER +#define STREST STOREL +#define SHIFT_DISCARD SLLV +#else +#define LDFIRST LOADL +#define LDREST LOADR +#define STFIRST STOREL +#define STREST STORER +#define SHIFT_DISCARD SRLV +#endif + +#define FIRST(unit) ((unit)*NBYTES) +#define REST(unit) (FIRST(unit)+NBYTES-1) +#define UNIT(unit) FIRST(unit) + +#define ADDRMASK (NBYTES-1) + + .text + .set noreorder + .set noat + +/* + * A combined memcpy/__copy_user + * __copy_user sets len to 0 for success; else to an upper bound of + * the number of uncopied bytes. + * memcpy sets v0 to dst. + */ + .align 5 +LEAF(__copy_user_inatomic) + /* + * Note: dst & src may be unaligned, len may be 0 + * Temps + */ +#define rem t8 + + /* + * The "issue break"s below are very approximate. + * Issue delays for dcache fills will perturb the schedule, as will + * load queue full replay traps, etc. + * + * If len < NBYTES use byte operations. + */ + PREF( 0, 0(src) ) + PREF( 1, 0(dst) ) + sltu t2, len, NBYTES + and t1, dst, ADDRMASK + PREF( 0, 1*32(src) ) + PREF( 1, 1*32(dst) ) + bnez t2, copy_bytes_checklen + and t0, src, ADDRMASK + PREF( 0, 2*32(src) ) + PREF( 1, 2*32(dst) ) + bnez t1, dst_unaligned + nop + bnez t0, src_unaligned_dst_aligned + /* + * use delay slot for fall-through + * src and dst are aligned; need to compute rem + */ +both_aligned: + SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter + beqz t0, cleanup_both_aligned # len < 8*NBYTES + and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) + PREF( 0, 3*32(src) ) + PREF( 1, 3*32(dst) ) + .align 4 +1: +EXC( LOAD t0, UNIT(0)(src), l_exc) +EXC( LOAD t1, UNIT(1)(src), l_exc_copy) +EXC( LOAD t2, UNIT(2)(src), l_exc_copy) +EXC( LOAD t3, UNIT(3)(src), l_exc_copy) + SUB len, len, 8*NBYTES +EXC( LOAD t4, UNIT(4)(src), l_exc_copy) +EXC( LOAD t7, UNIT(5)(src), l_exc_copy) + STORE t0, UNIT(0)(dst) + STORE t1, UNIT(1)(dst) +EXC( LOAD t0, UNIT(6)(src), l_exc_copy) +EXC( LOAD t1, UNIT(7)(src), l_exc_copy) + ADD src, src, 8*NBYTES + ADD dst, dst, 8*NBYTES + STORE t2, UNIT(-6)(dst) + STORE t3, UNIT(-5)(dst) + STORE t4, UNIT(-4)(dst) + STORE t7, UNIT(-3)(dst) + STORE t0, UNIT(-2)(dst) + STORE t1, UNIT(-1)(dst) + PREF( 0, 8*32(src) ) + PREF( 1, 8*32(dst) ) + bne len, rem, 1b + nop + + /* + * len == rem == the number of bytes left to copy < 8*NBYTES + */ +cleanup_both_aligned: + beqz len, done + sltu t0, len, 4*NBYTES + bnez t0, less_than_4units + and rem, len, (NBYTES-1) # rem = len % NBYTES + /* + * len >= 4*NBYTES + */ +EXC( LOAD t0, UNIT(0)(src), l_exc) +EXC( LOAD t1, UNIT(1)(src), l_exc_copy) +EXC( LOAD t2, UNIT(2)(src), l_exc_copy) +EXC( LOAD t3, UNIT(3)(src), l_exc_copy) + SUB len, len, 4*NBYTES + ADD src, src, 4*NBYTES + STORE t0, UNIT(0)(dst) + STORE t1, UNIT(1)(dst) + STORE t2, UNIT(2)(dst) + STORE t3, UNIT(3)(dst) + beqz len, done + ADD dst, dst, 4*NBYTES +less_than_4units: + /* + * rem = len % NBYTES + */ + beq rem, len, copy_bytes + nop +1: +EXC( LOAD t0, 0(src), l_exc) + ADD src, src, NBYTES + SUB len, len, NBYTES + STORE t0, 0(dst) + bne rem, len, 1b + ADD dst, dst, NBYTES + + /* + * src and dst are aligned, need to copy rem bytes (rem < NBYTES) + * A loop would do only a byte at a time with possible branch + * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE + * because can't assume read-access to dst. Instead, use + * STREST dst, which doesn't require read access to dst. + * + * This code should perform better than a simple loop on modern, + * wide-issue mips processors because the code has fewer branches and + * more instruction-level parallelism. + */ +#define bits t2 + beqz len, done + ADD t1, dst, len # t1 is just past last byte of dst + li bits, 8*NBYTES + SLL rem, len, 3 # rem = number of bits to keep +EXC( LOAD t0, 0(src), l_exc) + SUB bits, bits, rem # bits = number of bits to discard + SHIFT_DISCARD t0, t0, bits + STREST t0, -1(t1) + jr ra + move len, zero +dst_unaligned: + /* + * dst is unaligned + * t0 = src & ADDRMASK + * t1 = dst & ADDRMASK; T1 > 0 + * len >= NBYTES + * + * Copy enough bytes to align dst + * Set match = (src and dst have same alignment) + */ +#define match rem +EXC( LDFIRST t3, FIRST(0)(src), l_exc) + ADD t2, zero, NBYTES +EXC( LDREST t3, REST(0)(src), l_exc_copy) + SUB t2, t2, t1 # t2 = number of bytes copied + xor match, t0, t1 + STFIRST t3, FIRST(0)(dst) + beq len, t2, done + SUB len, len, t2 + ADD dst, dst, t2 + beqz match, both_aligned + ADD src, src, t2 + +src_unaligned_dst_aligned: + SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter + PREF( 0, 3*32(src) ) + beqz t0, cleanup_src_unaligned + and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES + PREF( 1, 3*32(dst) ) +1: +/* + * Avoid consecutive LD*'s to the same register since some mips + * implementations can't issue them in the same cycle. + * It's OK to load FIRST(N+1) before REST(N) because the two addresses + * are to the same unit (unless src is aligned, but it's not). + */ +EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) + SUB len, len, 4*NBYTES +EXC( LDREST t0, REST(0)(src), l_exc_copy) +EXC( LDREST t1, REST(1)(src), l_exc_copy) +EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) +EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) +EXC( LDREST t2, REST(2)(src), l_exc_copy) +EXC( LDREST t3, REST(3)(src), l_exc_copy) + PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) + ADD src, src, 4*NBYTES +#ifdef CONFIG_CPU_SB1 + nop # improves slotting +#endif + STORE t0, UNIT(0)(dst) + STORE t1, UNIT(1)(dst) + STORE t2, UNIT(2)(dst) + STORE t3, UNIT(3)(dst) + PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) + bne len, rem, 1b + ADD dst, dst, 4*NBYTES + +cleanup_src_unaligned: + beqz len, done + and rem, len, NBYTES-1 # rem = len % NBYTES + beq rem, len, copy_bytes + nop +1: +EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDREST t0, REST(0)(src), l_exc_copy) + ADD src, src, NBYTES + SUB len, len, NBYTES + STORE t0, 0(dst) + bne len, rem, 1b + ADD dst, dst, NBYTES + +copy_bytes_checklen: + beqz len, done + nop +copy_bytes: + /* 0 < len < NBYTES */ +#define COPY_BYTE(N) \ +EXC( lb t0, N(src), l_exc); \ + SUB len, len, 1; \ + beqz len, done; \ + sb t0, N(dst) + + COPY_BYTE(0) + COPY_BYTE(1) +#ifdef USE_DOUBLE + COPY_BYTE(2) + COPY_BYTE(3) + COPY_BYTE(4) + COPY_BYTE(5) +#endif +EXC( lb t0, NBYTES-2(src), l_exc) + SUB len, len, 1 + jr ra + sb t0, NBYTES-2(dst) +done: + jr ra + nop + END(__copy_user_inatomic) + +l_exc_copy: + /* + * Copy bytes from src until faulting load address (or until a + * lb faults) + * + * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28) + * may be more than a byte beyond the last address. + * Hence, the lb below may get an exception. + * + * Assumes src < THREAD_BUADDR($28) + */ + LOAD t0, TI_TASK($28) + nop + LOAD t0, THREAD_BUADDR(t0) +1: +EXC( lb t1, 0(src), l_exc) + ADD src, src, 1 + sb t1, 0(dst) # can't fault -- we're copy_from_user + bne src, t0, 1b + ADD dst, dst, 1 +l_exc: + LOAD t0, TI_TASK($28) + nop + LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address + nop + SUB len, AT, t0 # len number of uncopied bytes + jr ra + nop diff -Naur linux-2.6.20.1.orig/arch/mips/lib-32/dump_tlb.c linux-2.6.20.1/arch/mips/lib-32/dump_tlb.c --- linux-2.6.20.1.orig/arch/mips/lib-32/dump_tlb.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/lib-32/dump_tlb.c 2007-02-20 16:47:41.000000000 -0800 @@ -40,8 +40,6 @@ return "256Mb"; #endif } - - return "unknown"; } #define BARRIER() \ diff -Naur linux-2.6.20.1.orig/arch/mips/lib-64/dump_tlb.c linux-2.6.20.1/arch/mips/lib-64/dump_tlb.c --- linux-2.6.20.1.orig/arch/mips/lib-64/dump_tlb.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/lib-64/dump_tlb.c 2007-02-20 16:47:41.000000000 -0800 @@ -31,8 +31,6 @@ case PM_256M: return "256Mb"; #endif } - - return "unknown"; } #define BARRIER() \ diff -Naur linux-2.6.20.1.orig/arch/mips/mm/c-sb1.c linux-2.6.20.1/arch/mips/mm/c-sb1.c --- linux-2.6.20.1.orig/arch/mips/mm/c-sb1.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/mm/c-sb1.c 2007-02-20 16:47:41.000000000 -0800 @@ -259,6 +259,12 @@ on_each_cpu(sb1_flush_cache_data_page_ipi, (void *) addr, 1, 1); } #else + +static void local_sb1_flush_cache_data_page(unsigned long addr) +{ + __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); +} + void sb1_flush_cache_data_page(unsigned long) __attribute__((alias("local_sb1_flush_cache_data_page"))); #endif diff -Naur linux-2.6.20.1.orig/arch/mips/mm/init.c linux-2.6.20.1/arch/mips/mm/init.c --- linux-2.6.20.1.orig/arch/mips/mm/init.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/mm/init.c 2007-02-20 16:47:41.000000000 -0800 @@ -61,8 +61,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -unsigned long highstart_pfn, highend_pfn; - /* * We have up to 8 empty zeroed pages so we can map one of the right colour * when needed. This is necessary only on R4000 / R4400 SC and MC versions @@ -261,6 +259,8 @@ #ifdef CONFIG_HIGHMEM +unsigned long highstart_pfn, highend_pfn; + pte_t *kmap_pte; pgprot_t kmap_prot; diff -Naur linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/Makefile linux-2.6.20.1/arch/mips/momentum/jaguar_atx/Makefile --- linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/Makefile 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/momentum/jaguar_atx/Makefile 2007-02-20 16:47:41.000000000 -0800 @@ -6,7 +6,7 @@ # unless it's something special (ie not a .c file). # -obj-y += irq.o prom.o reset.o setup.o +obj-y += irq.o platform.o prom.o reset.o setup.o obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o diff -Naur linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h linux-2.6.20.1/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h --- linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h 2007-02-20 16:47:41.000000000 -0800 @@ -46,7 +46,9 @@ extern unsigned long ja_fpga_base; -#define JAGUAR_FPGA_WRITE(x,y) writeb(x, ja_fpga_base + JAGUAR_ATX_REG_##y) -#define JAGUAR_FPGA_READ(x) readb(ja_fpga_base + JAGUAR_ATX_REG_##x) +#define __FPGA_REG_TO_ADDR(reg) \ + ((void *) ja_fpga_base + JAGUAR_ATX_REG_##reg) +#define JAGUAR_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg)) +#define JAGUAR_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg)) #endif diff -Naur linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/platform.c linux-2.6.20.1/arch/mips/momentum/jaguar_atx/platform.c --- linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/platform.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.20.1/arch/mips/momentum/jaguar_atx/platform.c 2007-02-20 16:47:41.000000000 -0800 @@ -0,0 +1,235 @@ +#include +#include +#include +#include +#include + +#include "jaguar_atx_fpga.h" + +#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) + +static struct resource mv643xx_eth_shared_resources[] = { + [0] = { + .name = "ethernet shared base", + .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, + .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + + MV643XX_ETH_SHARED_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv643xx_eth_shared_device = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), + .resource = mv643xx_eth_shared_resources, +}; + +#define MV_SRAM_BASE 0xfe000000UL +#define MV_SRAM_SIZE (256 * 1024) + +#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) +#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) + +#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE +#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) + +#define MV64x60_IRQ_ETH_0 48 +#define MV64x60_IRQ_ETH_1 49 +#define MV64x60_IRQ_ETH_2 50 + +#ifdef CONFIG_MV643XX_ETH_0 + +static struct resource mv64x60_eth0_resources[] = { + [0] = { + .name = "eth0 irq", + .start = MV64x60_IRQ_ETH_0, + .end = MV64x60_IRQ_ETH_0, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth0_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth0_pd = { + .mac_addr = eth0_mac_addr, + + .tx_sram_addr = MV_SRAM_BASE_ETH0, + .tx_sram_size = MV_SRAM_TXRING_SIZE, + .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, + + .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, + .rx_sram_size = MV_SRAM_RXRING_SIZE, + .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, +}; + +static struct platform_device eth0_device = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), + .resource = mv64x60_eth0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_0 */ + +#ifdef CONFIG_MV643XX_ETH_1 + +static struct resource mv64x60_eth1_resources[] = { + [0] = { + .name = "eth1 irq", + .start = MV64x60_IRQ_ETH_1, + .end = MV64x60_IRQ_ETH_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth1_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth1_pd = { + .mac_addr = eth1_mac_addr, + + .tx_sram_addr = MV_SRAM_BASE_ETH1, + .tx_sram_size = MV_SRAM_TXRING_SIZE, + .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, + + .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, + .rx_sram_size = MV_SRAM_RXRING_SIZE, + .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, +}; + +static struct platform_device eth1_device = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), + .resource = mv64x60_eth1_resources, + .dev = { + .platform_data = ð1_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_1 */ + +#ifdef CONFIG_MV643XX_ETH_2 + +static struct resource mv64x60_eth2_resources[] = { + [0] = { + .name = "eth2 irq", + .start = MV64x60_IRQ_ETH_2, + .end = MV64x60_IRQ_ETH_2, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth2_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth2_pd = { + .mac_addr = eth2_mac_addr, +}; + +static struct platform_device eth2_device = { + .name = MV643XX_ETH_NAME, + .id = 2, + .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), + .resource = mv64x60_eth2_resources, + .dev = { + .platform_data = ð2_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_2 */ + +static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { + &mv643xx_eth_shared_device, +#ifdef CONFIG_MV643XX_ETH_0 + ð0_device, +#endif +#ifdef CONFIG_MV643XX_ETH_1 + ð1_device, +#endif +#ifdef CONFIG_MV643XX_ETH_2 + ð2_device, +#endif +}; + +static u8 __init exchange_bit(u8 val, u8 cs) +{ + /* place the data */ + JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); + udelay(1); + + /* turn the clock on */ + JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); + udelay(1); + + /* turn the clock off and read-strobe */ + JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); + + /* return the data */ + return (JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; +} + +static void __init get_mac(char dest[6]) +{ + u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int i,j; + + for (i = 0; i < 12; i++) + exchange_bit(read_opcode[i], 1); + + for (j = 0; j < 6; j++) { + dest[j] = 0; + for (i = 0; i < 8; i++) { + dest[j] <<= 1; + dest[j] |= exchange_bit(0, 1); + } + } + + /* turn off CS */ + exchange_bit(0,0); +} + +/* + * Copy and increment ethernet MAC address by a small value. + * + * This is useful for systems where the only one MAC address is stored in + * non-volatile memory for multiple ports. + */ +static inline void eth_mac_add(unsigned char *dst, unsigned char *src, + unsigned int add) +{ + int i; + + BUG_ON(add >= 256); + + for (i = ETH_ALEN; i >= 0; i--) { + dst[i] = src[i] + add; + add = dst[i] < src[i]; /* compute carry */ + } + + WARN_ON(add); +} + +static int __init mv643xx_eth_add_pds(void) +{ + unsigned char mac[ETH_ALEN]; + int ret; + + get_mac(mac); +#ifdef CONFIG_MV643XX_ETH_0 + eth_mac_add(eth1_mac_addr, mac, 0); +#endif +#ifdef CONFIG_MV643XX_ETH_1 + eth_mac_add(eth1_mac_addr, mac, 1); +#endif +#ifdef CONFIG_MV643XX_ETH_2 + eth_mac_add(eth2_mac_addr, mac, 2); +#endif + ret = platform_add_devices(mv643xx_eth_pd_devs, + ARRAY_SIZE(mv643xx_eth_pd_devs)); + + return ret; +} + +device_initcall(mv643xx_eth_add_pds); + +#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ diff -Naur linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/prom.c linux-2.6.20.1/arch/mips/momentum/jaguar_atx/prom.c --- linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/prom.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/momentum/jaguar_atx/prom.c 2007-02-20 16:47:41.000000000 -0800 @@ -39,56 +39,6 @@ return "Momentum Jaguar-ATX"; } -#ifdef CONFIG_MV643XX_ETH -extern unsigned char prom_mac_addr_base[6]; - -static void burn_clocks(void) -{ - int i; - - /* this loop should burn at least 1us -- this should be plenty */ - for (i = 0; i < 0x10000; i++) - ; -} - -static u8 exchange_bit(u8 val, u8 cs) -{ - /* place the data */ - JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); - burn_clocks(); - - /* turn the clock on */ - JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); - burn_clocks(); - - /* turn the clock off and read-strobe */ - JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); - - /* return the data */ - return ((JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); -} - -void get_mac(char dest[6]) -{ - u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int i,j; - - for (i = 0; i < 12; i++) - exchange_bit(read_opcode[i], 1); - - for (j = 0; j < 6; j++) { - dest[j] = 0; - for (i = 0; i < 8; i++) { - dest[j] <<= 1; - dest[j] |= exchange_bit(0, 1); - } - } - - /* turn off CS */ - exchange_bit(0,0); -} -#endif - #ifdef CONFIG_64BIT unsigned long signext(unsigned long addr) @@ -228,11 +178,6 @@ #endif /* CONFIG_64BIT */ mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_JAGUAR_ATX; - -#ifdef CONFIG_MV643XX_ETH - /* get the base MAC address for on-board ethernet ports */ - get_mac(prom_mac_addr_base); -#endif } unsigned long __init prom_free_prom_memory(void) diff -Naur linux-2.6.20.1.orig/arch/mips/momentum/ocelot_3/platform.c linux-2.6.20.1/arch/mips/momentum/ocelot_3/platform.c --- linux-2.6.20.1.orig/arch/mips/momentum/ocelot_3/platform.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/momentum/ocelot_3/platform.c 2007-02-20 16:47:41.000000000 -0800 @@ -129,7 +129,7 @@ static struct platform_device eth2_device = { .name = MV643XX_ETH_NAME, - .id = 1, + .id = 2, .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), .resource = mv64x60_eth2_resources, .dev = { diff -Naur linux-2.6.20.1.orig/arch/mips/oprofile/Kconfig linux-2.6.20.1/arch/mips/oprofile/Kconfig --- linux-2.6.20.1.orig/arch/mips/oprofile/Kconfig 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/oprofile/Kconfig 2007-02-20 16:47:41.000000000 -0800 @@ -11,7 +11,7 @@ config OPROFILE tristate "OProfile system profiling (EXPERIMENTAL)" - depends on PROFILING && EXPERIMENTAL + depends on PROFILING && !MIPS_MT_SMTC && EXPERIMENTAL help OProfile is a profiling system capable of profiling the whole system, include the kernel, kernel modules, libraries, diff -Naur linux-2.6.20.1.orig/arch/mips/pci/fixup-tb0219.c linux-2.6.20.1/arch/mips/pci/fixup-tb0219.c --- linux-2.6.20.1.orig/arch/mips/pci/fixup-tb0219.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/pci/fixup-tb0219.c 2007-02-20 16:47:41.000000000 -0800 @@ -2,7 +2,7 @@ * fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups. * * Copyright (C) 2003 Megasolution Inc. - * Copyright (C) 2004 Yoichi Yuasa + * Copyright (C) 2004-2005 Yoichi Yuasa * * 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 diff -Naur linux-2.6.20.1.orig/arch/mips/pci/pci.c linux-2.6.20.1/arch/mips/pci/pci.c --- linux-2.6.20.1.orig/arch/mips/pci/pci.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/pci/pci.c 2007-02-20 16:47:41.000000000 -0800 @@ -79,6 +79,14 @@ { *hose_tail = hose; hose_tail = &hose->next; + + /* + * Do not panic here but later - this might hapen before console init. + */ + if (!hose->io_map_base) { + printk(KERN_WARNING + "registering PCI controller with io_map_base unset\n"); + } } /* Most MIPS systems have straight-forward swizzling needs. */ @@ -103,10 +111,15 @@ return PCI_SLOT(dev->devfn); } +int mips_system_has_legacy_ide; + +EXPORT_SYMBOL_GPL(mips_system_has_legacy_ide); + static int __init pcibios_init(void) { struct pci_controller *hose; struct pci_bus *bus; + struct pci_dev *dev; int next_busno; int need_domain_info = 0; @@ -150,6 +163,13 @@ pci_assign_unassigned_resources(); pci_fixup_irqs(common_swizzle, pcibios_map_irq); + if ((dev = pci_get_class(PCI_CLASS_BRIDGE_EISA << 8, NULL)) != NULL || + (dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL)) != NULL) { + pci_dev_put(dev); + + mips_system_has_legacy_ide = 1; + } + return 0; } diff -Naur linux-2.6.20.1.orig/arch/mips/pmc-sierra/yosemite/dbg_io.c linux-2.6.20.1/arch/mips/pmc-sierra/yosemite/dbg_io.c --- linux-2.6.20.1.orig/arch/mips/pmc-sierra/yosemite/dbg_io.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/pmc-sierra/yosemite/dbg_io.c 2007-02-20 16:47:41.000000000 -0800 @@ -93,7 +93,7 @@ * Functions to READ and WRITE to serial port 1 */ #define SERIAL_READ_1(ofs) (*((volatile unsigned char*) \ - (TITAN_SERIAL_BASE_1 + ofs) + (TITAN_SERIAL_BASE_1 + ofs))) #define SERIAL_WRITE_1(ofs, val) ((*((volatile unsigned char*) \ (TITAN_SERIAL_BASE_1 + ofs))) = val) diff -Naur linux-2.6.20.1.orig/arch/mips/pmc-sierra/yosemite/setup.c linux-2.6.20.1/arch/mips/pmc-sierra/yosemite/setup.c --- linux-2.6.20.1.orig/arch/mips/pmc-sierra/yosemite/setup.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/pmc-sierra/yosemite/setup.c 2007-02-20 16:47:41.000000000 -0800 @@ -171,6 +171,7 @@ static void __init py_uart_setup(void) { +#ifdef CONFIG_SERIAL_8250 struct uart_port up; /* @@ -188,6 +189,7 @@ if (early_serial_setup(&up)) printk(KERN_ERR "Early serial init of port 0 failed\n"); +#endif /* CONFIG_SERIAL_8250 */ } static void __init py_rtc_setup(void) diff -Naur linux-2.6.20.1.orig/arch/mips/qemu/Makefile linux-2.6.20.1/arch/mips/qemu/Makefile --- linux-2.6.20.1.orig/arch/mips/qemu/Makefile 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/qemu/Makefile 2007-02-20 16:47:41.000000000 -0800 @@ -4,4 +4,5 @@ obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o q-reset.o +obj-$(CONFIG_VT) += q-vga.o obj-$(CONFIG_SMP) += q-smp.o diff -Naur linux-2.6.20.1.orig/arch/mips/qemu/q-setup.c linux-2.6.20.1/arch/mips/qemu/q-setup.c --- linux-2.6.20.1.orig/arch/mips/qemu/q-setup.c 2007-02-19 22:34:32.000000000 -0800 +++ linux-2.6.20.1/arch/mips/qemu/q-setup.c 2007-02-20 16:47:41.000000000 -0800 @@ -2,6 +2,7 @@ #include #include +extern void qvga_init(void); extern void qemu_reboot_setup(void); #define QEMU_PORT_BASE 0xb4000000 @@ -23,5 +24,9 @@ void __init plat_mem_setup(void) { set_io_port_base(QEMU_PORT_BASE); +#ifdef CONFIG_VT + qvga_init(); +#endif + qemu_reboot_setup(); } diff -Naur linux-2.6.20.1.orig/arch/mips/qemu/q-vga.c linux-2.6.20.1/arch/mips/qemu/q-vga.c --- linux-2.6.20.1.orig/arch/mips/qemu/q-vga.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.20.1/arch/mips/qemu/q-vga.c 2007-02-20 16:47:41.000000000 -0800 @@ -0,0 +1,189 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2005 by Ralf Baechle (ralf@linux-mips.org) + * + * This will eventually go into the qemu firmware. + */ +#include +#include +#include +#include +#include