aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/common
diff options
context:
space:
mode:
authorEric Miao <eric.y.miao@gmail.com>2010-02-04 21:07:33 -0500
committerEric Miao <eric.y.miao@gmail.com>2010-03-01 18:40:50 -0500
commitac609d266e4af4ebf586d610bd76e04dddae0c4c (patch)
tree24465ed348c37c8abcfadd80676912b395f196eb /arch/arm/common
parent00dd8027b913088ff9b656c5aaa6336c303b7f26 (diff)
[ARM] locomo: allow cascaded IRQ base to be specified by platforms
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
Diffstat (limited to 'arch/arm/common')
-rw-r--r--arch/arm/common/locomo.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index d8a1261f029c..90ae00b631c2 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -32,6 +32,12 @@
32 32
33#include <asm/hardware/locomo.h> 33#include <asm/hardware/locomo.h>
34 34
35/* LoCoMo Interrupts */
36#define IRQ_LOCOMO_KEY (0)
37#define IRQ_LOCOMO_GPIO (1)
38#define IRQ_LOCOMO_LT (2)
39#define IRQ_LOCOMO_SPI (3)
40
35/* M62332 output channel selection */ 41/* M62332 output channel selection */
36#define M62332_EVR_CH 1 /* M62332 volume channel number */ 42#define M62332_EVR_CH 1 /* M62332 volume channel number */
37 /* 0 : CH.1 , 1 : CH. 2 */ 43 /* 0 : CH.1 , 1 : CH. 2 */
@@ -58,6 +64,7 @@ struct locomo {
58 struct device *dev; 64 struct device *dev;
59 unsigned long phys; 65 unsigned long phys;
60 unsigned int irq; 66 unsigned int irq;
67 int irq_base;
61 spinlock_t lock; 68 spinlock_t lock;
62 void __iomem *base; 69 void __iomem *base;
63#ifdef CONFIG_PM 70#ifdef CONFIG_PM
@@ -81,9 +88,7 @@ struct locomo_dev_info {
81static struct locomo_dev_info locomo_devices[] = { 88static struct locomo_dev_info locomo_devices[] = {
82 { 89 {
83 .devid = LOCOMO_DEVID_KEYBOARD, 90 .devid = LOCOMO_DEVID_KEYBOARD,
84 .irq = { 91 .irq = { IRQ_LOCOMO_KEY },
85 IRQ_LOCOMO_KEY,
86 },
87 .name = "locomo-keyboard", 92 .name = "locomo-keyboard",
88 .offset = LOCOMO_KEYBOARD, 93 .offset = LOCOMO_KEYBOARD,
89 .length = 16, 94 .length = 16,
@@ -135,18 +140,18 @@ static struct locomo_dev_info locomo_devices[] = {
135 140
136static void locomo_handler(unsigned int irq, struct irq_desc *desc) 141static void locomo_handler(unsigned int irq, struct irq_desc *desc)
137{ 142{
143 struct locomo *lchip = get_irq_chip_data(irq);
138 int req, i; 144 int req, i;
139 void __iomem *mapbase = get_irq_chip_data(irq);
140 145
141 /* Acknowledge the parent IRQ */ 146 /* Acknowledge the parent IRQ */
142 desc->chip->ack(irq); 147 desc->chip->ack(irq);
143 148
144 /* check why this interrupt was generated */ 149 /* check why this interrupt was generated */
145 req = locomo_readl(mapbase + LOCOMO_ICR) & 0x0f00; 150 req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
146 151
147 if (req) { 152 if (req) {
148 /* generate the next interrupt(s) */ 153 /* generate the next interrupt(s) */
149 irq = IRQ_LOCOMO_KEY; 154 irq = lchip->irq_base;
150 for (i = 0; i <= 3; i++, irq++) { 155 for (i = 0; i <= 3; i++, irq++) {
151 if (req & (0x0100 << i)) { 156 if (req & (0x0100 << i)) {
152 generic_handle_irq(irq); 157 generic_handle_irq(irq);
@@ -162,20 +167,20 @@ static void locomo_ack_irq(unsigned int irq)
162 167
163static void locomo_mask_irq(unsigned int irq) 168static void locomo_mask_irq(unsigned int irq)
164{ 169{
165 void __iomem *mapbase = get_irq_chip_data(irq); 170 struct locomo *lchip = get_irq_chip_data(irq);
166 unsigned int r; 171 unsigned int r;
167 r = locomo_readl(mapbase + LOCOMO_ICR); 172 r = locomo_readl(lchip->base + LOCOMO_ICR);
168 r &= ~(0x0010 << (irq - IRQ_LOCOMO_KEY)); 173 r &= ~(0x0010 << (irq - lchip->irq_base));
169 locomo_writel(r, mapbase + LOCOMO_ICR); 174 locomo_writel(r, lchip->base + LOCOMO_ICR);
170} 175}
171 176
172static void locomo_unmask_irq(unsigned int irq) 177static void locomo_unmask_irq(unsigned int irq)
173{ 178{
174 void __iomem *mapbase = get_irq_chip_data(irq); 179 struct locomo *lchip = get_irq_chip_data(irq);
175 unsigned int r; 180 unsigned int r;
176 r = locomo_readl(mapbase + LOCOMO_ICR); 181 r = locomo_readl(lchip->base + LOCOMO_ICR);
177 r |= (0x0010 << (irq - IRQ_LOCOMO_KEY)); 182 r |= (0x0010 << (irq - lchip->irq_base));
178 locomo_writel(r, mapbase + LOCOMO_ICR); 183 locomo_writel(r, lchip->base + LOCOMO_ICR);
179} 184}
180 185
181static struct irq_chip locomo_chip = { 186static struct irq_chip locomo_chip = {
@@ -187,21 +192,20 @@ static struct irq_chip locomo_chip = {
187 192
188static void locomo_setup_irq(struct locomo *lchip) 193static void locomo_setup_irq(struct locomo *lchip)
189{ 194{
190 int irq; 195 int irq = lchip->irq_base;
191 void __iomem *irqbase = lchip->base;
192 196
193 /* 197 /*
194 * Install handler for IRQ_LOCOMO_HW. 198 * Install handler for IRQ_LOCOMO_HW.
195 */ 199 */
196 set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING); 200 set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
197 set_irq_chip_data(lchip->irq, irqbase); 201 set_irq_chip_data(lchip->irq, lchip);
198 set_irq_chained_handler(lchip->irq, locomo_handler); 202 set_irq_chained_handler(lchip->irq, locomo_handler);
199 203
200 /* install handlers for IRQ_LOCOMO_* */ 204 /* Install handlers for IRQ_LOCOMO_* */
201 for (irq = IRQ_LOCOMO_KEY; irq < IRQ_LOCOMO_KEY + 4; irq++) { 205 for ( ; irq <= lchip->irq_base + 3; irq++) {
202 set_irq_chip(irq, &locomo_chip); 206 set_irq_chip(irq, &locomo_chip);
203 set_irq_chip_data(irq, irqbase); 207 set_irq_chip_data(irq, lchip);
204 set_irq_handler(irq, handle_edge_irq); 208 set_irq_handler(irq, handle_level_irq);
205 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 209 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
206 } 210 }
207} 211}
@@ -248,7 +252,8 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
248 dev->mapbase = 0; 252 dev->mapbase = 0;
249 dev->length = info->length; 253 dev->length = info->length;
250 254
251 memmove(dev->irq, info->irq, sizeof(dev->irq)); 255 dev->irq[0] = (lchip->irq_base == NO_IRQ) ?
256 NO_IRQ : lchip->irq_base + info->irq[0];
252 257
253 ret = device_register(&dev->dev); 258 ret = device_register(&dev->dev);
254 if (ret) { 259 if (ret) {
@@ -365,6 +370,7 @@ static int locomo_resume(struct platform_device *dev)
365static int 370static int
366__locomo_probe(struct device *me, struct resource *mem, int irq) 371__locomo_probe(struct device *me, struct resource *mem, int irq)
367{ 372{
373 struct locomo_platform_data *pdata = me->platform_data;
368 struct locomo *lchip; 374 struct locomo *lchip;
369 unsigned long r; 375 unsigned long r;
370 int i, ret = -ENODEV; 376 int i, ret = -ENODEV;
@@ -380,6 +386,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
380 386
381 lchip->phys = mem->start; 387 lchip->phys = mem->start;
382 lchip->irq = irq; 388 lchip->irq = irq;
389 lchip->irq_base = (pdata) ? pdata->irq_base : NO_IRQ;
383 390
384 /* 391 /*
385 * Map the whole region. This also maps the 392 * Map the whole region. This also maps the
@@ -446,7 +453,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
446 * The interrupt controller must be initialised before any 453 * The interrupt controller must be initialised before any
447 * other device to ensure that the interrupts are available. 454 * other device to ensure that the interrupts are available.
448 */ 455 */
449 if (lchip->irq != NO_IRQ) 456 if (lchip->irq != NO_IRQ && lchip->irq_base != NO_IRQ)
450 locomo_setup_irq(lchip); 457 locomo_setup_irq(lchip);
451 458
452 for (i = 0; i < ARRAY_SIZE(locomo_devices); i++) 459 for (i = 0; i < ARRAY_SIZE(locomo_devices); i++)