diff mbox

[v2,1/1] pinctrl: baytrail: Do not add all GPIOs to IRQ domain

Message ID 20170111134900.31026-1-andriy.shevchenko@linux.intel.com
State New
Headers show

Commit Message

Andy Shevchenko Jan. 11, 2017, 1:49 p.m. UTC
When DIRECT_IRQ_EN is set, the pin is routed directly to the IO-APIC bypassing
the GPIO driver completely. However, the mask register is still used to
determine if the pin is supposed to generate IRQ or not.

So with commit 3ae02c14d964 the IRQ core masks all IRQs (because of
handle_bad_irq()) the pin connected to the touchscreen gets masked as well and
hence no interrupts.

To make this all work as expected we do not add those GPIOs to the IRQ domain
that can actually propagate interrupts.

Fixes: 3ae02c14d964 ("pinctrl: intel: set default handler to be handle_bad_irq()")
Reported-by: Robert R. Howell <rhowell@uwyo.edu>
Suggested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
In v3:
- drop upstreamed patch
- fix commit message (Mika)
- add Suggested-by tag
 drivers/pinctrl/intel/pinctrl-baytrail.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

Comments

Mika Westerberg Jan. 11, 2017, 2:02 p.m. UTC | #1
On Wed, Jan 11, 2017 at 03:49:00PM +0200, Andy Shevchenko wrote:
> When DIRECT_IRQ_EN is set, the pin is routed directly to the IO-APIC bypassing
> the GPIO driver completely. However, the mask register is still used to
> determine if the pin is supposed to generate IRQ or not.
> 
> So with commit 3ae02c14d964 the IRQ core masks all IRQs (because of
> handle_bad_irq()) the pin connected to the touchscreen gets masked as well and
> hence no interrupts.
> 
> To make this all work as expected we do not add those GPIOs to the IRQ domain
> that can actually propagate interrupts.
> 
> Fixes: 3ae02c14d964 ("pinctrl: intel: set default handler to be handle_bad_irq()")
> Reported-by: Robert R. Howell <rhowell@uwyo.edu>
> Suggested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij Jan. 12, 2017, 7:12 a.m. UTC | #2
On Wed, Jan 11, 2017 at 2:49 PM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> When DIRECT_IRQ_EN is set, the pin is routed directly to the IO-APIC bypassing
> the GPIO driver completely. However, the mask register is still used to
> determine if the pin is supposed to generate IRQ or not.
>
> So with commit 3ae02c14d964 the IRQ core masks all IRQs (because of
> handle_bad_irq()) the pin connected to the touchscreen gets masked as well and
> hence no interrupts.
>
> To make this all work as expected we do not add those GPIOs to the IRQ domain
> that can actually propagate interrupts.
>
> Fixes: 3ae02c14d964 ("pinctrl: intel: set default handler to be handle_bad_irq()")
> Reported-by: Robert R. Howell <rhowell@uwyo.edu>
> Suggested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> In v3:

Patch applied for fixes.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index 000eb79ecf07..e696a01365cb 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -1623,6 +1623,8 @@  static void byt_gpio_irq_handler(struct irq_desc *desc)
 
 static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
 {
+	struct gpio_chip *gc = &vg->chip;
+	struct device *dev = &vg->pdev->dev;
 	void __iomem *reg;
 	u32 base, value;
 	int i;
@@ -1644,10 +1646,12 @@  static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
 		}
 
 		value = readl(reg);
-		if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i) &&
-		    !(value & BYT_DIRECT_IRQ_EN)) {
+		if (value & BYT_DIRECT_IRQ_EN) {
+			clear_bit(i, gc->irq_valid_mask);
+			dev_dbg(dev, "excluding GPIO %d from IRQ domain\n", i);
+		} else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) {
 			byt_gpio_clear_triggering(vg, i);
-			dev_dbg(&vg->pdev->dev, "disabling GPIO %d\n", i);
+			dev_dbg(dev, "disabling GPIO %d\n", i);
 		}
 	}
 
@@ -1686,6 +1690,7 @@  static int byt_gpio_probe(struct byt_gpio *vg)
 	gc->can_sleep	= false;
 	gc->parent	= &vg->pdev->dev;
 	gc->ngpio	= vg->soc_data->npins;
+	gc->irq_need_valid_mask	= true;
 
 #ifdef CONFIG_PM_SLEEP
 	vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio,