aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorSemen Protsenko <semen.protsenko@globallogic.com>2015-01-13 08:41:43 -0500
committerLinus Walleij <linus.walleij@linaro.org>2015-01-15 11:53:56 -0500
commit479f8a5744d8141e95ef40ab364ae2d3648848ef (patch)
treef0c06f8e2492517c6bb303a56351916fe61ccf13 /drivers/gpio
parent43c4bcf9425ef596f9651bd0c647065dc5e9ad50 (diff)
gpio: max732x: Rewrite IRQ code to use irq_domain API
Signed-off-by: Semen Protsenko <semen.protsenko@globallogic.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/Kconfig1
-rw-r--r--drivers/gpio/gpio-max732x.c100
2 files changed, 66 insertions, 35 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 192f97396d12..d24492c59bf9 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -528,6 +528,7 @@ config GPIO_MAX7300
528config GPIO_MAX732X 528config GPIO_MAX732X
529 tristate "MAX7319, MAX7320-7327 I2C Port Expanders" 529 tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
530 depends on I2C 530 depends on I2C
531 select IRQ_DOMAIN
531 help 532 help
532 Say yes here to support the MAX7319, MAX7320-7327 series of I2C 533 Say yes here to support the MAX7319, MAX7320-7327 series of I2C
533 Port Expanders. Each IO port on these chips has a fixed role of 534 Port Expanders. Each IO port on these chips has a fixed role of
diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c
index a642f780901d..f8f3e8081a89 100644
--- a/drivers/gpio/gpio-max732x.c
+++ b/drivers/gpio/gpio-max732x.c
@@ -19,6 +19,7 @@
19#include <linux/gpio.h> 19#include <linux/gpio.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/irqdomain.h>
22#include <linux/i2c.h> 23#include <linux/i2c.h>
23#include <linux/i2c/max732x.h> 24#include <linux/i2c/max732x.h>
24#include <linux/of.h> 25#include <linux/of.h>
@@ -149,13 +150,14 @@ struct max732x_chip {
149 uint8_t reg_out[2]; 150 uint8_t reg_out[2];
150 151
151#ifdef CONFIG_GPIO_MAX732X_IRQ 152#ifdef CONFIG_GPIO_MAX732X_IRQ
152 struct mutex irq_lock; 153 struct irq_domain *irq_domain;
153 int irq_base; 154 struct mutex irq_lock;
154 uint8_t irq_mask; 155 int irq_base;
155 uint8_t irq_mask_cur; 156 uint8_t irq_mask;
156 uint8_t irq_trig_raise; 157 uint8_t irq_mask_cur;
157 uint8_t irq_trig_fall; 158 uint8_t irq_trig_raise;
158 uint8_t irq_features; 159 uint8_t irq_trig_fall;
160 uint8_t irq_features;
159#endif 161#endif
160}; 162};
161 163
@@ -341,21 +343,27 @@ static int max732x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
341 struct max732x_chip *chip; 343 struct max732x_chip *chip;
342 344
343 chip = container_of(gc, struct max732x_chip, gpio_chip); 345 chip = container_of(gc, struct max732x_chip, gpio_chip);
344 return chip->irq_base + off; 346
347 if (chip->irq_domain) {
348 return irq_create_mapping(chip->irq_domain,
349 chip->irq_base + off);
350 } else {
351 return -ENXIO;
352 }
345} 353}
346 354
347static void max732x_irq_mask(struct irq_data *d) 355static void max732x_irq_mask(struct irq_data *d)
348{ 356{
349 struct max732x_chip *chip = irq_data_get_irq_chip_data(d); 357 struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
350 358
351 chip->irq_mask_cur &= ~(1 << (d->irq - chip->irq_base)); 359 chip->irq_mask_cur &= ~(1 << d->hwirq);
352} 360}
353 361
354static void max732x_irq_unmask(struct irq_data *d) 362static void max732x_irq_unmask(struct irq_data *d)
355{ 363{
356 struct max732x_chip *chip = irq_data_get_irq_chip_data(d); 364 struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
357 365
358 chip->irq_mask_cur |= 1 << (d->irq - chip->irq_base); 366 chip->irq_mask_cur |= 1 << d->hwirq;
359} 367}
360 368
361static void max732x_irq_bus_lock(struct irq_data *d) 369static void max732x_irq_bus_lock(struct irq_data *d)
@@ -377,7 +385,7 @@ static void max732x_irq_bus_sync_unlock(struct irq_data *d)
377static int max732x_irq_set_type(struct irq_data *d, unsigned int type) 385static int max732x_irq_set_type(struct irq_data *d, unsigned int type)
378{ 386{
379 struct max732x_chip *chip = irq_data_get_irq_chip_data(d); 387 struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
380 uint16_t off = d->irq - chip->irq_base; 388 uint16_t off = d->hwirq;
381 uint16_t mask = 1 << off; 389 uint16_t mask = 1 << off;
382 390
383 if (!(mask & chip->dir_input)) { 391 if (!(mask & chip->dir_input)) {
@@ -458,7 +466,7 @@ static irqreturn_t max732x_irq_handler(int irq, void *devid)
458 466
459 do { 467 do {
460 level = __ffs(pending); 468 level = __ffs(pending);
461 handle_nested_irq(level + chip->irq_base); 469 handle_nested_irq(irq_find_mapping(chip->irq_domain, level));
462 470
463 pending &= ~(1 << level); 471 pending &= ~(1 << level);
464 } while (pending); 472 } while (pending);
@@ -466,6 +474,44 @@ static irqreturn_t max732x_irq_handler(int irq, void *devid)
466 return IRQ_HANDLED; 474 return IRQ_HANDLED;
467} 475}
468 476
477static int max732x_irq_map(struct irq_domain *h, unsigned int virq,
478 irq_hw_number_t hw)
479{
480 struct max732x_chip *chip = h->host_data;
481
482 if (!(chip->dir_input & (1 << hw))) {
483 dev_err(&chip->client->dev,
484 "Attempt to map output line as IRQ line: %lu\n",
485 hw);
486 return -EPERM;
487 }
488
489 irq_set_chip_data(virq, chip);
490 irq_set_chip_and_handler(virq, &max732x_irq_chip,
491 handle_edge_irq);
492 irq_set_nested_thread(virq, 1);
493#ifdef CONFIG_ARM
494 /* ARM needs us to explicitly flag the IRQ as valid
495 * and will set them noprobe when we do so. */
496 set_irq_flags(virq, IRQF_VALID);
497#else
498 irq_set_noprobe(virq);
499#endif
500
501 return 0;
502}
503
504static struct irq_domain_ops max732x_irq_domain_ops = {
505 .map = max732x_irq_map,
506 .xlate = irq_domain_xlate_twocell,
507};
508
509static void max732x_irq_teardown(struct max732x_chip *chip)
510{
511 if (chip->client->irq && chip->irq_domain)
512 irq_domain_remove(chip->irq_domain);
513}
514
469static int max732x_irq_setup(struct max732x_chip *chip, 515static int max732x_irq_setup(struct max732x_chip *chip,
470 const struct i2c_device_id *id) 516 const struct i2c_device_id *id)
471{ 517{
@@ -476,28 +522,17 @@ static int max732x_irq_setup(struct max732x_chip *chip,
476 522
477 if (((pdata && pdata->irq_base) || client->irq) 523 if (((pdata && pdata->irq_base) || client->irq)
478 && has_irq != INT_NONE) { 524 && has_irq != INT_NONE) {
479 int lvl;
480
481 if (pdata) 525 if (pdata)
482 chip->irq_base = pdata->irq_base; 526 chip->irq_base = pdata->irq_base;
483 chip->irq_features = has_irq; 527 chip->irq_features = has_irq;
484 mutex_init(&chip->irq_lock); 528 mutex_init(&chip->irq_lock);
485 529
486 for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { 530 chip->irq_domain = irq_domain_add_simple(client->dev.of_node,
487 int irq = lvl + chip->irq_base; 531 chip->gpio_chip.ngpio, chip->irq_base,
488 532 &max732x_irq_domain_ops, chip);
489 if (!(chip->dir_input & (1 << lvl))) 533 if (!chip->irq_domain) {
490 continue; 534 dev_err(&client->dev, "Failed to create IRQ domain\n");
491 535 return -ENOMEM;
492 irq_set_chip_data(irq, chip);
493 irq_set_chip_and_handler(irq, &max732x_irq_chip,
494 handle_edge_irq);
495 irq_set_nested_thread(irq, 1);
496#ifdef CONFIG_ARM
497 set_irq_flags(irq, IRQF_VALID);
498#else
499 irq_set_noprobe(irq);
500#endif
501 } 536 }
502 537
503 ret = request_threaded_irq(client->irq, 538 ret = request_threaded_irq(client->irq,
@@ -517,15 +552,10 @@ static int max732x_irq_setup(struct max732x_chip *chip,
517 return 0; 552 return 0;
518 553
519out_failed: 554out_failed:
520 chip->irq_base = 0; 555 max732x_irq_teardown(chip);
521 return ret; 556 return ret;
522} 557}
523 558
524static void max732x_irq_teardown(struct max732x_chip *chip)
525{
526 if (chip->irq_base)
527 free_irq(chip->client->irq, chip);
528}
529#else /* CONFIG_GPIO_MAX732X_IRQ */ 559#else /* CONFIG_GPIO_MAX732X_IRQ */
530static int max732x_irq_setup(struct max732x_chip *chip, 560static int max732x_irq_setup(struct max732x_chip *chip,
531 const struct i2c_device_id *id) 561 const struct i2c_device_id *id)