diff options
38 files changed, 571 insertions, 701 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a00fabe2e4e0..5c863bcd5614 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -117,9 +117,9 @@ config MACH_JAZZ select ARC32 select ARCH_MAY_HAVE_PC_FDC select GENERIC_ISA_DMA - select I8253 select I8259 select ISA + select PCSPEAKER select SYS_HAS_CPU_R4X00 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL @@ -347,9 +347,9 @@ config QEMU select DMA_COHERENT select GENERIC_ISA_DMA select HAVE_STD_PC_SERIAL_PORT - select I8253 select I8259 select ISA + select PCSPEAKER select SWAP_IO_SPACE select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL @@ -562,9 +562,9 @@ config SNI_RM select HW_HAS_EISA select HW_HAS_PCI select IRQ_CPU - select I8253 select I8259 select ISA + select PCSPEAKER select SWAP_IO_SPACE if CPU_BIG_ENDIAN select SYS_HAS_CPU_R4X00 select SYS_HAS_CPU_R5000 @@ -1404,6 +1404,19 @@ config MIPS_MT_SMTC_INSTANT_REPLAY it off), but ensures that IPIs are handled promptly even under heavy I/O interrupt load. +config MIPS_MT_SMTC_IM_BACKSTOP + bool "Use per-TC register bits as backstop for inhibited IM bits" + depends on MIPS_MT_SMTC + default y + help + To support multiple TC microthreads acting as "CPUs" within + a VPE, VPE-wide interrupt mask bits must be specially manipulated + during interrupt handling. To support legacy drivers and interrupt + controller management code, SMTC has a "backstop" to track and + if necessary restore the interrupt mask. This has some performance + impact on interrupt service overhead. Disable it only if you know + what you are doing. + config MIPS_VPE_LOADER_TOM bool "Load VPE program into memory hidden from linux" depends on MIPS_VPE_LOADER @@ -1851,7 +1864,7 @@ config MMU bool default y -config I8253 +config PCSPEAKER bool source "drivers/pcmcia/Kconfig" diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c index 13fe187f35d6..fdf2b85a69c8 100644 --- a/arch/mips/au1000/common/setup.c +++ b/arch/mips/au1000/common/setup.c @@ -100,9 +100,6 @@ void __init plat_mem_setup(void) argptr = prom_getcmdline(); /* default panel */ /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/ -#ifdef CONFIG_MIPS_HYDROGEN3 - strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor"); -#endif } #endif diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index dd04eece9fd3..8a0b4ac5283d 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -241,7 +241,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ISA=y CONFIG_MMU=y -CONFIG_I8253=y +CONFIG_PCSPEAKER=y # # PCCARD (PCMCIA/CardBus) support diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig index 6cca105832ca..703de002e372 100644 --- a/arch/mips/configs/qemu_defconfig +++ b/arch/mips/configs/qemu_defconfig @@ -221,7 +221,7 @@ CONFIG_DEFAULT_IOSCHED="noop" # CONFIG_ISA=y CONFIG_MMU=y -CONFIG_I8253=y +CONFIG_PCSPEAKER=y # # PCCARD (PCMCIA/CardBus) support diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 1a67a85aabbb..a5dc5cb97aae 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -251,7 +251,7 @@ CONFIG_PCI=y CONFIG_ISA=y # CONFIG_EISA is not set CONFIG_MMU=y -CONFIG_I8253=y +CONFIG_PCSPEAKER=y # # PCCARD (PCMCIA/CardBus) support diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index f1cdb12f7925..f342d8c887b8 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -592,8 +592,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set # CONFIG_RTC is not set -CONFIG_GEN_RTC=y -CONFIG_GEN_RTC_X=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 961594cb5214..5c8085b6d7ab 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -63,7 +63,7 @@ obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_64BIT) += cpu-bugs64.o -obj-$(CONFIG_I8253) += i8253.o +obj-$(CONFIG_PCSPEAKER) += pcspeaker.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index 686249c5c328..e29598ae939d 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -84,6 +84,7 @@ FEXPORT(restore_all) # restore full frame LONG_S sp, TI_REGS($28) jal deferred_smtc_ipi LONG_S s0, TI_REGS($28) +#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP /* Re-arm any temporarily masked interrupts not explicitly "acked" */ mfc0 v0, CP0_TCSTATUS ori v1, v0, TCSTATUS_IXMT @@ -110,6 +111,7 @@ FEXPORT(restore_all) # restore full frame _ehb xor t0, t0, t3 mtc0 t0, CP0_TCCONTEXT +#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */ #endif /* CONFIG_MIPS_MT_SMTC */ .set noat RESTORE_TEMP diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 297bd56c2347..c0f19d638b98 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -243,9 +243,11 @@ NESTED(except_vec_vi_handler, 0, sp) */ mfc0 t1, CP0_STATUS and t0, a0, t1 +#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP mfc0 t2, CP0_TCCONTEXT or t0, t0, t2 mtc0 t0, CP0_TCCONTEXT +#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */ xor t1, t1, t0 mtc0 t1, CP0_STATUS _ehb diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/pcspeaker.c index 475df6904219..475df6904219 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/pcspeaker.c diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 06729596812f..d9bfae53c43f 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -85,12 +85,7 @@ move $28, a2 cpu_restore_nonscratch a1 -#if (_THREAD_SIZE - 32) < 0x10000 - PTR_ADDIU t0, $28, _THREAD_SIZE - 32 -#else - PTR_LI t0, _THREAD_SIZE - 32 - PTR_ADDU t0, $28 -#endif + PTR_ADDU t0, $28, _THREAD_SIZE - 32 set_saved_sp t0, t1, t2 #ifdef CONFIG_MIPS_MT_SMTC /* Read-modify-writes of Status must be atomic on a VPE */ diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 80ea4fa95bd9..5e9fa83c4ef0 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -373,7 +373,7 @@ asmlinkage void do_be(struct pt_regs *regs) action = MIPS_BE_FIXUP; if (board_be_handler) - action = board_be_handler(regs, fixup != 0); + action = board_be_handler(regs, fixup != NULL); switch (action) { case MIPS_BE_DISCARD: diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index 1a4db7dc77cb..465ff0ec85b9 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c @@ -10,6 +10,7 @@ #include <asm/mipsregs.h> #include <asm/page.h> #include <asm/pgtable.h> +#include <asm/tlbdebug.h> static inline const char *msk2str(unsigned int mask) { diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c index 52f87795ecc3..9cee907975ae 100644 --- a/arch/mips/lib/r3k_dump_tlb.c +++ b/arch/mips/lib/r3k_dump_tlb.c @@ -11,6 +11,7 @@ #include <asm/mipsregs.h> #include <asm/page.h> #include <asm/pgtable.h> +#include <asm/tlbdebug.h> extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */ diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c index 2388f7f3ffde..58d14f4d9349 100644 --- a/arch/mips/lib/uncached.c +++ b/arch/mips/lib/uncached.c @@ -12,6 +12,7 @@ #include <asm/addrspace.h> #include <asm/bug.h> +#include <asm/cacheflush.h> #ifndef CKSEG2 #define CKSEG2 CKSSEG diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c index d86b37235cf6..5cbc3509ab52 100644 --- a/arch/mips/mipssim/sim_int.c +++ b/arch/mips/mipssim/sim_int.c @@ -77,7 +77,7 @@ asmlinkage void plat_irq_dispatch(void) irq = irq_ffs(pending); if (irq > 0) - do_IRQ(MIPSCPU_INT_BASE + irq); + do_IRQ(MIPS_CPU_IRQ_BASE + irq); else spurious_interrupt(); } diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c index 3643582bdade..60e66906be65 100644 --- a/arch/mips/mipssim/sim_setup.c +++ b/arch/mips/mipssim/sim_setup.c @@ -84,7 +84,7 @@ static void __init serial_init(void) /* hardware int 4 - the serial int, is CPU int 6 but poll for now */ s.irq = 0; - s.uartclk = BASE_BAUD * 16; + s.uartclk = 1843200; s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; s.iotype = UPIO_PORT; s.regshift = 0; diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c index 874a18e8ac24..a0f5a5dca1b2 100644 --- a/arch/mips/mipssim/sim_time.c +++ b/arch/mips/mipssim/sim_time.c @@ -5,7 +5,6 @@ #include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/mc146818rtc.h> -#include <linux/mipsregs.h> #include <linux/smp.h> #include <linux/timex.h> diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 8108231f2e20..99d8f4fd3ff4 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -269,7 +269,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) } for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { - struct pci_dev *dev = pci_dev_b(ln); + dev = pci_dev_b(ln); if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) pcibios_fixup_device_resources(dev, bus); diff --git a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c deleted file mode 100644 index 97c73c793c35..000000000000 --- a/arch/mips/sibyte/swarm/time.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - * Time routines for the swarm board. We pass all the hard stuff - * through to the sb1250 handling code. Only thing we really keep - * track of here is what time of day we think it is. And we don't - * really even do a good job of that... - */ - - -#include <linux/bcd.h> -#include <linux/init.h> -#include <linux/time.h> -#include <linux/sched.h> -#include <linux/spinlock.h> -#include <asm/system.h> -#include <asm/addrspace.h> -#include <asm/io.h> - -#include <asm/sibyte/sb1250.h> -#include <asm/sibyte/sb1250_regs.h> -#include <asm/sibyte/sb1250_smbus.h> - -static unsigned long long sec_bias = 0; -static unsigned int usec_bias = 0; - -/* Xicor 1241 definitions */ - -/* - * Register bits - */ - -#define X1241REG_SR_BAT 0x80 /* currently on battery power */ -#define X1241REG_SR_RWEL 0x04 /* r/w latch is enabled, can write RTC */ -#define X1241REG_SR_WEL 0x02 /* r/w latch is unlocked, can enable r/w now */ -#define X1241REG_SR_RTCF 0x01 /* clock failed */ -#define X1241REG_BL_BP2 0x80 /* block protect 2 */ -#define X1241REG_BL_BP1 0x40 /* block protect 1 */ -#define X1241REG_BL_BP0 0x20 /* block protect 0 */ -#define X1241REG_BL_WD1 0x10 -#define X1241REG_BL_WD0 0x08 -#define X1241REG_HR_MIL 0x80 /* military time format */ - -/* - * Register numbers - */ - -#define X1241REG_BL 0x10 /* block protect bits */ -#define X1241REG_INT 0x11 /* */ -#define X1241REG_SC 0x30 /* Seconds */ -#define X1241REG_MN 0x31 /* Minutes */ -#define X1241REG_HR 0x32 /* Hours */ -#define X1241REG_DT 0x33 /* Day of month */ -#define X1241REG_MO 0x34 /* Month */ -#define X1241REG_YR 0x35 /* Year */ -#define X1241REG_DW 0x36 /* Day of Week */ -#define X1241REG_Y2K 0x37 /* Year 2K */ -#define X1241REG_SR 0x3F /* Status register */ - -#define X1241_CCR_ADDRESS 0x6F - -#define SMB_CSR(reg) (IOADDR(A_SMB_REGISTER(1, reg))) - -static int xicor_read(uint8_t addr) -{ - while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) - ; - - __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD)); - __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA)); - __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE, - SMB_CSR(R_SMB_START)); - - while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) - ; - - __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE, - SMB_CSR(R_SMB_START)); - - while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) - ; - - if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { - /* Clear error bit by writing a 1 */ - __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); - return -1; - } - - return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); -} - -static int xicor_write(uint8_t addr, int b) -{ - while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) - ; - - __raw_writeq(addr, SMB_CSR(R_SMB_CMD)); - __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA)); - __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE, - SMB_CSR(R_SMB_START)); - - while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) - ; - - if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { - /* Clear error bit by writing a 1 */ - __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); - return -1; - } else { - return 0; - } -} - -/* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be - * called 500 ms after the second nowtime has started, because when - * nowtime is written into the registers of the CMOS clock, it will - * jump to the next second precisely 500 ms later. Check the Motorola - * MC146818A or Dallas DS12887 data sheet for details. - * - * BUG: This routine does not handle hour overflow properly; it just - * sets the minutes. Usually you'll only notice that after reboot! - */ -int set_rtc_mmss(unsigned long nowtime) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - - cmos_minutes = xicor_read(X1241REG_MN); - cmos_minutes = BCD2BIN(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - /* unlock writes to the CCR */ - xicor_write(X1241REG_SR, X1241REG_SR_WEL); - xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL); - - if (abs(real_minutes - cmos_minutes) < 30) { - real_seconds = BIN2BCD(real_seconds); - real_minutes = BIN2BCD(real_minutes); - xicor_write(X1241REG_SC, real_seconds); - xicor_write(X1241REG_MN, real_minutes); - } else { - printk(KERN_WARNING - "set_rtc_mmss: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - xicor_write(X1241REG_SR, 0); - - printk("set_rtc_mmss: %02d:%02d\n", real_minutes, real_seconds); - - return retval; -} - -static unsigned long __init get_swarm_time(void) -{ - unsigned int year, mon, day, hour, min, sec, y2k; - - sec = xicor_read(X1241REG_SC); - min = xicor_read(X1241REG_MN); - hour = xicor_read(X1241REG_HR); - - if (hour & X1241REG_HR_MIL) { - hour &= 0x3f; - } else { - if (hour & 0x20) - hour = (hour & 0xf) + 0x12; - } - - sec = BCD2BIN(sec); - min = BCD2BIN(min); - hour = BCD2BIN(hour); - - day = xicor_read(X1241REG_DT); - mon = xicor_read(X1241REG_MO); - year = xicor_read(X1241REG_YR); - y2k = xicor_read(X1241REG_Y2K); - - day = BCD2BIN(day); - mon = BCD2BIN(mon); - year = BCD2BIN(year); - y2k = BCD2BIN(y2k); - - year += (y2k * 100); - - return mktime(year, mon, day, hour, min, sec); -} - -/* - * Bring up the timer at 100 Hz. - */ -void __init swarm_time_init(void) -{ - unsigned int flags; - int status; - - /* Set up the scd general purpose timer 0 to cpu 0 */ - sb1250_time_init(); - - /* Establish communication with the Xicor 1241 RTC */ - /* XXXKW how do I share the SMBus with the I2C subsystem? */ - - __raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ)); - __raw_writeq(0, SMB_CSR(R_SMB_CONTROL)); - - if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) { - printk("x1241: couldn't detect on SWARM SMBus 1\n"); - } else { - if (status & X1241REG_SR_RTCF) - printk("x1241: battery failed -- time is probably wrong\n"); - write_seqlock_irqsave(&xtime_lock, flags); - xtime.tv_sec = get_swarm_time(); - xtime.tv_nsec = 0; - write_sequnlock_irqrestore(&xtime_lock, flags); - } -} diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index 6850a29defcd..acc9ba76c1a9 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c @@ -87,8 +87,8 @@ static struct platform_device snirm_82596_pdev = { static struct resource snirm_53c710_rsrc[] = { { - .start = 0xb9000000, - .end = 0xb90fffff, + .start = 0x19000000, + .end = 0x190fffff, .flags = IORESOURCE_MEM }, { @@ -106,8 +106,8 @@ static struct platform_device snirm_53c710_pdev = { static struct resource sc26xx_rsrc[] = { { - .start = 0xbc070000, - .end = 0xbc0700ff, + .start = 0x1c070000, + .end = 0x1c0700ff, .flags = IORESOURCE_MEM }, { diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c index 4bfda020fdc7..28a11d8605ce 100644 --- a/arch/mips/sni/rm200.c +++ b/arch/mips/sni/rm200.c @@ -88,8 +88,8 @@ static struct platform_device snirm_82596_rm200_pdev = { static struct resource snirm_53c710_rm200_rsrc[] = { { - .start = 0xb9000000, - .end = 0xb90fffff, + .start = 0x19000000, + .end = 0x190fffff, .flags = IORESOURCE_MEM }, { diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile index f842783acd86..d0d84ec8d63d 100644 --- a/arch/mips/vr41xx/common/Makefile +++ b/arch/mips/vr41xx/common/Makefile @@ -2,4 +2,4 @@ # Makefile for common code of the NEC VR4100 series. # -obj-y += bcu.o cmu.o icu.o init.o irq.o pmu.o type.o +obj-y += bcu.o cmu.o giu.o icu.o init.o irq.o pmu.o rtc.o siu.o type.o diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c new file mode 100644 index 000000000000..d21f6f2d22a3 --- /dev/null +++ b/arch/mips/vr41xx/common/giu.c @@ -0,0 +1,122 @@ +/* + * NEC VR4100 series GIU platform device. + * + * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> + +#include <asm/cpu.h> +#include <asm/vr41xx/giu.h> +#include <asm/vr41xx/irq.h> + +static struct resource giu_50pins_pullupdown_resource[] __initdata = { + { + .start = 0x0b000100, + .end = 0x0b00011f, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x0b0002e0, + .end = 0x0b0002e3, + .flags = IORESOURCE_MEM, + }, + { + .start = GIUINT_IRQ, + .end = GIUINT_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource giu_36pins_resource[] __initdata = { + { + .start = 0x0f000140, + .end = 0x0f00015f, + .flags = IORESOURCE_MEM, + }, + { + .start = GIUINT_IRQ, + .end = GIUINT_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource giu_48pins_resource[] __initdata = { + { + .start = 0x0f000140, + .end = 0x0f000167, + .flags = IORESOURCE_MEM, + }, + { + .start = GIUINT_IRQ, + .end = GIUINT_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static int __init vr41xx_giu_add(void) +{ + struct platform_device *pdev; + struct resource *res; + unsigned int num; + int retval; + + pdev = platform_device_alloc("GIU", -1); + if (!pdev) + return -ENOMEM; + + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + pdev->id = GPIO_50PINS_PULLUPDOWN; + res = giu_50pins_pullupdown_resource; + num = ARRAY_SIZE(giu_50pins_pullupdown_resource); + break; + case CPU_VR4122: + case CPU_VR4131: + pdev->id = GPIO_36PINS; + res = giu_36pins_resource; + num = ARRAY_SIZE(giu_36pins_resource); + break; + case CPU_VR4133: + pdev->id = GPIO_48PINS_EDGE_SELECT; + res = giu_48pins_resource; + num = ARRAY_SIZE(giu_48pins_resource); + break; + default: + retval = -ENODEV; + goto err_free_device; + } + + retval = platform_device_add_resources(pdev, res, num); + if (retval) + goto err_free_device; + + retval = platform_device_add(pdev); + if (retval) + goto err_free_device; + + return 0; + +err_free_device: + platform_device_put(pdev); + + return retval; +} +device_initcall(vr41xx_giu_add); diff --git a/arch/mips/vr41xx/common/rtc.c b/arch/mips/vr41xx/common/rtc.c new file mode 100644 index 000000000000..cce605b3d688 --- /dev/null +++ b/arch/mips/vr41xx/common/rtc.c @@ -0,0 +1,117 @@ +/* + * NEC VR4100 series RTC platform device. + * + * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> + +#include <asm/cpu.h> +#include <asm/vr41xx/irq.h> + +static struct resource rtc_type1_resource[] __initdata = { + { + .start = 0x0b0000c0, + .end = 0x0b0000df, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x0b0001c0, + .end = 0x0b0001df, + .flags = IORESOURCE_MEM, + }, + { + .start = ELAPSEDTIME_IRQ, + .end = ELAPSEDTIME_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .start = RTCLONG1_IRQ, + .end = RTCLONG1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource rtc_type2_resource[] __initdata = { + { + .start = 0x0f000100, + .end = 0x0f00011f, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x0f000120, + .end = 0x0f00013f, + .flags = IORESOURCE_MEM, + }, + { + .start = ELAPSEDTIME_IRQ, + .end = ELAPSEDTIME_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .start = RTCLONG1_IRQ, + .end = RTCLONG1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static int __init vr41xx_rtc_add(void) +{ + struct platform_device *pdev; + struct resource *res; + unsigned int num; + int retval; + + pdev = platform_device_alloc("RTC", -1); + if (!pdev) + return -ENOMEM; + + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + res = rtc_type1_resource; + num = ARRAY_SIZE(rtc_type1_resource); + break; + case CPU_VR4122: + case CPU_VR4131: + case CPU_VR4133: + res = rtc_type2_resource; + num = ARRAY_SIZE(rtc_type2_resource); + break; + default: + retval = -ENODEV; + goto err_free_device; + } + + retval = platform_device_add_resources(pdev, res, num); + if (retval) + goto err_free_device; + + retval = platform_device_add(pdev); + if (retval) + goto err_free_device; + + return 0; + +err_free_device: + platform_device_put(pdev); + + return retval; +} +device_initcall(vr41xx_rtc_add); diff --git a/arch/mips/vr41xx/common/siu.c b/arch/mips/vr41xx/common/siu.c new file mode 100644 index 000000000000..a1e774142163 --- /dev/null +++ b/arch/mips/vr41xx/common/siu.c @@ -0,0 +1,120 @@ +/* + * NEC VR4100 series SIU platform device. + * + * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> +#include <linux/serial_core.h> + +#include <asm/cpu.h> +#include <asm/vr41xx/siu.h> + +static unsigned int siu_type1_ports[SIU_PORTS_MAX] __initdata = { + PORT_VR41XX_SIU, + PORT_UNKNOWN, +}; + +static struct resource siu_type1_resource[] __initdata = { + { + .start = 0x0c000000, + .end = 0x0c00000a, + .flags = IORESOURCE_MEM, + }, + { + .start = SIU_IRQ, + .end = SIU_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static unsigned int siu_type2_ports[SIU_PORTS_MAX] __initdata = { + PORT_VR41XX_SIU, + PORT_VR41XX_DSIU, +}; + +static struct resource siu_type2_resource[] __initdata = { + { + .start = 0x0f000800, + .end = 0x0f00080a, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x0f000820, + .end = 0x0f000829, + .flags = IORESOURCE_MEM, + }, + { + .start = SIU_IRQ, + .end = SIU_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .start = DSIU_IRQ, + .end = DSIU_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static int __init vr41xx_siu_add(void) +{ + struct platform_device *pdev; + struct resource *res; + unsigned int num; + int retval; + + pdev = platform_device_alloc("SIU", -1); + if (!pdev) + return -ENOMEM; + + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + pdev->dev.platform_data = siu_type1_ports; + res = siu_type1_resource; + num = ARRAY_SIZE(siu_type1_resource); + break; + case CPU_VR4122: + case CPU_VR4131: + case CPU_VR4133: + pdev->dev.platform_data = siu_type2_ports; + res = siu_type2_resource; + num = ARRAY_SIZE(siu_type2_resource); + break; + default: + retval = -ENODEV; + goto err_free_device; + } + + retval = platform_device_add_resources(pdev, res, num); + if (retval) + goto err_free_device; + + retval = platform_device_add(pdev); + if (retval) + goto err_free_device; + + return 0; + +err_free_device: + platform_device_put(pdev); + + return retval; +} +device_initcall(vr41xx_siu_add); diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index ef683ebd367c..a31c6d2c061f 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -815,7 +815,7 @@ config SGI_IP27_RTC config GEN_RTC tristate "Generic /dev/rtc emulation" - depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390 && !SUPERH + depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index 0cea8d4907df..e5ed09192be8 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c @@ -19,18 +19,17 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <linux/platform_device.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/init.h> -#include <linux/irq.h> #include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/types.h> -#include <asm/cpu.h> #include <asm/io.h> #include <asm/vr41xx/giu.h> #include <asm/vr41xx/irq.h> @@ -44,18 +43,6 @@ static int major; /* default is dynamic major device number */ module_param(major, int, 0); MODULE_PARM_DESC(major, "Major device number"); -#define GIU_TYPE1_START 0x0b000100UL -#define GIU_TYPE1_SIZE 0x20UL - -#define GIU_TYPE2_START 0x0f000140UL -#define GIU_TYPE2_SIZE 0x20UL - -#define GIU_TYPE3_START 0x0f000140UL -#define GIU_TYPE3_SIZE 0x28UL - -#define GIU_PULLUPDOWN_START 0x0b0002e0UL -#define GIU_PULLUPDOWN_SIZE 0x04UL - #define GIUIOSELL 0x00 #define GIUIOSELH 0x02 #define GIUPIODL 0x04 @@ -89,8 +76,6 @@ MODULE_PARM_DESC(major, "Major device number"); #define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100 static spinlock_t giu_lock; -static struct resource *giu_resource1; -static struct resource *giu_resource2; static unsigned long giu_flags; static unsigned int giu_nr_pins; @@ -234,7 +219,7 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_ giu_set(GIUINTHTSELL, mask); else giu_clear(GIUINTHTSELL, mask); - if (current_cpu_data.cputype == CPU_VR4133) { + if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { switch (trigger) { case IRQ_TRIGGER_EDGE_FALLING: giu_set(GIUFEDGEINHL, mask); @@ -269,7 +254,7 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_ giu_set(GIUINTHTSELH, mask); else giu_clear(GIUINTHTSELH, mask); - if (current_cpu_data.cputype == CPU_VR4133) { + if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { switch (trigger) { case IRQ_TRIGGER_EDGE_FALLING: giu_set(GIUFEDGEINHH, mask); @@ -298,7 +283,6 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_ giu_write(GIUINTSTATH, mask); } } - EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger); void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) @@ -321,7 +305,6 @@ void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) giu_write(GIUINTSTATH, mask); } } - EXPORT_SYMBOL_GPL(vr41xx_set_irq_level); gpio_data_t vr41xx_gpio_get_pin(unsigned int pin) @@ -350,7 +333,6 @@ gpio_data_t vr41xx_gpio_get_pin(unsigned int pin) return GPIO_DATA_LOW; } - EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin); int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data) @@ -388,7 +370,6 @@ int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data) return 0; } - EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin); int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir) @@ -438,7 +419,6 @@ int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir) return 0; } - EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction); int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) @@ -477,7 +457,6 @@ int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) return 0; } - EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown); static ssize_t gpio_read(struct file *file, char __user *buf, size_t len, @@ -596,61 +575,40 @@ static const struct file_operations gpio_fops = { static int __devinit giu_probe(struct platform_device *dev) { - unsigned long start, size, flags = 0; - unsigned int nr_pins = 0, trigger, i, pin; - struct resource *res1, *res2 = NULL; - void *base; + struct resource *res; + unsigned int trigger, i, pin; struct irq_chip *chip; - int retval; - - switch (current_cpu_data.cputype) { - case CPU_VR4111: - case CPU_VR4121: - start = GIU_TYPE1_START; - size = GIU_TYPE1_SIZE; - flags = GPIO_HAS_PULLUPDOWN_IO; - nr_pins = 50; + int irq, retval; + + switch (dev->id) { + case GPIO_50PINS_PULLUPDOWN: + giu_flags = GPIO_HAS_PULLUPDOWN_IO; + giu_nr_pins = 50; break; - case CPU_VR4122: - case CPU_VR4131: - start = GIU_TYPE2_START; - size = GIU_TYPE2_SIZE; - nr_pins = 36; + case GPIO_36PINS: + giu_nr_pins = 36; break; - case CPU_VR4133: - start = GIU_TYPE3_START; - size = GIU_TYPE3_SIZE; - flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; - nr_pins = 48; + case GPIO_48PINS_EDGE_SELECT: + giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; + giu_nr_pins = 48; break; default: + printk(KERN_ERR "GIU: unknown ID %d\n", dev->id); return -ENODEV; } - res1 = request_mem_region(start, size, "GIU"); - if (res1 == NULL) + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!res) return -EBUSY; - base = ioremap(start, size); - if (base == NULL) { - release_resource(res1); + giu_base = ioremap(res->start, res->end - res->start + 1); + if (!giu_base) return -ENOMEM; - } - - if (flags & GPIO_HAS_PULLUPDOWN_IO) { - res2 = request_mem_region(GIU_PULLUPDOWN_START, GIU_PULLUPDOWN_SIZE, "GIU"); - if (res2 == NULL) { - iounmap(base); - release_resource(res1); - return -EBUSY; - } - } retval = register_chrdev(major, "GIU", &gpio_fops); if (retval < 0) { - iounmap(base); - release_resource(res1); - release_resource(res2); + iounmap(giu_base); + giu_base = NULL; return retval; } @@ -660,11 +618,6 @@ static int __devinit giu_probe(struct platform_device *dev) } spin_lock_init(&giu_lock); - giu_base = base; - giu_resource1 = res1; - giu_resource2 = res2; - giu_flags = flags; - giu_nr_pins = nr_pins; giu_write(GIUINTENL, 0); giu_write(GIUINTENH, 0); @@ -685,22 +638,23 @@ static int __devinit giu_probe(struct platform_device *dev) } - return cascade_irq(GIUINT_IRQ, giu_get_irq); + irq = platform_get_irq(dev, 0); + if (irq < 0 || irq >= NR_IRQS) + return -EBUSY; + + return cascade_irq(irq, giu_get_irq); } static int __devexit giu_remove(struct platform_device *dev) { - iounmap(giu_base); - - release_resource(giu_resource1); - if (giu_flags & GPIO_HAS_PULLUPDOWN_IO) - release_resource(giu_resource2); + if (giu_base) { + iounmap(giu_base); + giu_base = NULL; + } return 0; } -static struct platform_device *giu_platform_device; - static struct platform_driver giu_device_driver = { .probe = giu_probe, .remove = __devexit_p(giu_remove), @@ -712,30 +666,12 @@ static struct platform_driver giu_device_driver = { static int __init vr41xx_giu_init(void) { - int retval; - - giu_platform_device = platform_device_alloc("GIU", -1); - if (!giu_platform_device) - return -ENOMEM; - - retval = platform_device_add(giu_platform_device); - if (retval < 0) { - platform_device_put(giu_platform_device); - return retval; - } - - retval = platform_driver_register(&giu_device_driver); - if (retval < 0) - platform_device_unregister(giu_platform_device); - - return retval; + return platform_driver_register(&giu_device_driver); } static void __exit vr41xx_giu_exit(void) { platform_driver_unregister(&giu_device_driver); - - platform_device_unregister(giu_platform_device); } module_init(vr41xx_giu_init); diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index af7596ef29e2..ce2f78de7a80 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -17,10 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/err.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/ioport.h> -#include <linux/irq.h> +#include <linux/interrupt.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/rtc.h> @@ -30,25 +31,11 @@ #include <asm/div64.h> #include <asm/io.h> #include <asm/uaccess.h> -#include <asm/vr41xx/irq.h> MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); MODULE_DESCRIPTION("NEC VR4100 series RTC driver"); MODULE_LICENSE("GPL"); -#define RTC1_TYPE1_START 0x0b0000c0UL -#define RTC1_TYPE1_END 0x0b0000dfUL -#define RTC2_TYPE1_START 0x0b0001c0UL -#define RTC2_TYPE1_END 0x0b0001dfUL - -#define RTC1_TYPE2_START 0x0f000100UL -#define RTC1_TYPE2_END 0x0f00011fUL -#define RTC2_TYPE2_START 0x0f000120UL -#define RTC2_TYPE2_END 0x0f00013fUL - -#define RTC1_SIZE 0x20 -#define RTC2_SIZE 0x20 - /* RTC 1 registers */ #define ETIMELREG 0x00 #define ETIMEMREG 0x02 @@ -98,13 +85,8 @@ static char rtc_name[] = "RTC"; static unsigned long periodic_frequency; static unsigned long periodic_count; static unsigned int alarm_enabled; - -struct resource rtc_resource[2] = { - { .name = rtc_name, - .flags = IORESOURCE_MEM, }, - { .name = rtc_name, - .flags = IORESOURCE_MEM, }, -}; +static int aie_irq = -1; +static int pie_irq = -1; static inline unsigned long read_elapsed_second(void) { @@ -150,8 +132,8 @@ static void vr41xx_rtc_release(struct device *dev) spin_unlock_irq(&rtc_lock); - disable_irq(ELAPSEDTIME_IRQ); - disable_irq(RTCLONG1_IRQ); + disable_irq(aie_irq); + disable_irq(pie_irq); } static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time) @@ -209,14 +191,14 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) spin_lock_irq(&rtc_lock); if (alarm_enabled) - disable_irq(ELAPSEDTIME_IRQ); + disable_irq(aie_irq); rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); if (wkalrm->enabled) - enable_irq(ELAPSEDTIME_IRQ); + enable_irq(aie_irq); alarm_enabled = wkalrm->enabled; @@ -234,7 +216,7 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long spin_lock_irq(&rtc_lock); if (!alarm_enabled) { - enable_irq(ELAPSEDTIME_IRQ); + enable_irq(aie_irq); alarm_enabled = 1; } @@ -244,17 +226,17 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long spin_lock_irq(&rtc_lock); if (alarm_enabled) { - disable_irq(ELAPSEDTIME_IRQ); + disable_irq(aie_irq); alarm_enabled = 0; } spin_unlock_irq(&rtc_lock); break; case RTC_PIE_ON: - enable_irq(RTCLONG1_IRQ); + enable_irq(pie_irq); break; case RTC_PIE_OFF: - disable_irq(RTCLONG1_IRQ); + disable_irq(pie_irq); break; case RTC_IRQP_READ: return put_user(periodic_frequency, (unsigned long __user *)arg); @@ -331,31 +313,37 @@ static const struct rtc_class_ops vr41xx_rtc_ops = { static int __devinit rtc_probe(struct platform_device *pdev) { + struct resource *res; struct rtc_device *rtc; - unsigned int irq; int retval; - if (pdev->num_resources != 2) + if (pdev->num_resources != 4) return -EBUSY; - rtc1_base = ioremap(pdev->resource[0].start, RTC1_SIZE); - if (rtc1_base == NULL) + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) return -EBUSY; - rtc2_base = ioremap(pdev->resource[1].start, RTC2_SIZE); - if (rtc2_base == NULL) { - iounmap(rtc1_base); - rtc1_base = NULL; + rtc1_base = ioremap(res->start, res->end - res->start + 1); + if (!rtc1_base) return -EBUSY; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + retval = -EBUSY; + goto err_rtc1_iounmap; + } + + rtc2_base = ioremap(res->start, res->end - res->start + 1); + if (!rtc2_base) { + retval = -EBUSY; + goto err_rtc1_iounmap; } rtc = rtc_device_register(rtc_name, &pdev->dev, &vr41xx_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { - iounmap(rtc1_base); - iounmap(rtc2_base); - rtc1_base = NULL; - rtc2_base = NULL; - return PTR_ERR(rtc); + retval = PTR_ERR(rtc); + goto err_iounmap_all; } spin_lock_irq(&rtc_lock); @@ -368,35 +356,50 @@ static int __devinit rtc_probe(struct platform_device *pdev) spin_unlock_irq(&rtc_lock); - irq = ELAPSEDTIME_IRQ; - retval = request_irq(irq, elapsedtime_interrupt, IRQF_DISABLED, - "elapsed_time", pdev); - if (retval == 0) { - irq = RTCLONG1_IRQ; - retval = request_irq(irq, rtclong1_interrupt, IRQF_DISABLED, - "rtclong1", pdev); + aie_irq = platform_get_irq(pdev, 0); + if (aie_irq < 0 || aie_irq >= NR_IRQS) { + retval = -EBUSY; + goto err_device_unregister; } - if (retval < 0) { - printk(KERN_ERR "rtc: IRQ%d is busy\n", irq); - rtc_device_unregister(rtc); - if (irq == RTCLONG1_IRQ) - free_irq(ELAPSEDTIME_IRQ, NULL); - iounmap(rtc1_base); - iounmap(rtc2_base); - rtc1_base = NULL; - rtc2_base = NULL; - return retval; - } + retval = request_irq(aie_irq, elapsedtime_interrupt, IRQF_DISABLED, + "elapsed_time", pdev); + if (retval < 0) + goto err_device_unregister; + + pie_irq = platform_get_irq(pdev, 1); + if (pie_irq < 0 || pie_irq >= NR_IRQS) + goto err_free_irq; + + retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, + "rtclong1", pdev); + if (retval < 0) + goto err_free_irq; platform_set_drvdata(pdev, rtc); - disable_irq(ELAPSEDTIME_IRQ); - disable_irq(RTCLONG1_IRQ); + disable_irq(aie_irq); + disable_irq(pie_irq); printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n"); return 0; + +err_free_irq: + free_irq(aie_irq, pdev); + +err_device_unregister: + rtc_device_unregister(rtc); + +err_iounmap_all: + iounmap(rtc2_base); + rtc2_base = NULL; + +err_rtc1_iounmap: + iounmap(rtc1_base); + rtc1_base = NULL; + + return retval; } static int __devexit rtc_remove(struct platform_device *pdev) @@ -404,23 +407,21 @@ static int __devexit rtc_remove(struct platform_device *pdev) struct rtc_device *rtc; rtc = platform_get_drvdata(pdev); - if (rtc != NULL) + if (rtc) rtc_device_unregister(rtc); platform_set_drvdata(pdev, NULL); - free_irq(ELAPSEDTIME_IRQ, NULL); - free_irq(RTCLONG1_IRQ, NULL); - if (rtc1_base != NULL) + free_irq(aie_irq, pdev); + free_irq(pie_irq, pdev); + if (rtc1_base) iounmap(rtc1_base); - if (rtc2_base != NULL) + if (rtc2_base) iounmap(rtc2_base); return 0; } -static struct platform_device *rtc_platform_device; - static struct platform_driver rtc_platform_driver = { .probe = rtc_probe, .remove = __devexit_p(rtc_remove), @@ -432,55 +433,12 @@ static struct platform_driver rtc_platform_driver = { static int __init vr41xx_rtc_init(void) { - int retval; - - switch (current_cpu_data.cputype) { - case CPU_VR4111: - case CPU_VR4121: - rtc_resource[0].start = RTC1_TYPE1_START; - rtc_resource[0].end = RTC1_TYPE1_END; - rtc_resource[1].start = RTC2_TYPE1_START; - rtc_resource[1].end = RTC2_TYPE1_END; - break; - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4133: - rtc_resource[0].start = RTC1_TYPE2_START; - rtc_resource[0].end = RTC1_TYPE2_END; - rtc_resource[1].start = RTC2_TYPE2_START; - rtc_resource[1].end = RTC2_TYPE2_END; - break; - default: - return -ENODEV; - break; - } - - rtc_platform_device = platform_device_alloc("RTC", -1); - if (rtc_platform_device == NULL) - return -ENOMEM; - - retval = platform_device_add_resources(rtc_platform_device, - rtc_resource, ARRAY_SIZE(rtc_resource)); - - if (retval == 0) - retval = platform_device_add(rtc_platform_device); - - if (retval < 0) { - platform_device_put(rtc_platform_device); - return retval; - } - - retval = platform_driver_register(&rtc_platform_driver); - if (retval < 0) - platform_device_unregister(rtc_platform_device); - - return retval; + return platform_driver_register(&rtc_platform_driver); } static void __exit vr41xx_rtc_exit(void) { platform_driver_unregister(&rtc_platform_driver); - platform_device_unregister(rtc_platform_device); } module_init(vr41xx_rtc_init); diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index cf0e663b42ed..85309acb75f6 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c @@ -1,7 +1,7 @@ /* * Driver for NEC VR4100 series Serial Interface Unit. * - * Copyright (C) 2004-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> + * Copyright (C) 2004-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> * * Based on drivers/serial/8250.c, by Russell King. * @@ -25,12 +25,12 @@ #endif #include <linux/console.h> -#include <linux/platform_device.h> -#include <linux/err.h> -#include <linux/ioport.h> +#include <linux/errno.h> #include <linux/init.h> #include <linux/interrupt.h> +#include <linux/ioport.h> #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/serial.h> #include <linux/serial_core.h> #include <linux/serial_reg.h> @@ -38,11 +38,9 @@ #include <linux/tty_flip.h> #include <asm/io.h> -#include <asm/vr41xx/irq.h> #include <asm/vr41xx/siu.h> #include <asm/vr41xx/vr41xx.h> -#define SIU_PORTS_MAX 2 #define SIU_BAUD_BASE 1152000 #define SIU_MAJOR 204 #define SIU_MINOR_BASE 82 @@ -60,32 +58,13 @@ #define IRUSESEL 0x02 #define SIRSEL 0x01 -struct siu_port { - unsigned int type; - unsigned int irq; - unsigned long start; -}; - -static const struct siu_port siu_type1_ports[] = { - { .type = PORT_VR41XX_SIU, - .irq = SIU_IRQ, - .start = 0x0c000000UL, }, -}; - -#define SIU_TYPE1_NR_PORTS (sizeof(siu_type1_ports) / sizeof(struct siu_port)) - -static const struct siu_port siu_type2_ports[] = { - { .type = PORT_VR41XX_SIU, - .irq = SIU_IRQ, - .start = 0x0f000800UL, }, - { .type = PORT_VR41XX_DSIU, - .irq = DSIU_IRQ, - .start = 0x0f000820UL, }, +static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = { + [0 ... SIU_PORTS_MAX-1] = { + .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock), + .irq = -1, + }, }; -#define SIU_TYPE2_NR_PORTS (sizeof(siu_type2_ports) / sizeof(struct siu_port)) - -static struct uart_port siu_uart_ports[SIU_PORTS_MAX]; static uint8_t lsr_break_flag[SIU_PORTS_MAX]; #define siu_read(port, offset) readb((port)->membase + (offset)) @@ -110,7 +89,6 @@ void vr41xx_select_siu_interface(siu_interface_t interface) spin_unlock_irqrestore(&port->lock, flags); } - EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface); void vr41xx_use_irda(irda_use_t use) @@ -132,7 +110,6 @@ void vr41xx_use_irda(irda_use_t use) spin_unlock_irqrestore(&port->lock, flags); } - EXPORT_SYMBOL_GPL(vr41xx_use_irda); void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed) @@ -166,7 +143,6 @@ void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed) spin_unlock_irqrestore(&port->lock, flags); } - EXPORT_SYMBOL_GPL(vr41xx_select_irda_module); static inline void siu_clear_fifo(struct uart_port *port) @@ -177,21 +153,6 @@ static inline void siu_clear_fifo(struct uart_port *port) siu_write(port, UART_FCR, 0); } -static inline int siu_probe_ports(void) -{ - switch (current_cpu_data.cputype) { - case CPU_VR4111: - case CPU_VR4121: - return SIU_TYPE1_NR_PORTS; - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4133: - return SIU_TYPE2_NR_PORTS; - } - - return 0; -} - static inline unsigned long siu_port_size(struct uart_port *port) { switch (port->type) { @@ -206,21 +167,10 @@ static inline unsigned long siu_port_size(struct uart_port *port) static inline unsigned int siu_check_type(struct uart_port *port) { - switch (current_cpu_data.cputype) { - case CPU_VR4111: - case CPU_VR4121: - if (port->line == 0) - return PORT_VR41XX_SIU; - break; - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4133: - if (port->line == 0) - return PORT_VR41XX_SIU; - else if (port->line == 1) - return PORT_VR41XX_DSIU; - break; - } + if (port->line == 0) + return PORT_VR41XX_SIU; + if (port->line == 1 && port->irq != -1) + return PORT_VR41XX_DSIU; return PORT_UNKNOWN; } @@ -751,44 +701,34 @@ static struct uart_ops siu_uart_ops = { .verify_port = siu_verify_port, }; -static int siu_init_ports(void) +static int siu_init_ports(struct platform_device *pdev) { - const struct siu_port *siu; struct uart_port *port; - int i, num; + struct resource *res; + int *type = pdev->dev.platform_data; + int i; - switch (current_cpu_data.cputype) { - case CPU_VR4111: - case CPU_VR4121: - siu = siu_type1_ports; - break; - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4133: - siu = siu_type2_ports; - break; - default: + if (!type) return 0; - } port = siu_uart_ports; - num = siu_probe_ports(); - for (i = 0; i < num; i++) { - spin_lock_init(&port->lock); - port->irq = siu->irq; + for (i = 0; i < SIU_PORTS_MAX; i++) { + port->type = type[i]; + if (port->type == PORT_UNKNOWN) + continue; + port->irq = platform_get_irq(pdev, i); port->uartclk = SIU_BAUD_BASE * 16; port->fifosize = 16; port->regshift = 0; port->iotype = UPIO_MEM; port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; - port->type = siu->type; port->line = i; - port->mapbase = siu->start; - siu++; + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + port->mapbase = res->start; port++; } - return num; + return i; } #ifdef CONFIG_SERIAL_VR41XX_CONSOLE @@ -883,13 +823,9 @@ static struct console siu_console = { static int __devinit siu_console_init(void) { struct uart_port *port; - int num, i; - - num = siu_init_ports(); - if (num <= 0) - return -ENODEV; + int i; - for (i = 0; i < num; i++) { + for (i = 0; i < SIU_PORTS_MAX; i++) { port = &siu_uart_ports[i]; port->ops = &siu_uart_ops; } @@ -920,7 +856,7 @@ static int __devinit siu_probe(struct platform_device *dev) struct uart_port *port; int num, i, retval; - num = siu_init_ports(); + num = siu_init_ports(dev); if (num <= 0) return -ENODEV; @@ -998,8 +934,6 @@ static int siu_resume(struct platform_device *dev) return 0; } -static struct platform_device *siu_platform_device; - static struct platform_driver siu_device_driver = { .probe = siu_probe, .remove = __devexit_p(siu_remove), @@ -1013,29 +947,12 @@ static struct platform_driver siu_device_driver = { static int __init vr41xx_siu_init(void) { - int retval; - - siu_platform_device = platform_device_alloc("SIU", -1); - if (!siu_platform_device) - return -ENOMEM; - - retval = platform_device_add(siu_platform_device); - if (retval < 0) { - platform_device_put(siu_platform_device); - return retval; - } - - retval = platform_driver_register(&siu_device_driver); - if (retval < 0) - platform_device_unregister(siu_platform_device); - - return retval; + return platform_driver_register(&siu_device_driver); } static void __exit vr41xx_siu_exit(void) { platform_driver_unregister(&siu_device_driver); - platform_device_unregister(siu_platform_device); } module_init(vr41xx_siu_init); diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c index 4fff61b32dcb..ed979f13908a 100644 --- a/drivers/tc/zs.c +++ b/drivers/tc/zs.c @@ -136,14 +136,14 @@ struct dec_serial *zs_chain; /* list of all channels */ struct tty_struct zs_ttys[NUM_CHANNELS]; #ifdef CONFIG_SERIAL_DEC_CONSOLE -static struct console sercons; +static struct console zs_console; #endif #if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \ !defined(MODULE) static unsigned long break_pressed; /* break, really ... */ #endif -static unsigned char zs_init_regs[16] = { +static unsigned char zs_init_regs[16] __initdata = { 0, /* write 0 */ 0, /* write 1 */ 0, /* write 2 */ @@ -383,7 +383,7 @@ static void receive_chars(struct dec_serial *info) #if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \ !defined(MODULE) - if (break_pressed && info->line == sercons.index) { + if (break_pressed && info->line == zs_console.index) { /* Ignore the null char got when BREAK is removed. */ if (ch == 0) continue; @@ -446,7 +446,7 @@ static void status_handle(struct dec_serial *info) if ((stat & BRK_ABRT) && !(info->read_reg_zero & BRK_ABRT)) { #if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \ !defined(MODULE) - if (info->line == sercons.index) { + if (info->line == zs_console.index) { if (!break_pressed) break_pressed = jiffies; } else @@ -1557,9 +1557,9 @@ static int rs_open(struct tty_struct *tty, struct file * filp) } #ifdef CONFIG_SERIAL_DEC_CONSOLE - if (sercons.cflag && sercons.index == line) { - tty->termios->c_cflag = sercons.cflag; - sercons.cflag = 0; + if (zs_console.cflag && zs_console.index == line) { + tty->termios->c_cflag = zs_console.cflag; + zs_console.cflag = 0; change_speed(info); } #endif @@ -1581,7 +1581,7 @@ static void __init show_serial_version(void) /* Initialize Z8530s zs_channels */ -static void probe_sccs(void) +static void __init probe_sccs(void) { struct dec_serial **pp; int i, n, n_chips = 0, n_channels, chip, channel; @@ -1923,7 +1923,7 @@ static struct tty_driver *serial_console_device(struct console *c, int *index) * - initialize the serial port * Return non-zero if we didn't find a serial port. */ -static int serial_console_setup(struct console *co, char *options) +static int __init serial_console_setup(struct console *co, char *options) { struct dec_serial *info; int baud = 9600; @@ -2069,7 +2069,7 @@ static int serial_console_setup(struct console *co, char *options) return 0; } -static struct console sercons = { +static struct console zs_console = { .name = "ttyS", .write = serial_console_write, .device = serial_console_device, @@ -2083,7 +2083,7 @@ static struct console sercons = { */ void __init zs_serial_console_init(void) { - register_console(&sercons); + register_console(&zs_console); } #endif /* ifdef CONFIG_SERIAL_DEC_CONSOLE */ diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 12bcc1f9fba9..7ba92890ea13 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -212,7 +212,8 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, */ if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) && flags == _CACHE_UNCACHED) - return (void __iomem *)CKSEG1ADDR(phys_addr); + return (void __iomem *) + (unsigned long)CKSEG1ADDR(phys_addr); } return __ioremap(offset, size, flags); diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h index 3ca6a076124d..97102ebc54b1 100644 --- a/include/asm-mips/irq.h +++ b/include/asm-mips/irq.h @@ -24,7 +24,7 @@ static inline int irq_canonicalize(int irq) #define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */ #endif -#ifdef CONFIG_MIPS_MT_SMTC +#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP /* * Clear interrupt mask handling "backstop" if irq_hwmask * entry so indicates. This implies that the ack() or end() diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 706b3691f57e..18f47f1e8cd5 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -707,10 +707,10 @@ do { \ */ #define __read_64bit_c0_split(source, sel) \ ({ \ - unsigned long long val; \ - unsigned long flags; \ + unsigned long long __val; \ + unsigned long __flags; \ \ - local_irq_save(flags); \ + local_irq_save(__flags); \ if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ @@ -719,7 +719,7 @@ do { \ "dsrl\t%M0, %M0, 32\n\t" \ "dsrl\t%L0, %L0, 32\n\t" \ ".set\tmips0" \ - : "=r" (val)); \ + : "=r" (__val)); \ else \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ @@ -728,17 +728,17 @@ do { \ "dsrl\t%M0, %M0, 32\n\t" \ "dsrl\t%L0, %L0, 32\n\t" \ ".set\tmips0" \ - : "=r" (val)); \ - local_irq_restore(flags); \ + : "=r" (__val)); \ + local_irq_restore(__flags); \ \ - val; \ + __val; \ }) #define __write_64bit_c0_split(source, sel, val) \ do { \ - unsigned long flags; \ + unsigned long __flags; \ \ - local_irq_save(flags); \ + local_irq_save(__flags); \ if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ @@ -759,7 +759,7 @@ do { \ "dmtc0\t%L0, " #source ", " #sel "\n\t" \ ".set\tmips0" \ : : "r" (val)); \ - local_irq_restore(flags); \ + local_irq_restore(__flags); \ } while (0) #define read_c0_index() __read_32bit_c0_register($0, 0) diff --git a/include/asm-mips/rtc.h b/include/asm-mips/rtc.h deleted file mode 100644 index 82ad401c7dca..000000000000 --- a/include/asm-mips/rtc.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * include/asm-mips/rtc.h - * - * (Really an interface for drivers/char/genrtc.c) - * - * Copyright (C) 2004 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * Please read the COPYING file for all license details. - */ - -#ifndef _MIPS_RTC_H -#define _MIPS_RTC_H - -#ifdef __KERNEL__ - -#include <linux/rtc.h> -#include <asm/time.h> - -#define RTC_PIE 0x40 /* periodic interrupt enable */ -#define RTC_AIE 0x20 /* alarm interrupt enable */ -#define RTC_UIE 0x10 /* update-finished interrupt enable */ - -/* some dummy definitions */ -#define RTC_BATT_BAD 0x100 /* battery bad */ -#define RTC_SQWE 0x08 /* enable square-wave output */ -#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ -#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ -#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ - -static inline unsigned int get_rtc_time(struct rtc_time *time) -{ - unsigned long nowtime; - - nowtime = rtc_mips_get_time(); - to_tm(nowtime, time); - time->tm_year -= 1900; - - return RTC_24H; -} - -static inline int set_rtc_time(struct rtc_time *time) -{ - unsigned long nowtime; - int ret; - - nowtime = mktime(time->tm_year+1900, time->tm_mon+1, - time->tm_mday, time->tm_hour, time->tm_min, - time->tm_sec); - ret = rtc_mips_set_time(nowtime); - - return ret; -} - -static inline unsigned int get_rtc_ss(void) -{ - struct rtc_time h; - - get_rtc_time(&h); - return h.tm_sec; -} - -static inline int get_rtc_pll(struct rtc_pll_info *pll) -{ - return -EINVAL; -} - -static inline int set_rtc_pll(struct rtc_pll_info *pll) -{ - return -EINVAL; -} -#endif -#endif diff --git a/include/asm-mips/tlbdebug.h b/include/asm-mips/tlbdebug.h index fff7a73e22d0..bb8f5c29c3d9 100644 --- a/include/asm-mips/tlbdebug.h +++ b/include/asm-mips/tlbdebug.h @@ -11,10 +11,6 @@ /* * TLB debugging functions: */ -extern void dump_tlb(int first, int last); extern void dump_tlb_all(void); -extern void dump_tlb_wired(void); -extern void dump_tlb_addr(unsigned long addr); -extern void dump_tlb_nonwired(void); #endif /* __ASM_TLBDEBUG_H */ diff --git a/include/asm-mips/vr41xx/giu.h b/include/asm-mips/vr41xx/giu.h index 8109cda557dc..0bcdd3a5c256 100644 --- a/include/asm-mips/vr41xx/giu.h +++ b/include/asm-mips/vr41xx/giu.h @@ -20,6 +20,15 @@ #ifndef __NEC_VR41XX_GIU_H #define __NEC_VR41XX_GIU_H +/* + * NEC VR4100 series GIU platform device IDs. + */ +enum { + GPIO_50PINS_PULLUPDOWN, + GPIO_36PINS, + GPIO_48PINS_EDGE_SELECT, +}; + typedef enum { IRQ_TRIGGER_LEVEL, IRQ_TRIGGER_EDGE, diff --git a/include/asm-mips/vr41xx/siu.h b/include/asm-mips/vr41xx/siu.h index 1fcf6e8082b4..98cdb4096485 100644 --- a/include/asm-mips/vr41xx/siu.h +++ b/include/asm-mips/vr41xx/siu.h @@ -20,6 +20,8 @@ #ifndef __NEC_VR41XX_SIU_H #define __NEC_VR41XX_SIU_H +#define SIU_PORTS_MAX 2 + typedef enum { SIU_INTERFACE_RS232C, SIU_INTERFACE_IRDA, |