diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2019-09-04 10:01:04 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2019-09-10 20:09:37 -0400 |
commit | 5fbe5b5883f847363ff1b7280e8b1d2980526b8e (patch) | |
tree | 806efff2538fb4d6860cae617f4990f47481db7c /drivers/gpio | |
parent | 4f78d91c722345de94a3c72da49b9d0d49cb76b8 (diff) |
gpio: Initialize the irqchip valid_mask with a callback
After changing the valid_mask for the struct gpio_chip
to detect the need and presence of a valid mask with the
presence of a .init_valid_mask() callback to fill it in,
we augment the gpio_irq_chip to use the same logic.
Switch all driver using the gpio_irq_chio valid_mask
over to this new method.
This makes sure the valid_mask for the gpio_irq_chip gets
filled in when we add the gpio_chip, which makes it a
little easier to switch over drivers using the old
way of setting up gpio_irq_chip over to the new method
of passing the gpio_irq_chip along with the gpio_chip.
(See drivers/gpio/TODO for details.)
Cc: Joel Stanley <joel@jms.id.au>
Cc: Thierry Reding <treding@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
Link: https://lore.kernel.org/r/20190904140104.32426-1-linus.walleij@linaro.org
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-aspeed.c | 13 | ||||
-rw-r--r-- | drivers/gpio/gpio-stmpe.c | 36 | ||||
-rw-r--r-- | drivers/gpio/gpio-tqmx86.c | 21 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 12 |
4 files changed, 52 insertions, 30 deletions
diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index 9defe25d4721..7bcd83dbc3e3 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c | |||
@@ -689,8 +689,11 @@ static struct irq_chip aspeed_gpio_irqchip = { | |||
689 | .irq_set_type = aspeed_gpio_set_type, | 689 | .irq_set_type = aspeed_gpio_set_type, |
690 | }; | 690 | }; |
691 | 691 | ||
692 | static void set_irq_valid_mask(struct aspeed_gpio *gpio) | 692 | static void aspeed_init_irq_valid_mask(struct gpio_chip *gc, |
693 | unsigned long *valid_mask, | ||
694 | unsigned int ngpios) | ||
693 | { | 695 | { |
696 | struct aspeed_gpio *gpio = gpiochip_get_data(gc); | ||
694 | const struct aspeed_bank_props *props = gpio->config->props; | 697 | const struct aspeed_bank_props *props = gpio->config->props; |
695 | 698 | ||
696 | while (!is_bank_props_sentinel(props)) { | 699 | while (!is_bank_props_sentinel(props)) { |
@@ -704,7 +707,7 @@ static void set_irq_valid_mask(struct aspeed_gpio *gpio) | |||
704 | if (i >= gpio->config->nr_gpios) | 707 | if (i >= gpio->config->nr_gpios) |
705 | break; | 708 | break; |
706 | 709 | ||
707 | clear_bit(i, gpio->chip.irq.valid_mask); | 710 | clear_bit(i, valid_mask); |
708 | } | 711 | } |
709 | 712 | ||
710 | props++; | 713 | props++; |
@@ -1203,7 +1206,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) | |||
1203 | girq->parents[0] = gpio->irq; | 1206 | girq->parents[0] = gpio->irq; |
1204 | girq->default_type = IRQ_TYPE_NONE; | 1207 | girq->default_type = IRQ_TYPE_NONE; |
1205 | girq->handler = handle_bad_irq; | 1208 | girq->handler = handle_bad_irq; |
1206 | girq->need_valid_mask = true; | 1209 | girq->init_valid_mask = aspeed_init_irq_valid_mask; |
1207 | } | 1210 | } |
1208 | 1211 | ||
1209 | gpio->offset_timer = | 1212 | gpio->offset_timer = |
@@ -1215,10 +1218,6 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) | |||
1215 | if (rc < 0) | 1218 | if (rc < 0) |
1216 | return rc; | 1219 | return rc; |
1217 | 1220 | ||
1218 | /* Now the valid mask is allocated */ | ||
1219 | if (gpio->irq) | ||
1220 | set_irq_valid_mask(gpio); | ||
1221 | |||
1222 | return 0; | 1221 | return 0; |
1223 | } | 1222 | } |
1224 | 1223 | ||
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index dbf9cbe36b2b..994d542daf53 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c | |||
@@ -429,6 +429,23 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) | |||
429 | return IRQ_HANDLED; | 429 | return IRQ_HANDLED; |
430 | } | 430 | } |
431 | 431 | ||
432 | static void stmpe_init_irq_valid_mask(struct gpio_chip *gc, | ||
433 | unsigned long *valid_mask, | ||
434 | unsigned int ngpios) | ||
435 | { | ||
436 | struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc); | ||
437 | int i; | ||
438 | |||
439 | if (!stmpe_gpio->norequest_mask) | ||
440 | return; | ||
441 | |||
442 | /* Forbid unused lines to be mapped as IRQs */ | ||
443 | for (i = 0; i < sizeof(u32); i++) { | ||
444 | if (stmpe_gpio->norequest_mask & BIT(i)) | ||
445 | clear_bit(i, valid_mask); | ||
446 | } | ||
447 | } | ||
448 | |||
432 | static int stmpe_gpio_probe(struct platform_device *pdev) | 449 | static int stmpe_gpio_probe(struct platform_device *pdev) |
433 | { | 450 | { |
434 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); | 451 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); |
@@ -454,14 +471,21 @@ static int stmpe_gpio_probe(struct platform_device *pdev) | |||
454 | stmpe_gpio->chip.parent = &pdev->dev; | 471 | stmpe_gpio->chip.parent = &pdev->dev; |
455 | stmpe_gpio->chip.of_node = np; | 472 | stmpe_gpio->chip.of_node = np; |
456 | stmpe_gpio->chip.base = -1; | 473 | stmpe_gpio->chip.base = -1; |
474 | /* | ||
475 | * REVISIT: this makes sure the valid mask gets allocated and | ||
476 | * filled in when adding the gpio_chip, but the rest of the | ||
477 | * gpio_irqchip is still filled in using the old method | ||
478 | * in gpiochip_irqchip_add_nested() so clean this up once we | ||
479 | * get the gpio_irqchip to initialize while adding the | ||
480 | * gpio_chip also for threaded irqchips. | ||
481 | */ | ||
482 | stmpe_gpio->chip.irq.init_valid_mask = stmpe_init_irq_valid_mask; | ||
457 | 483 | ||
458 | if (IS_ENABLED(CONFIG_DEBUG_FS)) | 484 | if (IS_ENABLED(CONFIG_DEBUG_FS)) |
459 | stmpe_gpio->chip.dbg_show = stmpe_dbg_show; | 485 | stmpe_gpio->chip.dbg_show = stmpe_dbg_show; |
460 | 486 | ||
461 | of_property_read_u32(np, "st,norequest-mask", | 487 | of_property_read_u32(np, "st,norequest-mask", |
462 | &stmpe_gpio->norequest_mask); | 488 | &stmpe_gpio->norequest_mask); |
463 | if (stmpe_gpio->norequest_mask) | ||
464 | stmpe_gpio->chip.irq.need_valid_mask = true; | ||
465 | 489 | ||
466 | irq = platform_get_irq(pdev, 0); | 490 | irq = platform_get_irq(pdev, 0); |
467 | if (irq < 0) | 491 | if (irq < 0) |
@@ -487,14 +511,6 @@ static int stmpe_gpio_probe(struct platform_device *pdev) | |||
487 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); | 511 | dev_err(&pdev->dev, "unable to get irq: %d\n", ret); |
488 | goto out_disable; | 512 | goto out_disable; |
489 | } | 513 | } |
490 | if (stmpe_gpio->norequest_mask) { | ||
491 | int i; | ||
492 | |||
493 | /* Forbid unused lines to be mapped as IRQs */ | ||
494 | for (i = 0; i < sizeof(u32); i++) | ||
495 | if (stmpe_gpio->norequest_mask & BIT(i)) | ||
496 | clear_bit(i, stmpe_gpio->chip.irq.valid_mask); | ||
497 | } | ||
498 | ret = gpiochip_irqchip_add_nested(&stmpe_gpio->chip, | 514 | ret = gpiochip_irqchip_add_nested(&stmpe_gpio->chip, |
499 | &stmpe_gpio_irq_chip, | 515 | &stmpe_gpio_irq_chip, |
500 | 0, | 516 | 0, |
diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c index 07050cdbadb9..a3109bcaa0ac 100644 --- a/drivers/gpio/gpio-tqmx86.c +++ b/drivers/gpio/gpio-tqmx86.c | |||
@@ -214,6 +214,17 @@ static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = { | |||
214 | tqmx86_gpio_runtime_resume, NULL) | 214 | tqmx86_gpio_runtime_resume, NULL) |
215 | }; | 215 | }; |
216 | 216 | ||
217 | static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip, | ||
218 | unsigned long *valid_mask, | ||
219 | unsigned int ngpios) | ||
220 | { | ||
221 | /* Only GPIOs 4-7 are valid for interrupts. Clear the others */ | ||
222 | clear_bit(0, valid_mask); | ||
223 | clear_bit(1, valid_mask); | ||
224 | clear_bit(2, valid_mask); | ||
225 | clear_bit(3, valid_mask); | ||
226 | } | ||
227 | |||
217 | static int tqmx86_gpio_probe(struct platform_device *pdev) | 228 | static int tqmx86_gpio_probe(struct platform_device *pdev) |
218 | { | 229 | { |
219 | struct device *dev = &pdev->dev; | 230 | struct device *dev = &pdev->dev; |
@@ -260,7 +271,6 @@ static int tqmx86_gpio_probe(struct platform_device *pdev) | |||
260 | chip->get = tqmx86_gpio_get; | 271 | chip->get = tqmx86_gpio_get; |
261 | chip->set = tqmx86_gpio_set; | 272 | chip->set = tqmx86_gpio_set; |
262 | chip->ngpio = TQMX86_NGPIO; | 273 | chip->ngpio = TQMX86_NGPIO; |
263 | chip->irq.need_valid_mask = true; | ||
264 | chip->parent = pdev->dev.parent; | 274 | chip->parent = pdev->dev.parent; |
265 | 275 | ||
266 | pm_runtime_enable(&pdev->dev); | 276 | pm_runtime_enable(&pdev->dev); |
@@ -296,6 +306,7 @@ static int tqmx86_gpio_probe(struct platform_device *pdev) | |||
296 | girq->parents[0] = irq; | 306 | girq->parents[0] = irq; |
297 | girq->default_type = IRQ_TYPE_NONE; | 307 | girq->default_type = IRQ_TYPE_NONE; |
298 | girq->handler = handle_simple_irq; | 308 | girq->handler = handle_simple_irq; |
309 | girq->init_valid_mask = tqmx86_init_irq_valid_mask; | ||
299 | } | 310 | } |
300 | 311 | ||
301 | ret = devm_gpiochip_add_data(dev, chip, gpio); | 312 | ret = devm_gpiochip_add_data(dev, chip, gpio); |
@@ -304,14 +315,6 @@ static int tqmx86_gpio_probe(struct platform_device *pdev) | |||
304 | goto out_pm_dis; | 315 | goto out_pm_dis; |
305 | } | 316 | } |
306 | 317 | ||
307 | /* Only GPIOs 4-7 are valid for interrupts. Clear the others */ | ||
308 | if (irq) { | ||
309 | clear_bit(0, girq->valid_mask); | ||
310 | clear_bit(1, girq->valid_mask); | ||
311 | clear_bit(2, girq->valid_mask); | ||
312 | clear_bit(3, girq->valid_mask); | ||
313 | } | ||
314 | |||
315 | dev_info(dev, "GPIO functionality initialized with %d pins\n", | 318 | dev_info(dev, "GPIO functionality initialized with %d pins\n", |
316 | chip->ngpio); | 319 | chip->ngpio); |
317 | 320 | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 56d0898d94aa..f5b2649e2893 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -1615,15 +1615,19 @@ static struct gpio_chip *find_chip_by_name(const char *name) | |||
1615 | * The following is irqchip helper code for gpiochips. | 1615 | * The following is irqchip helper code for gpiochips. |
1616 | */ | 1616 | */ |
1617 | 1617 | ||
1618 | static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip) | 1618 | static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gc) |
1619 | { | 1619 | { |
1620 | if (!gpiochip->irq.need_valid_mask) | 1620 | struct gpio_irq_chip *girq = &gc->irq; |
1621 | |||
1622 | if (!girq->init_valid_mask) | ||
1621 | return 0; | 1623 | return 0; |
1622 | 1624 | ||
1623 | gpiochip->irq.valid_mask = gpiochip_allocate_mask(gpiochip); | 1625 | girq->valid_mask = gpiochip_allocate_mask(gc); |
1624 | if (!gpiochip->irq.valid_mask) | 1626 | if (!girq->valid_mask) |
1625 | return -ENOMEM; | 1627 | return -ENOMEM; |
1626 | 1628 | ||
1629 | girq->init_valid_mask(gc, girq->valid_mask, gc->ngpio); | ||
1630 | |||
1627 | return 0; | 1631 | return 0; |
1628 | } | 1632 | } |
1629 | 1633 | ||