aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2016-09-20 08:15:22 -0400
committerLinus Walleij <linus.walleij@linaro.org>2016-09-23 08:57:33 -0400
commit47c950d1020226179d278297c85ba6a988ee398b (patch)
treea9736a87b36310c08443fbd92b945b93a5615621
parent0565f49cfe937640c2347f6d7f40ad2f4e4f088b (diff)
pinctrl: cherryview: Do not add all southwest and north GPIOs to IRQ domain
It turns out that for north and southwest communities, they can only generate GPIO interrupts for lower 8 interrupts (IntSel value). The upper part (8-15) can only generate GPEs (General Purpose Events). Now the reason why EC events such as pressing hotkeys does not work if we mask all the interrupts is that in order to generate either interrupts or GPEs the INTMASK register must have that particular interrupt unmasked. In case of GPEs the CPU does not trigger normal interrupt (and thus the GPIO driver does not see it) but instead it causes SCI (System Control Interrupt) to be triggered with the GPE in question set. To make this all work as expected we only add those GPIOs to the IRQ domain that can actually generate interrupts (IntSel value 0-7) and skip others. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/intel/pinctrl-cherryview.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c
index 0fe8fad25e4d..d23be3a2fb35 100644
--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -134,6 +134,7 @@ struct chv_gpio_pinrange {
134 * @gpio_ranges: An array of GPIO ranges in this community 134 * @gpio_ranges: An array of GPIO ranges in this community
135 * @ngpio_ranges: Number of GPIO ranges 135 * @ngpio_ranges: Number of GPIO ranges
136 * @ngpios: Total number of GPIOs in this community 136 * @ngpios: Total number of GPIOs in this community
137 * @nirqs: Total number of IRQs this community can generate
137 */ 138 */
138struct chv_community { 139struct chv_community {
139 const char *uid; 140 const char *uid;
@@ -146,6 +147,7 @@ struct chv_community {
146 const struct chv_gpio_pinrange *gpio_ranges; 147 const struct chv_gpio_pinrange *gpio_ranges;
147 size_t ngpio_ranges; 148 size_t ngpio_ranges;
148 size_t ngpios; 149 size_t ngpios;
150 size_t nirqs;
149}; 151};
150 152
151struct chv_pin_context { 153struct chv_pin_context {
@@ -396,6 +398,12 @@ static const struct chv_community southwest_community = {
396 .gpio_ranges = southwest_gpio_ranges, 398 .gpio_ranges = southwest_gpio_ranges,
397 .ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges), 399 .ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges),
398 .ngpios = ARRAY_SIZE(southwest_pins), 400 .ngpios = ARRAY_SIZE(southwest_pins),
401 /*
402 * Southwest community can benerate GPIO interrupts only for the
403 * first 8 interrupts. The upper half (8-15) can only be used to
404 * trigger GPEs.
405 */
406 .nirqs = 8,
399}; 407};
400 408
401static const struct pinctrl_pin_desc north_pins[] = { 409static const struct pinctrl_pin_desc north_pins[] = {
@@ -479,6 +487,12 @@ static const struct chv_community north_community = {
479 .gpio_ranges = north_gpio_ranges, 487 .gpio_ranges = north_gpio_ranges,
480 .ngpio_ranges = ARRAY_SIZE(north_gpio_ranges), 488 .ngpio_ranges = ARRAY_SIZE(north_gpio_ranges),
481 .ngpios = ARRAY_SIZE(north_pins), 489 .ngpios = ARRAY_SIZE(north_pins),
490 /*
491 * North community can benerate GPIO interrupts only for the first
492 * 8 interrupts. The upper half (8-15) can only be used to trigger
493 * GPEs.
494 */
495 .nirqs = 8,
482}; 496};
483 497
484static const struct pinctrl_pin_desc east_pins[] = { 498static const struct pinctrl_pin_desc east_pins[] = {
@@ -521,6 +535,7 @@ static const struct chv_community east_community = {
521 .gpio_ranges = east_gpio_ranges, 535 .gpio_ranges = east_gpio_ranges,
522 .ngpio_ranges = ARRAY_SIZE(east_gpio_ranges), 536 .ngpio_ranges = ARRAY_SIZE(east_gpio_ranges),
523 .ngpios = ARRAY_SIZE(east_pins), 537 .ngpios = ARRAY_SIZE(east_pins),
538 .nirqs = 16,
524}; 539};
525 540
526static const struct pinctrl_pin_desc southeast_pins[] = { 541static const struct pinctrl_pin_desc southeast_pins[] = {
@@ -646,6 +661,7 @@ static const struct chv_community southeast_community = {
646 .gpio_ranges = southeast_gpio_ranges, 661 .gpio_ranges = southeast_gpio_ranges,
647 .ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges), 662 .ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges),
648 .ngpios = ARRAY_SIZE(southeast_pins), 663 .ngpios = ARRAY_SIZE(southeast_pins),
664 .nirqs = 16,
649}; 665};
650 666
651static const struct chv_community *chv_communities[] = { 667static const struct chv_community *chv_communities[] = {
@@ -1497,7 +1513,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc)
1497 chained_irq_enter(chip, desc); 1513 chained_irq_enter(chip, desc);
1498 1514
1499 pending = readl(pctrl->regs + CHV_INTSTAT); 1515 pending = readl(pctrl->regs + CHV_INTSTAT);
1500 for_each_set_bit(intr_line, &pending, 16) { 1516 for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) {
1501 unsigned irq, offset; 1517 unsigned irq, offset;
1502 1518
1503 offset = pctrl->intr_lines[intr_line]; 1519 offset = pctrl->intr_lines[intr_line];
@@ -1520,6 +1536,7 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
1520 chip->label = dev_name(pctrl->dev); 1536 chip->label = dev_name(pctrl->dev);
1521 chip->parent = pctrl->dev; 1537 chip->parent = pctrl->dev;
1522 chip->base = -1; 1538 chip->base = -1;
1539 chip->irq_need_valid_mask = true;
1523 1540
1524 ret = gpiochip_add_data(chip, pctrl); 1541 ret = gpiochip_add_data(chip, pctrl);
1525 if (ret) { 1542 if (ret) {
@@ -1539,6 +1556,21 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
1539 offset += range->npins; 1556 offset += range->npins;
1540 } 1557 }
1541 1558
1559 /* Do not add GPIOs that can only generate GPEs to the IRQ domain */
1560 for (i = 0; i < pctrl->community->npins; i++) {
1561 const struct pinctrl_pin_desc *desc;
1562 u32 intsel;
1563
1564 desc = &pctrl->community->pins[i];
1565
1566 intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0));
1567 intsel &= CHV_PADCTRL0_INTSEL_MASK;
1568 intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
1569
1570 if (intsel >= pctrl->community->nirqs)
1571 clear_bit(i, chip->irq_valid_mask);
1572 }
1573
1542 /* Clear all interrupts */ 1574 /* Clear all interrupts */
1543 chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); 1575 chv_writel(0xffff, pctrl->regs + CHV_INTSTAT);
1544 1576