Blob Blame History Raw
From 55aedef50d4d810670916d9fce4a40d5da2079e7 Mon Sep 17 00:00:00 2001
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Date: Wed, 25 Jul 2018 15:42:08 +0300
Subject: [PATCH] pinctrl: intel: Do pin translation when lock IRQ
Git-commit: 55aedef50d4d810670916d9fce4a40d5da2079e7
Patch-mainline: v4.19-rc1
References: FATE#326296

Default GPIOLIB callbacks for request and release IRQ do not do a GPIO
to pin translation which is necessary for Intel hardware, such as Intel
Cannonlake. Absence of the translation prevents some pins to be locked
as IRQ due to direction check. Introduce own callbacks to make
translation possible to avoid above issue.

Fixes: a60eac3239f0 ("pinctrl: intel: Allow custom GPIO base for pad groups")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/pinctrl/intel/pinctrl-intel.c |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -872,6 +872,34 @@ static int intel_gpio_to_pin(struct inte
 	return -EINVAL;
 }
 
+static int intel_gpio_irq_reqres(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
+	if (pin >= 0) {
+		if (gpiochip_lock_as_irq(gc, pin)) {
+			dev_err(pctrl->dev, "unable to lock HW IRQ %d for IRQ\n",
+				pin);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static void intel_gpio_irq_relres(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
+	if (pin >= 0)
+		gpiochip_unlock_as_irq(gc, pin);
+}
+
 static void intel_gpio_irq_ack(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
@@ -1087,6 +1115,8 @@ static irqreturn_t intel_gpio_irq(int ir
 
 static struct irq_chip intel_gpio_irqchip = {
 	.name = "intel-gpio",
+	.irq_request_resources = intel_gpio_irq_reqres,
+	.irq_release_resources = intel_gpio_irq_relres,
 	.irq_enable = intel_gpio_irq_enable,
 	.irq_ack = intel_gpio_irq_ack,
 	.irq_mask = intel_gpio_irq_mask,