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 | |
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
-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 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-baytrail.c | 16 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-cherryview.c | 42 | ||||
-rw-r--r-- | drivers/platform/x86/intel_int0002_vgpio.c | 11 | ||||
-rw-r--r-- | include/linux/gpio/driver.h | 14 |
8 files changed, 111 insertions, 54 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 | ||
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index e5a112a8e067..297b7b5fcb28 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c | |||
@@ -1455,6 +1455,20 @@ static void byt_gpio_irq_handler(struct irq_desc *desc) | |||
1455 | chip->irq_eoi(data); | 1455 | chip->irq_eoi(data); |
1456 | } | 1456 | } |
1457 | 1457 | ||
1458 | static void byt_init_irq_valid_mask(struct gpio_chip *chip, | ||
1459 | unsigned long *valid_mask, | ||
1460 | unsigned int ngpios) | ||
1461 | { | ||
1462 | /* | ||
1463 | * FIXME: currently the valid_mask is filled in as part of | ||
1464 | * initializing the irq_chip below in byt_gpio_irq_init_hw(). | ||
1465 | * when converting this driver to the new way of passing the | ||
1466 | * gpio_irq_chip along when adding the gpio_chip, move the | ||
1467 | * mask initialization into this callback instead. Right now | ||
1468 | * this callback is here to make sure the mask gets allocated. | ||
1469 | */ | ||
1470 | } | ||
1471 | |||
1458 | static void byt_gpio_irq_init_hw(struct byt_gpio *vg) | 1472 | static void byt_gpio_irq_init_hw(struct byt_gpio *vg) |
1459 | { | 1473 | { |
1460 | struct gpio_chip *gc = &vg->chip; | 1474 | struct gpio_chip *gc = &vg->chip; |
@@ -1525,7 +1539,7 @@ static int byt_gpio_probe(struct byt_gpio *vg) | |||
1525 | gc->can_sleep = false; | 1539 | gc->can_sleep = false; |
1526 | gc->parent = &vg->pdev->dev; | 1540 | gc->parent = &vg->pdev->dev; |
1527 | gc->ngpio = vg->soc_data->npins; | 1541 | gc->ngpio = vg->soc_data->npins; |
1528 | gc->irq.need_valid_mask = true; | 1542 | gc->irq.init_valid_mask = byt_init_irq_valid_mask; |
1529 | 1543 | ||
1530 | #ifdef CONFIG_PM_SLEEP | 1544 | #ifdef CONFIG_PM_SLEEP |
1531 | vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio, | 1545 | vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio, |
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 03ec7a5d9d0b..ab681d1a3a74 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c | |||
@@ -1543,6 +1543,30 @@ static const struct dmi_system_id chv_no_valid_mask[] = { | |||
1543 | {} | 1543 | {} |
1544 | }; | 1544 | }; |
1545 | 1545 | ||
1546 | static void chv_init_irq_valid_mask(struct gpio_chip *chip, | ||
1547 | unsigned long *valid_mask, | ||
1548 | unsigned int ngpios) | ||
1549 | { | ||
1550 | struct chv_pinctrl *pctrl = gpiochip_get_data(chip); | ||
1551 | const struct chv_community *community = pctrl->community; | ||
1552 | int i; | ||
1553 | |||
1554 | /* Do not add GPIOs that can only generate GPEs to the IRQ domain */ | ||
1555 | for (i = 0; i < community->npins; i++) { | ||
1556 | const struct pinctrl_pin_desc *desc; | ||
1557 | u32 intsel; | ||
1558 | |||
1559 | desc = &community->pins[i]; | ||
1560 | |||
1561 | intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0)); | ||
1562 | intsel &= CHV_PADCTRL0_INTSEL_MASK; | ||
1563 | intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; | ||
1564 | |||
1565 | if (intsel >= community->nirqs) | ||
1566 | clear_bit(i, valid_mask); | ||
1567 | } | ||
1568 | } | ||
1569 | |||
1546 | static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) | 1570 | static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) |
1547 | { | 1571 | { |
1548 | const struct chv_gpio_pinrange *range; | 1572 | const struct chv_gpio_pinrange *range; |
@@ -1557,7 +1581,8 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) | |||
1557 | chip->label = dev_name(pctrl->dev); | 1581 | chip->label = dev_name(pctrl->dev); |
1558 | chip->parent = pctrl->dev; | 1582 | chip->parent = pctrl->dev; |
1559 | chip->base = -1; | 1583 | chip->base = -1; |
1560 | chip->irq.need_valid_mask = need_valid_mask; | 1584 | if (need_valid_mask) |
1585 | chip->irq.init_valid_mask = chv_init_irq_valid_mask; | ||
1561 | 1586 | ||
1562 | ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl); | 1587 | ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl); |
1563 | if (ret) { | 1588 | if (ret) { |
@@ -1576,21 +1601,6 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) | |||
1576 | } | 1601 | } |
1577 | } | 1602 | } |
1578 | 1603 | ||
1579 | /* Do not add GPIOs that can only generate GPEs to the IRQ domain */ | ||
1580 | for (i = 0; i < community->npins; i++) { | ||
1581 | const struct pinctrl_pin_desc *desc; | ||
1582 | u32 intsel; | ||
1583 | |||
1584 | desc = &community->pins[i]; | ||
1585 | |||
1586 | intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0)); | ||
1587 | intsel &= CHV_PADCTRL0_INTSEL_MASK; | ||
1588 | intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; | ||
1589 | |||
1590 | if (need_valid_mask && intsel >= community->nirqs) | ||
1591 | clear_bit(i, chip->irq.valid_mask); | ||
1592 | } | ||
1593 | |||
1594 | /* | 1604 | /* |
1595 | * The same set of machines in chv_no_valid_mask[] have incorrectly | 1605 | * The same set of machines in chv_no_valid_mask[] have incorrectly |
1596 | * configured GPIOs that generate spurious interrupts so we use | 1606 | * configured GPIOs that generate spurious interrupts so we use |
diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c index d9542c661ddc..f57bbbeb2495 100644 --- a/drivers/platform/x86/intel_int0002_vgpio.c +++ b/drivers/platform/x86/intel_int0002_vgpio.c | |||
@@ -152,6 +152,13 @@ static const struct x86_cpu_id int0002_cpu_ids[] = { | |||
152 | {} | 152 | {} |
153 | }; | 153 | }; |
154 | 154 | ||
155 | static void int0002_init_irq_valid_mask(struct gpio_chip *chip, | ||
156 | unsigned long *valid_mask, | ||
157 | unsigned int ngpios) | ||
158 | { | ||
159 | bitmap_clear(valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN); | ||
160 | } | ||
161 | |||
155 | static int int0002_probe(struct platform_device *pdev) | 162 | static int int0002_probe(struct platform_device *pdev) |
156 | { | 163 | { |
157 | struct device *dev = &pdev->dev; | 164 | struct device *dev = &pdev->dev; |
@@ -184,7 +191,7 @@ static int int0002_probe(struct platform_device *pdev) | |||
184 | chip->direction_output = int0002_gpio_direction_output; | 191 | chip->direction_output = int0002_gpio_direction_output; |
185 | chip->base = -1; | 192 | chip->base = -1; |
186 | chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1; | 193 | chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1; |
187 | chip->irq.need_valid_mask = true; | 194 | chip->irq.init_valid_mask = int0002_init_irq_valid_mask; |
188 | 195 | ||
189 | ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL); | 196 | ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL); |
190 | if (ret) { | 197 | if (ret) { |
@@ -192,8 +199,6 @@ static int int0002_probe(struct platform_device *pdev) | |||
192 | return ret; | 199 | return ret; |
193 | } | 200 | } |
194 | 201 | ||
195 | bitmap_clear(chip->irq.valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN); | ||
196 | |||
197 | /* | 202 | /* |
198 | * We manually request the irq here instead of passing a flow-handler | 203 | * We manually request the irq here instead of passing a flow-handler |
199 | * to gpiochip_set_chained_irqchip, because the irq is shared. | 204 | * to gpiochip_set_chained_irqchip, because the irq is shared. |
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index c667ad0c099d..f8245d67f070 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h | |||
@@ -202,11 +202,17 @@ struct gpio_irq_chip { | |||
202 | bool threaded; | 202 | bool threaded; |
203 | 203 | ||
204 | /** | 204 | /** |
205 | * @need_valid_mask: | 205 | * @init_valid_mask: optional routine to initialize @valid_mask, to be |
206 | * | 206 | * used if not all GPIO lines are valid interrupts. Sometimes some |
207 | * If set core allocates @valid_mask with all bits set to one. | 207 | * lines just cannot fire interrupts, and this routine, when defined, |
208 | * is passed a bitmap in "valid_mask" and it will have ngpios | ||
209 | * bits from 0..(ngpios-1) set to "1" as in valid. The callback can | ||
210 | * then directly set some bits to "0" if they cannot be used for | ||
211 | * interrupts. | ||
208 | */ | 212 | */ |
209 | bool need_valid_mask; | 213 | void (*init_valid_mask)(struct gpio_chip *chip, |
214 | unsigned long *valid_mask, | ||
215 | unsigned int ngpios); | ||
210 | 216 | ||
211 | /** | 217 | /** |
212 | * @valid_mask: | 218 | * @valid_mask: |