1/* 2 * arch/mips/emma2rh/markeins/irq_markeins.c 3 * This file defines the irq handler for Mark-eins. 4 * 5 * Copyright (C) NEC Electronics Corporation 2004-2006 6 * 7 * This file is based on the arch/mips/ddb5xxx/ddb5477/irq_5477.c 8 * 9 * Copyright 2001 MontaVista Software Inc. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25#include <linux/interrupt.h> 26#include <linux/irq.h> 27#include <linux/types.h> 28#include <linux/ptrace.h> 29 30#include <asm/debug.h> 31#include <asm/emma2rh/emma2rh.h> 32 33static int emma2rh_sw_irq_base = -1; 34static int emma2rh_gpio_irq_base = -1; 35 36void ll_emma2rh_sw_irq_enable(int reg); 37void ll_emma2rh_sw_irq_disable(int reg); 38void ll_emma2rh_gpio_irq_enable(int reg); 39void ll_emma2rh_gpio_irq_disable(int reg); 40 41static void emma2rh_sw_irq_enable(unsigned int irq) 42{ 43 ll_emma2rh_sw_irq_enable(irq - emma2rh_sw_irq_base); 44} 45 46static void emma2rh_sw_irq_disable(unsigned int irq) 47{ 48 ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base); 49} 50 51struct irq_chip emma2rh_sw_irq_controller = { 52 .name = "emma2rh_sw_irq", 53 .ack = emma2rh_sw_irq_disable, 54 .mask = emma2rh_sw_irq_disable, 55 .mask_ack = emma2rh_sw_irq_disable, 56 .unmask = emma2rh_sw_irq_enable, 57}; 58 59void emma2rh_sw_irq_init(u32 irq_base) 60{ 61 u32 i; 62 63 for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_SW; i++) 64 set_irq_chip_and_handler(i, &emma2rh_sw_irq_controller, 65 handle_level_irq); 66 67 emma2rh_sw_irq_base = irq_base; 68} 69 70void ll_emma2rh_sw_irq_enable(int irq) 71{ 72 u32 reg; 73 74 db_assert(irq >= 0); 75 db_assert(irq < NUM_EMMA2RH_IRQ_SW); 76 77 reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); 78 reg |= 1 << irq; 79 emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); 80} 81 82void ll_emma2rh_sw_irq_disable(int irq) 83{ 84 u32 reg; 85 86 db_assert(irq >= 0); 87 db_assert(irq < 32); 88 89 reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); 90 reg &= ~(1 << irq); 91 emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); 92} 93 94static void emma2rh_gpio_irq_enable(unsigned int irq) 95{ 96 ll_emma2rh_gpio_irq_enable(irq - emma2rh_gpio_irq_base); 97} 98 99static void emma2rh_gpio_irq_disable(unsigned int irq) 100{ 101 ll_emma2rh_gpio_irq_disable(irq - emma2rh_gpio_irq_base); 102} 103 104static void emma2rh_gpio_irq_ack(unsigned int irq) 105{ 106 irq -= emma2rh_gpio_irq_base; 107 emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq)); 108 ll_emma2rh_gpio_irq_disable(irq); 109} 110 111static void emma2rh_gpio_irq_end(unsigned int irq) 112{ 113 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) 114 ll_emma2rh_gpio_irq_enable(irq - emma2rh_gpio_irq_base); 115} 116 117struct irq_chip emma2rh_gpio_irq_controller = { 118 .name = "emma2rh_gpio_irq", 119 .ack = emma2rh_gpio_irq_ack, 120 .mask = emma2rh_gpio_irq_disable, 121 .mask_ack = emma2rh_gpio_irq_ack, 122 .unmask = emma2rh_gpio_irq_enable, 123 .end = emma2rh_gpio_irq_end, 124}; 125 126void emma2rh_gpio_irq_init(u32 irq_base) 127{ 128 u32 i; 129 130 for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_GPIO; i++) 131 set_irq_chip(i, &emma2rh_gpio_irq_controller); 132 133 emma2rh_gpio_irq_base = irq_base; 134} 135 136void ll_emma2rh_gpio_irq_enable(int irq) 137{ 138 u32 reg; 139 140 db_assert(irq >= 0); 141 db_assert(irq < NUM_EMMA2RH_IRQ_GPIO); 142 143 reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); 144 reg |= 1 << irq; 145 emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); 146} 147 148void ll_emma2rh_gpio_irq_disable(int irq) 149{ 150 u32 reg; 151 152 db_assert(irq >= 0); 153 db_assert(irq < NUM_EMMA2RH_IRQ_GPIO); 154 155 reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); 156 reg &= ~(1 << irq); 157 emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); 158} 159