aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2015-01-30 05:32:01 -0500
committerLinus Walleij <linus.walleij@linaro.org>2015-03-02 09:44:08 -0500
commit984f66432e357701194abc7f753dcad89a1f9de3 (patch)
tree42fee9c8f535c86a1efe679b2844e94402c34935
parentfd9c963c5661af3403e77e312c0d9941773b6c1b (diff)
gpio: max732x: convert to GPIOLIB_IRQCHIP
Take a sweep to bring the irq support for the MAX732x expanders into the gpiolib core to cut down on duplicated code. Only compile tested! I need some feedback from people using this expander with interrupts to tell me if things go right or wrong when I do this. Cc: Semen Protsenko <semen.protsenko@globallogic.com> Cc: Mans Rullgard <mans@mansr.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/gpio/Kconfig2
-rw-r--r--drivers/gpio/gpio-max732x.c134
2 files changed, 43 insertions, 93 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index c1e2ca3d9a51..09bc70b3875b 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -543,7 +543,6 @@ config GPIO_MAX7300
543config GPIO_MAX732X 543config GPIO_MAX732X
544 tristate "MAX7319, MAX7320-7327 I2C Port Expanders" 544 tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
545 depends on I2C 545 depends on I2C
546 select IRQ_DOMAIN
547 help 546 help
548 Say yes here to support the MAX7319, MAX7320-7327 series of I2C 547 Say yes here to support the MAX7319, MAX7320-7327 series of I2C
549 Port Expanders. Each IO port on these chips has a fixed role of 548 Port Expanders. Each IO port on these chips has a fixed role of
@@ -563,6 +562,7 @@ config GPIO_MAX732X
563config GPIO_MAX732X_IRQ 562config GPIO_MAX732X_IRQ
564 bool "Interrupt controller support for MAX732x" 563 bool "Interrupt controller support for MAX732x"
565 depends on GPIO_MAX732X=y 564 depends on GPIO_MAX732X=y
565 select GPIOLIB_IRQCHIP
566 help 566 help
567 Say yes here to enable the max732x to be used as an interrupt 567 Say yes here to enable the max732x to be used as an interrupt
568 controller. It requires the driver to be built in the kernel. 568 controller. It requires the driver to be built in the kernel.
diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c
index a095b2393fe9..0fa4543c5e02 100644
--- a/drivers/gpio/gpio-max732x.c
+++ b/drivers/gpio/gpio-max732x.c
@@ -4,6 +4,7 @@
4 * Copyright (C) 2007 Marvell International Ltd. 4 * Copyright (C) 2007 Marvell International Ltd.
5 * Copyright (C) 2008 Jack Ren <jack.ren@marvell.com> 5 * Copyright (C) 2008 Jack Ren <jack.ren@marvell.com>
6 * Copyright (C) 2008 Eric Miao <eric.miao@marvell.com> 6 * Copyright (C) 2008 Eric Miao <eric.miao@marvell.com>
7 * Copyright (C) 2015 Linus Walleij <linus.walleij@linaro.org>
7 * 8 *
8 * Derived from drivers/gpio/pca953x.c 9 * Derived from drivers/gpio/pca953x.c
9 * 10 *
@@ -16,10 +17,8 @@
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/slab.h> 18#include <linux/slab.h>
18#include <linux/string.h> 19#include <linux/string.h>
19#include <linux/gpio.h> 20#include <linux/gpio/driver.h>
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
21#include <linux/irq.h>
22#include <linux/irqdomain.h>
23#include <linux/i2c.h> 22#include <linux/i2c.h>
24#include <linux/i2c/max732x.h> 23#include <linux/i2c/max732x.h>
25#include <linux/of.h> 24#include <linux/of.h>
@@ -150,9 +149,7 @@ struct max732x_chip {
150 uint8_t reg_out[2]; 149 uint8_t reg_out[2];
151 150
152#ifdef CONFIG_GPIO_MAX732X_IRQ 151#ifdef CONFIG_GPIO_MAX732X_IRQ
153 struct irq_domain *irq_domain;
154 struct mutex irq_lock; 152 struct mutex irq_lock;
155 int irq_base;
156 uint8_t irq_mask; 153 uint8_t irq_mask;
157 uint8_t irq_mask_cur; 154 uint8_t irq_mask_cur;
158 uint8_t irq_trig_raise; 155 uint8_t irq_trig_raise;
@@ -356,35 +353,26 @@ static void max732x_irq_update_mask(struct max732x_chip *chip)
356 mutex_unlock(&chip->lock); 353 mutex_unlock(&chip->lock);
357} 354}
358 355
359static int max732x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
360{
361 struct max732x_chip *chip = to_max732x(gc);
362
363 if (chip->irq_domain) {
364 return irq_create_mapping(chip->irq_domain,
365 chip->irq_base + off);
366 } else {
367 return -ENXIO;
368 }
369}
370
371static void max732x_irq_mask(struct irq_data *d) 356static void max732x_irq_mask(struct irq_data *d)
372{ 357{
373 struct max732x_chip *chip = irq_data_get_irq_chip_data(d); 358 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
359 struct max732x_chip *chip = to_max732x(gc);
374 360
375 chip->irq_mask_cur &= ~(1 << d->hwirq); 361 chip->irq_mask_cur &= ~(1 << d->hwirq);
376} 362}
377 363
378static void max732x_irq_unmask(struct irq_data *d) 364static void max732x_irq_unmask(struct irq_data *d)
379{ 365{
380 struct max732x_chip *chip = irq_data_get_irq_chip_data(d); 366 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
367 struct max732x_chip *chip = to_max732x(gc);
381 368
382 chip->irq_mask_cur |= 1 << d->hwirq; 369 chip->irq_mask_cur |= 1 << d->hwirq;
383} 370}
384 371
385static void max732x_irq_bus_lock(struct irq_data *d) 372static void max732x_irq_bus_lock(struct irq_data *d)
386{ 373{
387 struct max732x_chip *chip = irq_data_get_irq_chip_data(d); 374 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
375 struct max732x_chip *chip = to_max732x(gc);
388 376
389 mutex_lock(&chip->irq_lock); 377 mutex_lock(&chip->irq_lock);
390 chip->irq_mask_cur = chip->irq_mask; 378 chip->irq_mask_cur = chip->irq_mask;
@@ -392,7 +380,8 @@ static void max732x_irq_bus_lock(struct irq_data *d)
392 380
393static void max732x_irq_bus_sync_unlock(struct irq_data *d) 381static void max732x_irq_bus_sync_unlock(struct irq_data *d)
394{ 382{
395 struct max732x_chip *chip = irq_data_get_irq_chip_data(d); 383 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
384 struct max732x_chip *chip = to_max732x(gc);
396 uint16_t new_irqs; 385 uint16_t new_irqs;
397 uint16_t level; 386 uint16_t level;
398 387
@@ -410,7 +399,8 @@ static void max732x_irq_bus_sync_unlock(struct irq_data *d)
410 399
411static int max732x_irq_set_type(struct irq_data *d, unsigned int type) 400static int max732x_irq_set_type(struct irq_data *d, unsigned int type)
412{ 401{
413 struct max732x_chip *chip = irq_data_get_irq_chip_data(d); 402 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
403 struct max732x_chip *chip = to_max732x(gc);
414 uint16_t off = d->hwirq; 404 uint16_t off = d->hwirq;
415 uint16_t mask = 1 << off; 405 uint16_t mask = 1 << off;
416 406
@@ -492,7 +482,8 @@ static irqreturn_t max732x_irq_handler(int irq, void *devid)
492 482
493 do { 483 do {
494 level = __ffs(pending); 484 level = __ffs(pending);
495 handle_nested_irq(irq_find_mapping(chip->irq_domain, level)); 485 handle_nested_irq(irq_find_mapping(chip->gpio_chip.irqdomain,
486 level));
496 487
497 pending &= ~(1 << level); 488 pending &= ~(1 << level);
498 } while (pending); 489 } while (pending);
@@ -500,86 +491,50 @@ static irqreturn_t max732x_irq_handler(int irq, void *devid)
500 return IRQ_HANDLED; 491 return IRQ_HANDLED;
501} 492}
502 493
503static int max732x_irq_map(struct irq_domain *h, unsigned int virq,
504 irq_hw_number_t hw)
505{
506 struct max732x_chip *chip = h->host_data;
507
508 if (!(chip->dir_input & (1 << hw))) {
509 dev_err(&chip->client->dev,
510 "Attempt to map output line as IRQ line: %lu\n",
511 hw);
512 return -EPERM;
513 }
514
515 irq_set_chip_data(virq, chip);
516 irq_set_chip_and_handler(virq, &max732x_irq_chip,
517 handle_edge_irq);
518 irq_set_nested_thread(virq, 1);
519#ifdef CONFIG_ARM
520 /* ARM needs us to explicitly flag the IRQ as valid
521 * and will set them noprobe when we do so. */
522 set_irq_flags(virq, IRQF_VALID);
523#else
524 irq_set_noprobe(virq);
525#endif
526
527 return 0;
528}
529
530static struct irq_domain_ops max732x_irq_domain_ops = {
531 .map = max732x_irq_map,
532 .xlate = irq_domain_xlate_twocell,
533};
534
535static void max732x_irq_teardown(struct max732x_chip *chip)
536{
537 if (chip->client->irq && chip->irq_domain)
538 irq_domain_remove(chip->irq_domain);
539}
540
541static int max732x_irq_setup(struct max732x_chip *chip, 494static int max732x_irq_setup(struct max732x_chip *chip,
542 const struct i2c_device_id *id) 495 const struct i2c_device_id *id)
543{ 496{
544 struct i2c_client *client = chip->client; 497 struct i2c_client *client = chip->client;
545 struct max732x_platform_data *pdata = dev_get_platdata(&client->dev); 498 struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);
546 int has_irq = max732x_features[id->driver_data] >> 32; 499 int has_irq = max732x_features[id->driver_data] >> 32;
500 int irq_base = 0;
547 int ret; 501 int ret;
548 502
549 if (((pdata && pdata->irq_base) || client->irq) 503 if (((pdata && pdata->irq_base) || client->irq)
550 && has_irq != INT_NONE) { 504 && has_irq != INT_NONE) {
551 if (pdata) 505 if (pdata)
552 chip->irq_base = pdata->irq_base; 506 irq_base = pdata->irq_base;
553 chip->irq_features = has_irq; 507 chip->irq_features = has_irq;
554 mutex_init(&chip->irq_lock); 508 mutex_init(&chip->irq_lock);
555 509
556 chip->irq_domain = irq_domain_add_simple(client->dev.of_node, 510 ret = devm_request_threaded_irq(&client->dev,
557 chip->gpio_chip.ngpio, chip->irq_base, 511 client->irq,
558 &max732x_irq_domain_ops, chip); 512 NULL,
559 if (!chip->irq_domain) { 513 max732x_irq_handler,
560 dev_err(&client->dev, "Failed to create IRQ domain\n"); 514 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
561 return -ENOMEM; 515 dev_name(&client->dev), chip);
562 }
563
564 ret = request_threaded_irq(client->irq,
565 NULL,
566 max732x_irq_handler,
567 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
568 dev_name(&client->dev), chip);
569 if (ret) { 516 if (ret) {
570 dev_err(&client->dev, "failed to request irq %d\n", 517 dev_err(&client->dev, "failed to request irq %d\n",
571 client->irq); 518 client->irq);
572 goto out_failed; 519 return ret;
573 } 520 }
574 521 ret = gpiochip_irqchip_add(&chip->gpio_chip,
575 chip->gpio_chip.to_irq = max732x_gpio_to_irq; 522 &max732x_irq_chip,
523 irq_base,
524 handle_edge_irq,
525 IRQ_TYPE_NONE);
526 if (ret) {
527 dev_err(&client->dev,
528 "could not connect irqchip to gpiochip\n");
529 return ret;
530 }
531 gpiochip_set_chained_irqchip(&chip->gpio_chip,
532 &max732x_irq_chip,
533 client->irq,
534 NULL);
576 } 535 }
577 536
578 return 0; 537 return 0;
579
580out_failed:
581 max732x_irq_teardown(chip);
582 return ret;
583} 538}
584 539
585#else /* CONFIG_GPIO_MAX732X_IRQ */ 540#else /* CONFIG_GPIO_MAX732X_IRQ */
@@ -595,10 +550,6 @@ static int max732x_irq_setup(struct max732x_chip *chip,
595 550
596 return 0; 551 return 0;
597} 552}
598
599static void max732x_irq_teardown(struct max732x_chip *chip)
600{
601}
602#endif 553#endif
603 554
604static int max732x_setup_gpio(struct max732x_chip *chip, 555static int max732x_setup_gpio(struct max732x_chip *chip,
@@ -730,13 +681,15 @@ static int max732x_probe(struct i2c_client *client,
730 if (nr_port > 8) 681 if (nr_port > 8)
731 max732x_readb(chip, is_group_a(chip, 8), &chip->reg_out[1]); 682 max732x_readb(chip, is_group_a(chip, 8), &chip->reg_out[1]);
732 683
733 ret = max732x_irq_setup(chip, id); 684 ret = gpiochip_add(&chip->gpio_chip);
734 if (ret) 685 if (ret)
735 goto out_failed; 686 goto out_failed;
736 687
737 ret = gpiochip_add(&chip->gpio_chip); 688 ret = max732x_irq_setup(chip, id);
738 if (ret) 689 if (ret) {
690 gpiochip_remove(&chip->gpio_chip);
739 goto out_failed; 691 goto out_failed;
692 }
740 693
741 if (pdata && pdata->setup) { 694 if (pdata && pdata->setup) {
742 ret = pdata->setup(client, chip->gpio_chip.base, 695 ret = pdata->setup(client, chip->gpio_chip.base,
@@ -751,7 +704,6 @@ static int max732x_probe(struct i2c_client *client,
751out_failed: 704out_failed:
752 if (chip->client_dummy) 705 if (chip->client_dummy)
753 i2c_unregister_device(chip->client_dummy); 706 i2c_unregister_device(chip->client_dummy);
754 max732x_irq_teardown(chip);
755 return ret; 707 return ret;
756} 708}
757 709
@@ -774,8 +726,6 @@ static int max732x_remove(struct i2c_client *client)
774 726
775 gpiochip_remove(&chip->gpio_chip); 727 gpiochip_remove(&chip->gpio_chip);
776 728
777 max732x_irq_teardown(chip);
778
779 /* unregister any dummy i2c_client */ 729 /* unregister any dummy i2c_client */
780 if (chip->client_dummy) 730 if (chip->client_dummy)
781 i2c_unregister_device(chip->client_dummy); 731 i2c_unregister_device(chip->client_dummy);