/* * Toshiba RBTX4938 specific interrupt handlers * 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) */ /* IRQ Device 16 TX4938-CP0/00 Software 0 17 TX4938-CP0/01 Software 1 18 TX4938-CP0/02 Cascade TX4938-CP0 19 TX4938-CP0/03 Multiplexed -- do not use 20 TX4938-CP0/04 Multiplexed -- do not use 21 TX4938-CP0/05 Multiplexed -- do not use 22 TX4938-CP0/06 Multiplexed -- do not use 23 TX4938-CP0/07 CPU TIMER 24 TX4938-PIC/00 25 TX4938-PIC/01 26 TX4938-PIC/02 Cascade RBTX4938-IOC 27 TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet 28 TX4938-PIC/04 29 TX4938-PIC/05 TX4938 ETH1 30 TX4938-PIC/06 TX4938 ETH0 31 TX4938-PIC/07 32 TX4938-PIC/08 TX4938 SIO 0 33 TX4938-PIC/09 TX4938 SIO 1 34 TX4938-PIC/10 TX4938 DMA0 35 TX4938-PIC/11 TX4938 DMA1 36 TX4938-PIC/12 TX4938 DMA2 37 TX4938-PIC/13 TX4938 DMA3 38 TX4938-PIC/14 39 TX4938-PIC/15 40 TX4938-PIC/16 TX4938 PCIC 41 TX4938-PIC/17 TX4938 TMR0 42 TX4938-PIC/18 TX4938 TMR1 43 TX4938-PIC/19 TX4938 TMR2 44 TX4938-PIC/20 45 TX4938-PIC/21 46 TX4938-PIC/22 TX4938 PCIERR 47 TX4938-PIC/23 48 TX4938-PIC/24 49 TX4938-PIC/25 50 TX4938-PIC/26 51 TX4938-PIC/27 52 TX4938-PIC/28 53 TX4938-PIC/29 54 TX4938-PIC/30 55 TX4938-PIC/31 TX4938 SPI 56 RBTX4938-IOC/00 PCI-D 57 RBTX4938-IOC/01 PCI-C 58 RBTX4938-IOC/02 PCI-B 59 RBTX4938-IOC/03 PCI-A 60 RBTX4938-IOC/04 RTC 61 RBTX4938-IOC/05 ATA 62 RBTX4938-IOC/06 MODEM 63 RBTX4938-IOC/07 SWINT */ #include #include #include #include #include static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { .name = TOSHIBA_RBTX4938_IOC_NAME, .ack = toshiba_rbtx4938_irq_ioc_disable, .mask = toshiba_rbtx4938_irq_ioc_disable, .mask_ack = toshiba_rbtx4938_irq_ioc_disable, .unmask = toshiba_rbtx4938_irq_ioc_enable, }; static int toshiba_rbtx4938_irq_nested(int sw_irq) { u8 level3; level3 = readb(rbtx4938_imstat_addr); if (level3) /* must use fls so onboard ATA has priority */ sw_irq = RBTX4938_IRQ_IOC + fls(level3) - 1; return sw_irq; } /**********************************************************************************/ /* Functions for ioc */ /**********************************************************************************/ static void __init toshiba_rbtx4938_irq_ioc_init(void) { int i; for (i = RBTX4938_IRQ_IOC; i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++) set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, handle_level_irq); set_irq_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq); } static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq) { unsigned char v; v = readb(rbtx4938_imask_addr); v |= (1 << (irq - RBTX4938_IRQ_IOC)); writeb(v, rbtx4938_imask_addr); mmiowb(); } static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) { unsigned char v; v = readb(rbtx4938_imask_addr); v &= ~(1 << (irq - RBTX4938_IRQ_IOC)); writeb(v, rbtx4938_imask_addr); mmiowb(); } static int rbtx4938_irq_dispatch(int pending) { int irq; if (pending & STATUSF_IP7) irq = MIPS_CPU_IRQ_BASE + 7; else if (pending & STATUSF_IP2) { irq = txx9_irq(); if (irq == RBTX4938_IRQ_IOCINT) irq = toshiba_rbtx4938_irq_nested(irq); } else if (pending & STATUSF_IP1) irq = MIPS_CPU_IRQ_BASE + 0; else if (pending & STATUSF_IP0) irq = MIPS_CPU_IRQ_BASE + 1; else irq = -1; return irq; } void __init rbtx4938_irq_setup(void) { txx9_irq_dispatch = rbtx4938_irq_dispatch; /* Now, interrupt control disabled, */ /* all IRC interrupts are masked, */ /* all IRC interrupt mode are Low Active. */ /* mask all IOC interrupts */ writeb(0, rbtx4938_imask_addr); /* clear SoftInt interrupts */ writeb(0, rbtx4938_softint_addr); tx4938_irq_init(); toshiba_rbtx4938_irq_ioc_init(); /* Onboard 10M Ether: High Active */ set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH); }