m68knommu: merge old ColdFire interrupt controller masking macros
[pandora-kernel.git] / arch / m68knommu / platform / coldfire / intc.c
1 /*
2  * intc.c  -- support for the old ColdFire interrupt controller
3  *
4  * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file COPYING in the main directory of this archive
8  * for more details.
9  */
10
11 #include <linux/types.h>
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/interrupt.h>
15 #include <linux/irq.h>
16 #include <linux/io.h>
17 #include <asm/traps.h>
18 #include <asm/coldfire.h>
19 #include <asm/mcfsim.h>
20
21 /*
22  * Define the vector numbers for the basic 7 interrupt sources.
23  * These are often referred to as the "external" interrupts in
24  * the ColdFire documentation (for the early ColdFire cores at least).
25  */
26 #define EIRQ1   25
27 #define EIRQ7   31
28
29 /*
30  * In the early version 2 core ColdFire parts the IMR register was 16 bits
31  * in size. Version 3 (and later version 2) core parts have a 32 bit
32  * sized IMR register. Provide some size independant methods to access the
33  * IMR register.
34  */
35 #ifdef MCFSIM_IMR_IS_16BITS
36
37 void mcf_setimr(int index)
38 {
39         u16 imr;
40         imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
41         __raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
42 }
43
44 void mcf_clrimr(int index)
45 {
46         u16 imr;
47         imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
48         __raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
49 }
50
51 void mcf_maskimr(unsigned int mask)
52 {
53         u16 imr;
54         imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
55         imr |= mask;
56         __raw_writew(imr, MCF_MBAR + MCFSIM_IMR);
57 }
58
59 #else
60
61 void mcf_setimr(int index)
62 {
63         u32 imr;
64         imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
65         __raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
66 }
67
68 void mcf_clrimr(int index)
69 {
70         u32 imr;
71         imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
72         __raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
73 }
74
75 void mcf_maskimr(unsigned int mask)
76 {
77         u32 imr;
78         imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
79         imr |= mask;
80         __raw_writel(imr, MCF_MBAR + MCFSIM_IMR);
81 }
82
83 #endif
84
85 /*
86  * Interrupts can be "vectored" on the ColdFire cores that support this old
87  * interrupt controller. That is, the device raising the interrupt can also
88  * supply the vector number to interrupt through. The AVR register of the
89  * interrupt controller enables or disables this for each external interrupt,
90  * so provide generic support for this. Setting this up is out-of-band for
91  * the interrupt system API's, and needs to be done by the driver that
92  * supports this device. Very few devices actually use this.
93  */
94 void mcf_autovector(int irq)
95 {
96         if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
97                 u8 avec;
98                 avec = __raw_readb(MCF_MBAR + MCFSIM_AVR);
99                 avec |= (0x1 << (irq - EIRQ1 + 1));
100                 __raw_writeb(avec, MCF_MBAR + MCFSIM_AVR);
101         }
102 }
103
104 static void intc_irq_mask(unsigned int irq)
105 {
106 }
107
108 static void intc_irq_unmask(unsigned int irq)
109 {
110 }
111
112 static int intc_irq_set_type(unsigned int irq, unsigned int type)
113 {
114         return 0;
115 }
116
117 static struct irq_chip intc_irq_chip = {
118         .name           = "CF-INTC",
119         .mask           = intc_irq_mask,
120         .unmask         = intc_irq_unmask,
121         .set_type       = intc_irq_set_type,
122 };
123
124 void __init init_IRQ(void)
125 {
126         int irq;
127
128         init_vectors();
129         mcf_maskimr(0xffffffff);
130
131         for (irq = 0; (irq < NR_IRQS); irq++) {
132                 irq_desc[irq].status = IRQ_DISABLED;
133                 irq_desc[irq].action = NULL;
134                 irq_desc[irq].depth = 1;
135                 irq_desc[irq].chip = &intc_irq_chip;
136                 intc_irq_set_type(irq, 0);
137         }
138 }
139