Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-2.6] / arch / mips / emma2rh / common / irq_emma2rh.c
1 /*
2  *  arch/mips/emma2rh/common/irq_emma2rh.c
3  *      This file defines the irq handler for EMMA2RH.
4  *
5  *  Copyright (C) NEC Electronics Corporation 2005-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
26 /*
27  * EMMA2RH defines 64 IRQs.
28  *
29  * This file exports one function:
30  *      emma2rh_irq_init(u32 irq_base);
31  */
32
33 #include <linux/interrupt.h>
34 #include <linux/types.h>
35 #include <linux/ptrace.h>
36
37 #include <asm/debug.h>
38
39 #include <asm/emma2rh/emma2rh.h>
40
41 /* number of total irqs supported by EMMA2RH */
42 #define NUM_EMMA2RH_IRQ         96
43
44 static int emma2rh_irq_base = -1;
45
46 void ll_emma2rh_irq_enable(int);
47 void ll_emma2rh_irq_disable(int);
48
49 static void emma2rh_irq_enable(unsigned int irq)
50 {
51         ll_emma2rh_irq_enable(irq - emma2rh_irq_base);
52 }
53
54 static void emma2rh_irq_disable(unsigned int irq)
55 {
56         ll_emma2rh_irq_disable(irq - emma2rh_irq_base);
57 }
58
59 static void emma2rh_irq_end(unsigned int irq)
60 {
61         if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
62                 ll_emma2rh_irq_enable(irq - emma2rh_irq_base);
63 }
64
65 struct irq_chip emma2rh_irq_controller = {
66         .typename = "emma2rh_irq",
67         .ack = emma2rh_irq_disable,
68         .mask = emma2rh_irq_disable,
69         .mask_ack = emma2rh_irq_disable,
70         .unmask = emma2rh_irq_enable,
71         .end = emma2rh_irq_end,
72 };
73
74 void emma2rh_irq_init(u32 irq_base)
75 {
76         u32 i;
77
78         for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ; i++)
79                 set_irq_chip_and_handler(i, &emma2rh_irq_controller,
80                                          handle_level_irq);
81
82         emma2rh_irq_base = irq_base;
83 }
84
85 void ll_emma2rh_irq_enable(int emma2rh_irq)
86 {
87         u32 reg_value;
88         u32 reg_bitmask;
89         u32 reg_index;
90
91         reg_index = EMMA2RH_BHIF_INT_EN_0
92             + (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0)
93             * (emma2rh_irq / 32);
94         reg_value = emma2rh_in32(reg_index);
95         reg_bitmask = 0x1 << (emma2rh_irq % 32);
96         db_assert((reg_value & reg_bitmask) == 0);
97         emma2rh_out32(reg_index, reg_value | reg_bitmask);
98 }
99
100 void ll_emma2rh_irq_disable(int emma2rh_irq)
101 {
102         u32 reg_value;
103         u32 reg_bitmask;
104         u32 reg_index;
105
106         reg_index = EMMA2RH_BHIF_INT_EN_0
107             + (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0)
108             * (emma2rh_irq / 32);
109         reg_value = emma2rh_in32(reg_index);
110         reg_bitmask = 0x1 << (emma2rh_irq % 32);
111         db_assert((reg_value & reg_bitmask) != 0);
112         emma2rh_out32(reg_index, reg_value & ~reg_bitmask);
113 }