/*1* Copyright 2001 MontaVista Software Inc.2* Author: MontaVista Software, Inc.3* [email protected]4*5* This file is subject to the terms and conditions of the GNU General Public6* License. See the file "COPYING" in the main directory of this archive7* for more details.8*9* Copyright (C) 2000-2001 Toshiba Corporation10*11* This program is free software; you can redistribute it and/or modify it12* under the terms of the GNU General Public License as published by the13* Free Software Foundation; either version 2 of the License, or (at your14* option) any later version.15*16* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED17* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF18* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN19* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,20* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT21* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF22* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON23* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF25* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.26*27* You should have received a copy of the GNU General Public License along28* with this program; if not, write to the Free Software Foundation, Inc.,29* 675 Mass Ave, Cambridge, MA 02139, USA.30*/31#include <linux/init.h>32#include <linux/types.h>33#include <linux/interrupt.h>34#include <linux/irq.h>3536#include <asm/io.h>37#include <asm/mipsregs.h>38#include <asm/txx9/generic.h>39#include <asm/txx9/jmr3927.h>4041#if JMR3927_IRQ_END > NR_IRQS42#error JMR3927_IRQ_END > NR_IRQS43#endif4445/*46* CP0_STATUS is a thread's resource (saved/restored on context switch).47* So disable_irq/enable_irq MUST handle IOC/IRC registers.48*/49static void mask_irq_ioc(struct irq_data *d)50{51/* 0: mask */52unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC;53unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);54unsigned int bit = 1 << irq_nr;55jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR);56/* flush write buffer */57(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);58}59static void unmask_irq_ioc(struct irq_data *d)60{61/* 0: mask */62unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC;63unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);64unsigned int bit = 1 << irq_nr;65jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR);66/* flush write buffer */67(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);68}6970static int jmr3927_ioc_irqroute(void)71{72unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR);73int i;7475for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) {76if (istat & (1 << i))77return JMR3927_IRQ_IOC + i;78}79return -1;80}8182static int jmr3927_irq_dispatch(int pending)83{84int irq;8586if ((pending & CAUSEF_IP7) == 0)87return -1;88irq = (pending >> CAUSEB_IP2) & 0x0f;89irq += JMR3927_IRQ_IRC;90if (irq == JMR3927_IRQ_IOCINT)91irq = jmr3927_ioc_irqroute();92return irq;93}9495static struct irq_chip jmr3927_irq_ioc = {96.name = "jmr3927_ioc",97.irq_mask = mask_irq_ioc,98.irq_unmask = unmask_irq_ioc,99};100101void __init jmr3927_irq_setup(void)102{103int i;104105txx9_irq_dispatch = jmr3927_irq_dispatch;106/* Now, interrupt control disabled, */107/* all IRC interrupts are masked, */108/* all IRC interrupt mode are Low Active. */109110/* mask all IOC interrupts */111jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR);112/* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */113jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR);114115/* clear PCI Soft interrupts */116jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR);117/* clear PCI Reset interrupts */118jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);119120tx3927_irq_init();121for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++)122irq_set_chip_and_handler(i, &jmr3927_irq_ioc,123handle_level_irq);124125/* setup IOC interrupt 1 (PCI, MODEM) */126irq_set_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq);127}128129130