aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/jz4740/gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/jz4740/gpio.c')
-rw-r--r--arch/mips/jz4740/gpio.c140
1 files changed, 38 insertions, 102 deletions
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
index 4397972949fa..e1ddb95c05e3 100644
--- a/arch/mips/jz4740/gpio.c
+++ b/arch/mips/jz4740/gpio.c
@@ -17,8 +17,6 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/init.h> 18#include <linux/init.h>
19 19
20#include <linux/spinlock.h>
21#include <linux/syscore_ops.h>
22#include <linux/io.h> 20#include <linux/io.h>
23#include <linux/gpio.h> 21#include <linux/gpio.h>
24#include <linux/delay.h> 22#include <linux/delay.h>
@@ -30,6 +28,8 @@
30 28
31#include <asm/mach-jz4740/base.h> 29#include <asm/mach-jz4740/base.h>
32 30
31#include "irq.h"
32
33#define JZ4740_GPIO_BASE_A (32*0) 33#define JZ4740_GPIO_BASE_A (32*0)
34#define JZ4740_GPIO_BASE_B (32*1) 34#define JZ4740_GPIO_BASE_B (32*1)
35#define JZ4740_GPIO_BASE_C (32*2) 35#define JZ4740_GPIO_BASE_C (32*2)
@@ -77,14 +77,10 @@
77struct jz_gpio_chip { 77struct jz_gpio_chip {
78 unsigned int irq; 78 unsigned int irq;
79 unsigned int irq_base; 79 unsigned int irq_base;
80 uint32_t wakeup;
81 uint32_t suspend_mask;
82 uint32_t edge_trigger_both; 80 uint32_t edge_trigger_both;
83 81
84 void __iomem *base; 82 void __iomem *base;
85 83
86 spinlock_t lock;
87
88 struct gpio_chip gpio_chip; 84 struct gpio_chip gpio_chip;
89}; 85};
90 86
@@ -102,7 +98,8 @@ static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *g
102 98
103static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data) 99static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data)
104{ 100{
105 return irq_data_get_irq_chip_data(data); 101 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
102 return gc->private;
106} 103}
107 104
108static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg) 105static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
@@ -304,21 +301,15 @@ static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
304{ 301{
305 uint32_t flag; 302 uint32_t flag;
306 unsigned int gpio_irq; 303 unsigned int gpio_irq;
307 unsigned int gpio_bank;
308 struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc); 304 struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc);
309 305
310 gpio_bank = JZ4740_IRQ_GPIO0 - irq;
311
312 flag = readl(chip->base + JZ_REG_GPIO_FLAG); 306 flag = readl(chip->base + JZ_REG_GPIO_FLAG);
313
314 if (!flag) 307 if (!flag)
315 return; 308 return;
316 309
317 gpio_irq = __fls(flag); 310 gpio_irq = chip->irq_base + __fls(flag);
318 311
319 jz_gpio_check_trigger_both(chip, irq); 312 jz_gpio_check_trigger_both(chip, gpio_irq);
320
321 gpio_irq += (gpio_bank << 5) + JZ4740_IRQ_GPIO(0);
322 313
323 generic_handle_irq(gpio_irq); 314 generic_handle_irq(gpio_irq);
324}; 315};
@@ -329,18 +320,12 @@ static inline void jz_gpio_set_irq_bit(struct irq_data *data, unsigned int reg)
329 writel(IRQ_TO_BIT(data->irq), chip->base + reg); 320 writel(IRQ_TO_BIT(data->irq), chip->base + reg);
330} 321}
331 322
332static void jz_gpio_irq_mask(struct irq_data *data)
333{
334 jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_SET);
335};
336
337static void jz_gpio_irq_unmask(struct irq_data *data) 323static void jz_gpio_irq_unmask(struct irq_data *data)
338{ 324{
339 struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); 325 struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
340 326
341 jz_gpio_check_trigger_both(chip, data->irq); 327 jz_gpio_check_trigger_both(chip, data->irq);
342 328 irq_gc_unmask_enable_reg(data);
343 jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_CLEAR);
344}; 329};
345 330
346/* TODO: Check if function is gpio */ 331/* TODO: Check if function is gpio */
@@ -353,18 +338,13 @@ static unsigned int jz_gpio_irq_startup(struct irq_data *data)
353 338
354static void jz_gpio_irq_shutdown(struct irq_data *data) 339static void jz_gpio_irq_shutdown(struct irq_data *data)
355{ 340{
356 jz_gpio_irq_mask(data); 341 irq_gc_mask_disable_reg(data);
357 342
358 /* Set direction to input */ 343 /* Set direction to input */
359 jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR); 344 jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
360 jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR); 345 jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR);
361} 346}
362 347
363static void jz_gpio_irq_ack(struct irq_data *data)
364{
365 jz_gpio_set_irq_bit(data, JZ_REG_GPIO_FLAG_CLEAR);
366};
367
368static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) 348static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
369{ 349{
370 struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); 350 struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
@@ -408,35 +388,13 @@ static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
408static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on) 388static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
409{ 389{
410 struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); 390 struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
411 spin_lock(&chip->lock);
412 if (on)
413 chip->wakeup |= IRQ_TO_BIT(data->irq);
414 else
415 chip->wakeup &= ~IRQ_TO_BIT(data->irq);
416 spin_unlock(&chip->lock);
417 391
392 irq_gc_set_wake(data, on);
418 irq_set_irq_wake(chip->irq, on); 393 irq_set_irq_wake(chip->irq, on);
394
419 return 0; 395 return 0;
420} 396}
421 397
422static struct irq_chip jz_gpio_irq_chip = {
423 .name = "GPIO",
424 .irq_mask = jz_gpio_irq_mask,
425 .irq_unmask = jz_gpio_irq_unmask,
426 .irq_ack = jz_gpio_irq_ack,
427 .irq_startup = jz_gpio_irq_startup,
428 .irq_shutdown = jz_gpio_irq_shutdown,
429 .irq_set_type = jz_gpio_irq_set_type,
430 .irq_set_wake = jz_gpio_irq_set_wake,
431 .flags = IRQCHIP_SET_TYPE_MASKED,
432};
433
434/*
435 * This lock class tells lockdep that GPIO irqs are in a different
436 * category than their parents, so it won't report false recursion.
437 */
438static struct lock_class_key gpio_lock_class;
439
440#define JZ4740_GPIO_CHIP(_bank) { \ 398#define JZ4740_GPIO_CHIP(_bank) { \
441 .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \ 399 .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
442 .gpio_chip = { \ 400 .gpio_chip = { \
@@ -458,64 +416,44 @@ static struct jz_gpio_chip jz4740_gpio_chips[] = {
458 JZ4740_GPIO_CHIP(D), 416 JZ4740_GPIO_CHIP(D),
459}; 417};
460 418
461static void jz4740_gpio_suspend_chip(struct jz_gpio_chip *chip) 419static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
462{
463 chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
464 writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
465 writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
466}
467
468static int jz4740_gpio_suspend(void)
469{
470 int i;
471
472 for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); i++)
473 jz4740_gpio_suspend_chip(&jz4740_gpio_chips[i]);
474
475 return 0;
476}
477
478static void jz4740_gpio_resume_chip(struct jz_gpio_chip *chip)
479{ 420{
480 uint32_t mask = chip->suspend_mask; 421 struct irq_chip_generic *gc;
422 struct irq_chip_type *ct;
481 423
482 writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR); 424 chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100);
483 writel(mask, chip->base + JZ_REG_GPIO_MASK_SET);
484}
485 425
486static void jz4740_gpio_resume(void) 426 chip->irq = JZ4740_IRQ_INTC_GPIO(id);
487{ 427 irq_set_handler_data(chip->irq, chip);
488 int i; 428 irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
489 429
490 for (i = ARRAY_SIZE(jz4740_gpio_chips) - 1; i >= 0 ; i--) 430 gc = irq_alloc_generic_chip(chip->gpio_chip.label, 1, chip->irq_base,
491 jz4740_gpio_resume_chip(&jz4740_gpio_chips[i]); 431 chip->base, handle_level_irq);
492}
493 432
494static struct syscore_ops jz4740_gpio_syscore_ops = { 433 gc->wake_enabled = IRQ_MSK(chip->gpio_chip.ngpio);
495 .suspend = jz4740_gpio_suspend, 434 gc->private = chip;
496 .resume = jz4740_gpio_resume,
497};
498 435
499static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) 436 ct = gc->chip_types;
500{ 437 ct->regs.enable = JZ_REG_GPIO_MASK_CLEAR;
501 int irq; 438 ct->regs.disable = JZ_REG_GPIO_MASK_SET;
439 ct->regs.ack = JZ_REG_GPIO_FLAG_CLEAR;
502 440
503 spin_lock_init(&chip->lock); 441 ct->chip.name = "GPIO";
442 ct->chip.irq_mask = irq_gc_mask_disable_reg;
443 ct->chip.irq_unmask = jz_gpio_irq_unmask;
444 ct->chip.irq_ack = irq_gc_ack_set_bit;
445 ct->chip.irq_suspend = jz4740_irq_suspend;
446 ct->chip.irq_resume = jz4740_irq_resume;
447 ct->chip.irq_startup = jz_gpio_irq_startup;
448 ct->chip.irq_shutdown = jz_gpio_irq_shutdown;
449 ct->chip.irq_set_type = jz_gpio_irq_set_type;
450 ct->chip.irq_set_wake = jz_gpio_irq_set_wake;
451 ct->chip.flags = IRQCHIP_SET_TYPE_MASKED;
504 452
505 chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100); 453 irq_setup_generic_chip(gc, IRQ_MSK(chip->gpio_chip.ngpio),
454 IRQ_GC_INIT_NESTED_LOCK, 0, IRQ_NOPROBE | IRQ_LEVEL);
506 455
507 gpiochip_add(&chip->gpio_chip); 456 gpiochip_add(&chip->gpio_chip);
508
509 chip->irq = JZ4740_IRQ_INTC_GPIO(id);
510 irq_set_handler_data(chip->irq, chip);
511 irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
512
513 for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) {
514 irq_set_lockdep_class(irq, &gpio_lock_class);
515 irq_set_chip_data(irq, chip);
516 irq_set_chip_and_handler(irq, &jz_gpio_irq_chip,
517 handle_level_irq);
518 }
519} 457}
520 458
521static int __init jz4740_gpio_init(void) 459static int __init jz4740_gpio_init(void)
@@ -525,8 +463,6 @@ static int __init jz4740_gpio_init(void)
525 for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) 463 for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i)
526 jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); 464 jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
527 465
528 register_syscore_ops(&jz4740_gpio_syscore_ops);
529
530 printk(KERN_INFO "JZ4740 GPIO initialized\n"); 466 printk(KERN_INFO "JZ4740 GPIO initialized\n");
531 467
532 return 0; 468 return 0;