diff options
Diffstat (limited to 'arch/mips/tx4938/common')
-rw-r--r-- | arch/mips/tx4938/common/Makefile | 3 | ||||
-rw-r--r-- | arch/mips/tx4938/common/irq.c | 279 | ||||
-rw-r--r-- | arch/mips/tx4938/common/rtc_rx5c348.c | 192 |
3 files changed, 11 insertions, 463 deletions
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile index 2033ae77f632..8352eca67906 100644 --- a/arch/mips/tx4938/common/Makefile +++ b/arch/mips/tx4938/common/Makefile @@ -6,6 +6,7 @@ # unless it's something special (ie not a .c file). # -obj-y += prom.o setup.o irq.o rtc_rx5c348.o +obj-y += prom.o setup.o irq.o obj-$(CONFIG_KGDB) += dbgio.o +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c index 3a2dbfc25014..c059b899d120 100644 --- a/arch/mips/tx4938/common/irq.c +++ b/arch/mips/tx4938/common/irq.c @@ -11,284 +11,21 @@ * * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) */ -#include <linux/errno.h> #include <linux/init.h> -#include <linux/kernel_stat.h> -#include <linux/module.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> #include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/timex.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/irq.h> -#include <asm/bitops.h> -#include <asm/bootinfo.h> -#include <asm/io.h> -#include <asm/irq.h> +#include <asm/irq_cpu.h> #include <asm/mipsregs.h> -#include <asm/system.h> -#include <asm/wbflush.h> #include <asm/tx4938/rbtx4938.h> -/**********************************************************************************/ -/* Forwad definitions for all pic's */ -/**********************************************************************************/ - -static void tx4938_irq_cp0_enable(unsigned int irq); -static void tx4938_irq_cp0_disable(unsigned int irq); - -static void tx4938_irq_pic_enable(unsigned int irq); -static void tx4938_irq_pic_disable(unsigned int irq); - -/**********************************************************************************/ -/* Kernel structs for all pic's */ -/**********************************************************************************/ - -#define TX4938_CP0_NAME "TX4938-CP0" -static struct irq_chip tx4938_irq_cp0_type = { - .name = TX4938_CP0_NAME, - .ack = tx4938_irq_cp0_disable, - .mask = tx4938_irq_cp0_disable, - .mask_ack = tx4938_irq_cp0_disable, - .unmask = tx4938_irq_cp0_enable, -}; - -#define TX4938_PIC_NAME "TX4938-PIC" -static struct irq_chip tx4938_irq_pic_type = { - .name = TX4938_PIC_NAME, - .ack = tx4938_irq_pic_disable, - .mask = tx4938_irq_pic_disable, - .mask_ack = tx4938_irq_pic_disable, - .unmask = tx4938_irq_pic_enable, -}; - -static struct irqaction tx4938_irq_pic_action = { - .handler = no_action, - .flags = 0, - .mask = CPU_MASK_NONE, - .name = TX4938_PIC_NAME -}; - -/**********************************************************************************/ -/* Functions for cp0 */ -/**********************************************************************************/ - -#define tx4938_irq_cp0_mask(irq) ( 1 << ( irq-TX4938_IRQ_CP0_BEG+8 ) ) - -static void __init -tx4938_irq_cp0_init(void) -{ - int i; - - for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) - set_irq_chip_and_handler(i, &tx4938_irq_cp0_type, - handle_level_irq); -} - -static void -tx4938_irq_cp0_enable(unsigned int irq) -{ - set_c0_status(tx4938_irq_cp0_mask(irq)); -} - -static void -tx4938_irq_cp0_disable(unsigned int irq) -{ - clear_c0_status(tx4938_irq_cp0_mask(irq)); -} - -/**********************************************************************************/ -/* Functions for pic */ -/**********************************************************************************/ - -u32 -tx4938_irq_pic_addr(int irq) -{ - /* MVMCP -- need to formulize this */ - irq -= TX4938_IRQ_PIC_BEG; - - switch (irq) { - case 17: - case 16: - case 1: - case 0:{ - return (TX4938_MKA(TX4938_IRC_IRLVL0)); - } - case 19: - case 18: - case 3: - case 2:{ - return (TX4938_MKA(TX4938_IRC_IRLVL1)); - } - case 21: - case 20: - case 5: - case 4:{ - return (TX4938_MKA(TX4938_IRC_IRLVL2)); - } - case 23: - case 22: - case 7: - case 6:{ - return (TX4938_MKA(TX4938_IRC_IRLVL3)); - } - case 25: - case 24: - case 9: - case 8:{ - return (TX4938_MKA(TX4938_IRC_IRLVL4)); - } - case 27: - case 26: - case 11: - case 10:{ - return (TX4938_MKA(TX4938_IRC_IRLVL5)); - } - case 29: - case 28: - case 13: - case 12:{ - return (TX4938_MKA(TX4938_IRC_IRLVL6)); - } - case 31: - case 30: - case 15: - case 14:{ - return (TX4938_MKA(TX4938_IRC_IRLVL7)); - } - } - - return 0; -} - -u32 -tx4938_irq_pic_mask(int irq) -{ - /* MVMCP -- need to formulize this */ - irq -= TX4938_IRQ_PIC_BEG; - - switch (irq) { - case 31: - case 29: - case 27: - case 25: - case 23: - case 21: - case 19: - case 17:{ - return (0x07000000); - } - case 30: - case 28: - case 26: - case 24: - case 22: - case 20: - case 18: - case 16:{ - return (0x00070000); - } - case 15: - case 13: - case 11: - case 9: - case 7: - case 5: - case 3: - case 1:{ - return (0x00000700); - } - case 14: - case 12: - case 10: - case 8: - case 6: - case 4: - case 2: - case 0:{ - return (0x00000007); - } - } - return 0x00000000; -} - -static void -tx4938_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, unsigned set_bits) -{ - unsigned long val = 0; - - val = TX4938_RD(pic_reg); - val &= (~clr_bits); - val |= (set_bits); - TX4938_WR(pic_reg, val); - mmiowb(); - TX4938_RD(pic_reg); -} - -static void __init -tx4938_irq_pic_init(void) -{ - int i; - - for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) - set_irq_chip_and_handler(i, &tx4938_irq_pic_type, - handle_level_irq); - - setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); - - TX4938_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ - TX4938_WR(0xff1ff600, TX4938_RD(0xff1ff600) | 0x1); /* irq enable */ -} - -static void -tx4938_irq_pic_enable(unsigned int irq) -{ - tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), 0, - tx4938_irq_pic_mask(irq)); -} - -static void -tx4938_irq_pic_disable(unsigned int irq) -{ - tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), - tx4938_irq_pic_mask(irq), 0); -} - -/**********************************************************************************/ -/* Main init functions */ -/**********************************************************************************/ - void __init tx4938_irq_init(void) { - tx4938_irq_cp0_init(); - tx4938_irq_pic_init(); + mips_cpu_irq_init(); + txx9_irq_init(TX4938_IRC_REG); + set_irq_chained_handler(TX4938_IRQ_NEST_PIC_ON_CP0, handle_simple_irq); } -int -tx4938_irq_nested(void) -{ - int sw_irq = 0; - u32 level2; - - level2 = TX4938_RD(0xff1ff6a0); - if ((level2 & 0x10000) == 0) { - level2 &= 0x1f; - sw_irq = TX4938_IRQ_PIC_BEG + level2; - if (sw_irq == 26) { - { - extern int toshiba_rbtx4938_irq_nested(int sw_irq); - sw_irq = toshiba_rbtx4938_irq_nested(sw_irq); - } - } - } - - wbflush(); - return sw_irq; -} +int toshiba_rbtx4938_irq_nested(int irq); asmlinkage void plat_irq_dispatch(void) { @@ -297,8 +34,10 @@ asmlinkage void plat_irq_dispatch(void) if (pending & STATUSF_IP7) do_IRQ(TX4938_IRQ_CPU_TIMER); else if (pending & STATUSF_IP2) { - int irq = tx4938_irq_nested(); - if (irq) + int irq = txx9_irq(); + if (irq == TX4938_IRQ_PIC_BEG + TX4938_IR_INT(0)) + irq = toshiba_rbtx4938_irq_nested(irq); + if (irq >= 0) do_IRQ(irq); else spurious_interrupt(); diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c deleted file mode 100644 index 07f782fc0725..000000000000 --- a/arch/mips/tx4938/common/rtc_rx5c348.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * RTC routines for RICOH Rx5C348 SPI chip. - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/rtc.h> -#include <linux/time.h> -#include <linux/bcd.h> -#include <asm/time.h> -#include <asm/tx4938/spi.h> - -#define EPOCH 2000 - -/* registers */ -#define Rx5C348_REG_SECOND 0 -#define Rx5C348_REG_MINUTE 1 -#define Rx5C348_REG_HOUR 2 -#define Rx5C348_REG_WEEK 3 -#define Rx5C348_REG_DAY 4 -#define Rx5C348_REG_MONTH 5 -#define Rx5C348_REG_YEAR 6 -#define Rx5C348_REG_ADJUST 7 -#define Rx5C348_REG_ALARM_W_MIN 8 -#define Rx5C348_REG_ALARM_W_HOUR 9 -#define Rx5C348_REG_ALARM_W_WEEK 10 -#define Rx5C348_REG_ALARM_D_MIN 11 -#define Rx5C348_REG_ALARM_D_HOUR 12 -#define Rx5C348_REG_CTL1 14 -#define Rx5C348_REG_CTL2 15 - -/* register bits */ -#define Rx5C348_BIT_PM 0x20 /* REG_HOUR */ -#define Rx5C348_BIT_Y2K 0x80 /* REG_MONTH */ -#define Rx5C348_BIT_24H 0x20 /* REG_CTL1 */ -#define Rx5C348_BIT_XSTP 0x10 /* REG_CTL2 */ - -/* commands */ -#define Rx5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */ -#define Rx5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */ -#define Rx5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */ -#define Rx5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */ - -static struct spi_dev_desc srtc_dev_desc = { - .baud = 1000000, /* 1.0Mbps @ Vdd 2.0V */ - .tcss = 31, - .tcsh = 1, - .tcsr = 62, - /* 31us for Tcss (62us for Tcsr) is required for carry operation) */ - .byteorder = 1, /* MSB-First */ - .polarity = 0, /* High-Active */ - .phase = 1, /* Shift-Then-Sample */ - -}; -static int srtc_chipid; -static int srtc_24h; - -static inline int -spi_rtc_io(unsigned char *inbuf, unsigned char *outbuf, unsigned int count) -{ - unsigned char *inbufs[1], *outbufs[1]; - unsigned int incounts[2], outcounts[2]; - inbufs[0] = inbuf; - incounts[0] = count; - incounts[1] = 0; - outbufs[0] = outbuf; - outcounts[0] = count; - outcounts[1] = 0; - return txx9_spi_io(srtc_chipid, &srtc_dev_desc, - inbufs, incounts, outbufs, outcounts, 0); -} - -/* RTC-dependent code for time.c */ - -static int -rtc_rx5c348_set_time(unsigned long t) -{ - unsigned char inbuf[8]; - struct rtc_time tm; - u8 year, month, day, hour, minute, second, century; - - /* convert */ - to_tm(t, &tm); - - year = tm.tm_year % 100; - month = tm.tm_mon+1; /* tm_mon starts from 0 to 11 */ - day = tm.tm_mday; - hour = tm.tm_hour; - minute = tm.tm_min; - second = tm.tm_sec; - century = tm.tm_year / 100; - - inbuf[0] = Rx5C348_CMD_MW(Rx5C348_REG_SECOND); - BIN_TO_BCD(second); - inbuf[1] = second; - BIN_TO_BCD(minute); - inbuf[2] = minute; - - if (srtc_24h) { - BIN_TO_BCD(hour); - inbuf[3] = hour; - } else { - /* hour 0 is AM12, noon is PM12 */ - inbuf[3] = 0; - if (hour >= 12) - inbuf[3] = Rx5C348_BIT_PM; - hour = (hour + 11) % 12 + 1; - BIN_TO_BCD(hour); - inbuf[3] |= hour; - } - inbuf[4] = 0; /* ignore week */ - BIN_TO_BCD(day); - inbuf[5] = day; - BIN_TO_BCD(month); - inbuf[6] = month; - if (century >= 20) - inbuf[6] |= Rx5C348_BIT_Y2K; - BIN_TO_BCD(year); - inbuf[7] = year; - /* write in one transfer to avoid data inconsistency */ - return spi_rtc_io(inbuf, NULL, 8); -} - -static unsigned long -rtc_rx5c348_get_time(void) -{ - unsigned char inbuf[8], outbuf[8]; - unsigned int year, month, day, hour, minute, second; - - inbuf[0] = Rx5C348_CMD_MR(Rx5C348_REG_SECOND); - memset(inbuf + 1, 0, 7); - /* read in one transfer to avoid data inconsistency */ - if (spi_rtc_io(inbuf, outbuf, 8)) - return 0; - second = outbuf[1]; - BCD_TO_BIN(second); - minute = outbuf[2]; - BCD_TO_BIN(minute); - if (srtc_24h) { - hour = outbuf[3]; - BCD_TO_BIN(hour); - } else { - hour = outbuf[3] & ~Rx5C348_BIT_PM; - BCD_TO_BIN(hour); - hour %= 12; - if (outbuf[3] & Rx5C348_BIT_PM) - hour += 12; - } - day = outbuf[5]; - BCD_TO_BIN(day); - month = outbuf[6] & ~Rx5C348_BIT_Y2K; - BCD_TO_BIN(month); - year = outbuf[7]; - BCD_TO_BIN(year); - year += EPOCH; - - return mktime(year, month, day, hour, minute, second); -} - -void __init -rtc_rx5c348_init(int chipid) -{ - unsigned char inbuf[2], outbuf[2]; - srtc_chipid = chipid; - /* turn on RTC if it is not on */ - inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL2); - inbuf[1] = 0; - spi_rtc_io(inbuf, outbuf, 2); - if (outbuf[1] & Rx5C348_BIT_XSTP) { - inbuf[0] = Rx5C348_CMD_W(Rx5C348_REG_CTL2); - inbuf[1] = 0; - spi_rtc_io(inbuf, NULL, 2); - } - - inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL1); - inbuf[1] = 0; - spi_rtc_io(inbuf, outbuf, 2); - if (outbuf[1] & Rx5C348_BIT_24H) - srtc_24h = 1; - - /* set the function pointers */ - rtc_mips_get_time = rtc_rx5c348_get_time; - rtc_mips_set_time = rtc_rx5c348_set_time; -} |