diff options
author | wanzongshun <mcuos.com@gmail.com> | 2009-07-04 07:26:33 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-07-09 12:14:48 -0400 |
commit | 19c0a7286f3f0093bbbbcdce0af4c3205421b608 (patch) | |
tree | 287995a399c8deae706a537a99c222c653676c91 /arch/arm/mach-w90x900 | |
parent | 28d0325ce6e0a52f53d8af687e6427fee59004d3 (diff) |
[ARM] 5591/1: Add group irq enable/disable for w90p910 platform.
Add group irq enable/disable for w90p910 platform.
Signed-off-by: Wan ZongShun <mcuos.com@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-w90x900')
-rw-r--r-- | arch/arm/mach-w90x900/irq.c | 154 |
1 files changed, 146 insertions, 8 deletions
diff --git a/arch/arm/mach-w90x900/irq.c b/arch/arm/mach-w90x900/irq.c index 0b4fc194729c..a296c9b81d24 100644 --- a/arch/arm/mach-w90x900/irq.c +++ b/arch/arm/mach-w90x900/irq.c | |||
@@ -10,8 +10,7 @@ | |||
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 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 | 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 | 13 | * the Free Software Foundation;version 2 of the License. |
14 | * (at your option) any later version. | ||
15 | * | 14 | * |
16 | */ | 15 | */ |
17 | 16 | ||
@@ -29,9 +28,114 @@ | |||
29 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
30 | #include <mach/regs-irq.h> | 29 | #include <mach/regs-irq.h> |
31 | 30 | ||
31 | struct group_irq { | ||
32 | unsigned long gpen; | ||
33 | unsigned int enabled; | ||
34 | void (*enable)(struct group_irq *, int enable); | ||
35 | }; | ||
36 | |||
37 | static DEFINE_SPINLOCK(groupirq_lock); | ||
38 | |||
39 | #define DEFINE_GROUP(_name, _ctrlbit, _num) \ | ||
40 | struct group_irq group_##_name = { \ | ||
41 | .enable = w90x900_group_enable, \ | ||
42 | .gpen = ((2 ^ _num) - 1) << _ctrlbit, \ | ||
43 | } | ||
44 | |||
45 | static void w90x900_group_enable(struct group_irq *gpirq, int enable); | ||
46 | |||
47 | static DEFINE_GROUP(nirq0, 0, 4); | ||
48 | static DEFINE_GROUP(nirq1, 4, 4); | ||
49 | static DEFINE_GROUP(usbh, 8, 2); | ||
50 | static DEFINE_GROUP(ottimer, 16, 3); | ||
51 | static DEFINE_GROUP(gdma, 20, 2); | ||
52 | static DEFINE_GROUP(sc, 24, 2); | ||
53 | static DEFINE_GROUP(i2c, 26, 2); | ||
54 | static DEFINE_GROUP(ps2, 28, 2); | ||
55 | |||
56 | static int group_irq_enable(struct group_irq *group_irq) | ||
57 | { | ||
58 | unsigned long flags; | ||
59 | |||
60 | spin_lock_irqsave(&groupirq_lock, flags); | ||
61 | if (group_irq->enabled++ == 0) | ||
62 | (group_irq->enable)(group_irq, 1); | ||
63 | spin_unlock_irqrestore(&groupirq_lock, flags); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static void group_irq_disable(struct group_irq *group_irq) | ||
69 | { | ||
70 | unsigned long flags; | ||
71 | |||
72 | WARN_ON(group_irq->enabled == 0); | ||
73 | |||
74 | spin_lock_irqsave(&groupirq_lock, flags); | ||
75 | if (--group_irq->enabled == 0) | ||
76 | (group_irq->enable)(group_irq, 0); | ||
77 | spin_unlock_irqrestore(&groupirq_lock, flags); | ||
78 | } | ||
79 | |||
80 | static void w90x900_group_enable(struct group_irq *gpirq, int enable) | ||
81 | { | ||
82 | unsigned int groupen = gpirq->gpen; | ||
83 | unsigned long regval; | ||
84 | |||
85 | regval = __raw_readl(REG_AIC_GEN); | ||
86 | |||
87 | if (enable) | ||
88 | regval |= groupen; | ||
89 | else | ||
90 | regval &= ~groupen; | ||
91 | |||
92 | __raw_writel(regval, REG_AIC_GEN); | ||
93 | } | ||
94 | |||
32 | static void w90x900_irq_mask(unsigned int irq) | 95 | static void w90x900_irq_mask(unsigned int irq) |
33 | { | 96 | { |
97 | struct group_irq *group_irq; | ||
98 | |||
99 | group_irq = NULL; | ||
100 | |||
34 | __raw_writel(1 << irq, REG_AIC_MDCR); | 101 | __raw_writel(1 << irq, REG_AIC_MDCR); |
102 | |||
103 | switch (irq) { | ||
104 | case IRQ_GROUP0: | ||
105 | group_irq = &group_nirq0; | ||
106 | break; | ||
107 | |||
108 | case IRQ_GROUP1: | ||
109 | group_irq = &group_nirq1; | ||
110 | break; | ||
111 | |||
112 | case IRQ_USBH: | ||
113 | group_irq = &group_usbh; | ||
114 | break; | ||
115 | |||
116 | case IRQ_T_INT_GROUP: | ||
117 | group_irq = &group_ottimer; | ||
118 | break; | ||
119 | |||
120 | case IRQ_GDMAGROUP: | ||
121 | group_irq = &group_gdma; | ||
122 | break; | ||
123 | |||
124 | case IRQ_SCGROUP: | ||
125 | group_irq = &group_sc; | ||
126 | break; | ||
127 | |||
128 | case IRQ_I2CGROUP: | ||
129 | group_irq = &group_i2c; | ||
130 | break; | ||
131 | |||
132 | case IRQ_P2SGROUP: | ||
133 | group_irq = &group_ps2; | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | if (group_irq) | ||
138 | group_irq_disable(group_irq); | ||
35 | } | 139 | } |
36 | 140 | ||
37 | /* | 141 | /* |
@@ -46,14 +150,48 @@ static void w90x900_irq_ack(unsigned int irq) | |||
46 | 150 | ||
47 | static void w90x900_irq_unmask(unsigned int irq) | 151 | static void w90x900_irq_unmask(unsigned int irq) |
48 | { | 152 | { |
49 | unsigned long mask; | 153 | struct group_irq *group_irq; |
154 | |||
155 | group_irq = NULL; | ||
50 | 156 | ||
51 | if (irq == IRQ_T_INT_GROUP) { | ||
52 | mask = __raw_readl(REG_AIC_GEN); | ||
53 | __raw_writel(TIME_GROUP_IRQ | mask, REG_AIC_GEN); | ||
54 | __raw_writel(1 << IRQ_T_INT_GROUP, REG_AIC_MECR); | ||
55 | } | ||
56 | __raw_writel(1 << irq, REG_AIC_MECR); | 157 | __raw_writel(1 << irq, REG_AIC_MECR); |
158 | |||
159 | switch (irq) { | ||
160 | case IRQ_GROUP0: | ||
161 | group_irq = &group_nirq0; | ||
162 | break; | ||
163 | |||
164 | case IRQ_GROUP1: | ||
165 | group_irq = &group_nirq1; | ||
166 | break; | ||
167 | |||
168 | case IRQ_USBH: | ||
169 | group_irq = &group_usbh; | ||
170 | break; | ||
171 | |||
172 | case IRQ_T_INT_GROUP: | ||
173 | group_irq = &group_ottimer; | ||
174 | break; | ||
175 | |||
176 | case IRQ_GDMAGROUP: | ||
177 | group_irq = &group_gdma; | ||
178 | break; | ||
179 | |||
180 | case IRQ_SCGROUP: | ||
181 | group_irq = &group_sc; | ||
182 | break; | ||
183 | |||
184 | case IRQ_I2CGROUP: | ||
185 | group_irq = &group_i2c; | ||
186 | break; | ||
187 | |||
188 | case IRQ_P2SGROUP: | ||
189 | group_irq = &group_ps2; | ||
190 | break; | ||
191 | } | ||
192 | |||
193 | if (group_irq) | ||
194 | group_irq_enable(group_irq); | ||
57 | } | 195 | } |
58 | 196 | ||
59 | static struct irq_chip w90x900_irq_chip = { | 197 | static struct irq_chip w90x900_irq_chip = { |