^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Toshiba RBTX4938 specific interrupt handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2000-2001 Toshiba Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * terms of the GNU General Public License version 2. This program is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * licensed "as is" without any warranty of any kind, whether express
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * MIPS_CPU_IRQ_BASE+00 Software 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * MIPS_CPU_IRQ_BASE+01 Software 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * MIPS_CPU_IRQ_BASE+02 Cascade TX4938-CP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * MIPS_CPU_IRQ_BASE+03 Multiplexed -- do not use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * MIPS_CPU_IRQ_BASE+04 Multiplexed -- do not use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * MIPS_CPU_IRQ_BASE+05 Multiplexed -- do not use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * MIPS_CPU_IRQ_BASE+06 Multiplexed -- do not use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * MIPS_CPU_IRQ_BASE+07 CPU TIMER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * TXX9_IRQ_BASE+00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * TXX9_IRQ_BASE+01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * TXX9_IRQ_BASE+02 Cascade RBTX4938-IOC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * TXX9_IRQ_BASE+03 RBTX4938 RTL-8019AS Ethernet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * TXX9_IRQ_BASE+04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * TXX9_IRQ_BASE+05 TX4938 ETH1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * TXX9_IRQ_BASE+06 TX4938 ETH0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * TXX9_IRQ_BASE+07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * TXX9_IRQ_BASE+08 TX4938 SIO 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * TXX9_IRQ_BASE+09 TX4938 SIO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * TXX9_IRQ_BASE+10 TX4938 DMA0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * TXX9_IRQ_BASE+11 TX4938 DMA1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * TXX9_IRQ_BASE+12 TX4938 DMA2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * TXX9_IRQ_BASE+13 TX4938 DMA3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * TXX9_IRQ_BASE+14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * TXX9_IRQ_BASE+15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * TXX9_IRQ_BASE+16 TX4938 PCIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * TXX9_IRQ_BASE+17 TX4938 TMR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * TXX9_IRQ_BASE+18 TX4938 TMR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * TXX9_IRQ_BASE+19 TX4938 TMR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * TXX9_IRQ_BASE+20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * TXX9_IRQ_BASE+21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * TXX9_IRQ_BASE+22 TX4938 PCIERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * TXX9_IRQ_BASE+23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * TXX9_IRQ_BASE+24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * TXX9_IRQ_BASE+25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * TXX9_IRQ_BASE+26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * TXX9_IRQ_BASE+27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * TXX9_IRQ_BASE+28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * TXX9_IRQ_BASE+29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * TXX9_IRQ_BASE+30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * TXX9_IRQ_BASE+31 TX4938 SPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * RBTX4938_IRQ_IOC+00 PCI-D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * RBTX4938_IRQ_IOC+01 PCI-C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * RBTX4938_IRQ_IOC+02 PCI-B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * RBTX4938_IRQ_IOC+03 PCI-A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * RBTX4938_IRQ_IOC+04 RTC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * RBTX4938_IRQ_IOC+05 ATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * RBTX4938_IRQ_IOC+06 MODEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * RBTX4938_IRQ_IOC+07 SWINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #include <asm/txx9/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #include <asm/txx9/rbtx4938.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int toshiba_rbtx4938_irq_nested(int sw_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u8 level3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) level3 = readb(rbtx4938_imstat_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (unlikely(!level3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* must use fls so onboard ATA has priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return RBTX4938_IRQ_IOC + __fls8(level3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static void toshiba_rbtx4938_irq_ioc_enable(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned char v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) v = readb(rbtx4938_imask_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) v |= (1 << (d->irq - RBTX4938_IRQ_IOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) writeb(v, rbtx4938_imask_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) mmiowb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static void toshiba_rbtx4938_irq_ioc_disable(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned char v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) v = readb(rbtx4938_imask_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) v &= ~(1 << (d->irq - RBTX4938_IRQ_IOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) writeb(v, rbtx4938_imask_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) mmiowb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .name = TOSHIBA_RBTX4938_IOC_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .irq_mask = toshiba_rbtx4938_irq_ioc_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .irq_unmask = toshiba_rbtx4938_irq_ioc_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static int rbtx4938_irq_dispatch(int pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (pending & STATUSF_IP7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) irq = MIPS_CPU_IRQ_BASE + 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) else if (pending & STATUSF_IP2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) irq = txx9_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (irq == RBTX4938_IRQ_IOCINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) irq = toshiba_rbtx4938_irq_nested(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) } else if (pending & STATUSF_IP1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) irq = MIPS_CPU_IRQ_BASE + 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) else if (pending & STATUSF_IP0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) irq = MIPS_CPU_IRQ_BASE + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void __init toshiba_rbtx4938_irq_ioc_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) for (i = RBTX4938_IRQ_IOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) irq_set_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) irq_set_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) void __init rbtx4938_irq_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) txx9_irq_dispatch = rbtx4938_irq_dispatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Now, interrupt control disabled, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* all IRC interrupts are masked, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* all IRC interrupt mode are Low Active. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* mask all IOC interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) writeb(0, rbtx4938_imask_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* clear SoftInt interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) writeb(0, rbtx4938_softint_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) tx4938_irq_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) toshiba_rbtx4938_irq_ioc_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Onboard 10M Ether: High Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) irq_set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }