diff options
Diffstat (limited to 'arch/arm/mach-davinci/gpio.c')
-rw-r--r-- | arch/arm/mach-davinci/gpio.c | 97 |
1 files changed, 50 insertions, 47 deletions
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index bf0ff587e46a..cafbe13a82a5 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c | |||
@@ -62,7 +62,7 @@ static inline struct davinci_gpio_regs __iomem *irq2regs(int irq) | |||
62 | { | 62 | { |
63 | struct davinci_gpio_regs __iomem *g; | 63 | struct davinci_gpio_regs __iomem *g; |
64 | 64 | ||
65 | g = (__force struct davinci_gpio_regs __iomem *)get_irq_chip_data(irq); | 65 | g = (__force struct davinci_gpio_regs __iomem *)irq_get_chip_data(irq); |
66 | 66 | ||
67 | return g; | 67 | return g; |
68 | } | 68 | } |
@@ -205,20 +205,20 @@ pure_initcall(davinci_gpio_setup); | |||
205 | * serve as EDMA event triggers. | 205 | * serve as EDMA event triggers. |
206 | */ | 206 | */ |
207 | 207 | ||
208 | static void gpio_irq_disable(unsigned irq) | 208 | static void gpio_irq_disable(struct irq_data *d) |
209 | { | 209 | { |
210 | struct davinci_gpio_regs __iomem *g = irq2regs(irq); | 210 | struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); |
211 | u32 mask = (u32) get_irq_data(irq); | 211 | u32 mask = (u32) irq_data_get_irq_handler_data(d); |
212 | 212 | ||
213 | __raw_writel(mask, &g->clr_falling); | 213 | __raw_writel(mask, &g->clr_falling); |
214 | __raw_writel(mask, &g->clr_rising); | 214 | __raw_writel(mask, &g->clr_rising); |
215 | } | 215 | } |
216 | 216 | ||
217 | static void gpio_irq_enable(unsigned irq) | 217 | static void gpio_irq_enable(struct irq_data *d) |
218 | { | 218 | { |
219 | struct davinci_gpio_regs __iomem *g = irq2regs(irq); | 219 | struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); |
220 | u32 mask = (u32) get_irq_data(irq); | 220 | u32 mask = (u32) irq_data_get_irq_handler_data(d); |
221 | unsigned status = irq_desc[irq].status; | 221 | unsigned status = irqd_get_trigger_type(d); |
222 | 222 | ||
223 | status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; | 223 | status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; |
224 | if (!status) | 224 | if (!status) |
@@ -230,47 +230,42 @@ static void gpio_irq_enable(unsigned irq) | |||
230 | __raw_writel(mask, &g->set_rising); | 230 | __raw_writel(mask, &g->set_rising); |
231 | } | 231 | } |
232 | 232 | ||
233 | static int gpio_irq_type(unsigned irq, unsigned trigger) | 233 | static int gpio_irq_type(struct irq_data *d, unsigned trigger) |
234 | { | 234 | { |
235 | struct davinci_gpio_regs __iomem *g = irq2regs(irq); | 235 | struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); |
236 | u32 mask = (u32) get_irq_data(irq); | 236 | u32 mask = (u32) irq_data_get_irq_handler_data(d); |
237 | 237 | ||
238 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | 238 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
239 | return -EINVAL; | 239 | return -EINVAL; |
240 | 240 | ||
241 | irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; | ||
242 | irq_desc[irq].status |= trigger; | ||
243 | |||
244 | /* don't enable the IRQ if it's currently disabled */ | ||
245 | if (irq_desc[irq].depth == 0) { | ||
246 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING) | ||
247 | ? &g->set_falling : &g->clr_falling); | ||
248 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING) | ||
249 | ? &g->set_rising : &g->clr_rising); | ||
250 | } | ||
251 | return 0; | 241 | return 0; |
252 | } | 242 | } |
253 | 243 | ||
254 | static struct irq_chip gpio_irqchip = { | 244 | static struct irq_chip gpio_irqchip = { |
255 | .name = "GPIO", | 245 | .name = "GPIO", |
256 | .enable = gpio_irq_enable, | 246 | .irq_enable = gpio_irq_enable, |
257 | .disable = gpio_irq_disable, | 247 | .irq_disable = gpio_irq_disable, |
258 | .set_type = gpio_irq_type, | 248 | .irq_set_type = gpio_irq_type, |
249 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
259 | }; | 250 | }; |
260 | 251 | ||
261 | static void | 252 | static void |
262 | gpio_irq_handler(unsigned irq, struct irq_desc *desc) | 253 | gpio_irq_handler(unsigned irq, struct irq_desc *desc) |
263 | { | 254 | { |
264 | struct davinci_gpio_regs __iomem *g = irq2regs(irq); | 255 | struct davinci_gpio_regs __iomem *g; |
265 | u32 mask = 0xffff; | 256 | u32 mask = 0xffff; |
257 | struct davinci_gpio_controller *d; | ||
258 | |||
259 | d = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc); | ||
260 | g = (struct davinci_gpio_regs __iomem *)d->regs; | ||
266 | 261 | ||
267 | /* we only care about one bank */ | 262 | /* we only care about one bank */ |
268 | if (irq & 1) | 263 | if (irq & 1) |
269 | mask <<= 16; | 264 | mask <<= 16; |
270 | 265 | ||
271 | /* temporarily mask (level sensitive) parent IRQ */ | 266 | /* temporarily mask (level sensitive) parent IRQ */ |
272 | desc->chip->mask(irq); | 267 | desc->irq_data.chip->irq_mask(&desc->irq_data); |
273 | desc->chip->ack(irq); | 268 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
274 | while (1) { | 269 | while (1) { |
275 | u32 status; | 270 | u32 status; |
276 | int n; | 271 | int n; |
@@ -281,11 +276,14 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
281 | if (!status) | 276 | if (!status) |
282 | break; | 277 | break; |
283 | __raw_writel(status, &g->intstat); | 278 | __raw_writel(status, &g->intstat); |
284 | if (irq & 1) | ||
285 | status >>= 16; | ||
286 | 279 | ||
287 | /* now demux them to the right lowlevel handler */ | 280 | /* now demux them to the right lowlevel handler */ |
288 | n = (int)get_irq_data(irq); | 281 | n = d->irq_base; |
282 | if (irq & 1) { | ||
283 | n += 16; | ||
284 | status >>= 16; | ||
285 | } | ||
286 | |||
289 | while (status) { | 287 | while (status) { |
290 | res = ffs(status); | 288 | res = ffs(status); |
291 | n += res; | 289 | n += res; |
@@ -293,7 +291,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
293 | status >>= res; | 291 | status >>= res; |
294 | } | 292 | } |
295 | } | 293 | } |
296 | desc->chip->unmask(irq); | 294 | desc->irq_data.chip->irq_unmask(&desc->irq_data); |
297 | /* now it may re-trigger */ | 295 | /* now it may re-trigger */ |
298 | } | 296 | } |
299 | 297 | ||
@@ -320,10 +318,10 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) | |||
320 | return -ENODEV; | 318 | return -ENODEV; |
321 | } | 319 | } |
322 | 320 | ||
323 | static int gpio_irq_type_unbanked(unsigned irq, unsigned trigger) | 321 | static int gpio_irq_type_unbanked(struct irq_data *d, unsigned trigger) |
324 | { | 322 | { |
325 | struct davinci_gpio_regs __iomem *g = irq2regs(irq); | 323 | struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); |
326 | u32 mask = (u32) get_irq_data(irq); | 324 | u32 mask = (u32) irq_data_get_irq_handler_data(d); |
327 | 325 | ||
328 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | 326 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
329 | return -EINVAL; | 327 | return -EINVAL; |
@@ -395,9 +393,9 @@ static int __init davinci_gpio_irq_setup(void) | |||
395 | 393 | ||
396 | /* AINTC handles mask/unmask; GPIO handles triggering */ | 394 | /* AINTC handles mask/unmask; GPIO handles triggering */ |
397 | irq = bank_irq; | 395 | irq = bank_irq; |
398 | gpio_irqchip_unbanked = *get_irq_desc_chip(irq_to_desc(irq)); | 396 | gpio_irqchip_unbanked = *irq_get_chip(irq); |
399 | gpio_irqchip_unbanked.name = "GPIO-AINTC"; | 397 | gpio_irqchip_unbanked.name = "GPIO-AINTC"; |
400 | gpio_irqchip_unbanked.set_type = gpio_irq_type_unbanked; | 398 | gpio_irqchip_unbanked.irq_set_type = gpio_irq_type_unbanked; |
401 | 399 | ||
402 | /* default trigger: both edges */ | 400 | /* default trigger: both edges */ |
403 | g = gpio2regs(0); | 401 | g = gpio2regs(0); |
@@ -406,10 +404,10 @@ static int __init davinci_gpio_irq_setup(void) | |||
406 | 404 | ||
407 | /* set the direct IRQs up to use that irqchip */ | 405 | /* set the direct IRQs up to use that irqchip */ |
408 | for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) { | 406 | for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) { |
409 | set_irq_chip(irq, &gpio_irqchip_unbanked); | 407 | irq_set_chip(irq, &gpio_irqchip_unbanked); |
410 | set_irq_data(irq, (void *) __gpio_mask(gpio)); | 408 | irq_set_handler_data(irq, (void *)__gpio_mask(gpio)); |
411 | set_irq_chip_data(irq, (__force void *) g); | 409 | irq_set_chip_data(irq, (__force void *)g); |
412 | irq_desc[irq].status |= IRQ_TYPE_EDGE_BOTH; | 410 | irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH); |
413 | } | 411 | } |
414 | 412 | ||
415 | goto done; | 413 | goto done; |
@@ -430,15 +428,20 @@ static int __init davinci_gpio_irq_setup(void) | |||
430 | __raw_writel(~0, &g->clr_rising); | 428 | __raw_writel(~0, &g->clr_rising); |
431 | 429 | ||
432 | /* set up all irqs in this bank */ | 430 | /* set up all irqs in this bank */ |
433 | set_irq_chained_handler(bank_irq, gpio_irq_handler); | 431 | irq_set_chained_handler(bank_irq, gpio_irq_handler); |
434 | set_irq_chip_data(bank_irq, (__force void *) g); | 432 | |
435 | set_irq_data(bank_irq, (void *) irq); | 433 | /* |
434 | * Each chip handles 32 gpios, and each irq bank consists of 16 | ||
435 | * gpio irqs. Pass the irq bank's corresponding controller to | ||
436 | * the chained irq handler. | ||
437 | */ | ||
438 | irq_set_handler_data(bank_irq, &chips[gpio / 32]); | ||
436 | 439 | ||
437 | for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { | 440 | for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { |
438 | set_irq_chip(irq, &gpio_irqchip); | 441 | irq_set_chip(irq, &gpio_irqchip); |
439 | set_irq_chip_data(irq, (__force void *) g); | 442 | irq_set_chip_data(irq, (__force void *)g); |
440 | set_irq_data(irq, (void *) __gpio_mask(gpio)); | 443 | irq_set_handler_data(irq, (void *)__gpio_mask(gpio)); |
441 | set_irq_handler(irq, handle_simple_irq); | 444 | irq_set_handler(irq, handle_simple_irq); |
442 | set_irq_flags(irq, IRQF_VALID); | 445 | set_irq_flags(irq, IRQF_VALID); |
443 | } | 446 | } |
444 | 447 | ||