FROMLIST: pinctrl: intel: Do pin translation in other GPIO operations as well

For some reason I thought GPIOLIB handles translation from GPIO ranges
to pinctrl pins but it turns out not to be the case. This means that
when GPIOs operations are performed for a pin controller having a custom
GPIO base such as Cannon Lake and Ice Lake incorrect pin number gets
used internally.

Fix this in the same way we did for lock/unlock IRQ operations and
translate the GPIO number to pin before using it.

Fixes: a60eac3239f0 ("pinctrl: intel: Allow custom GPIO base for pad groups")
Reported-by: Rajat Jain <rajatja@google.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
(am from https://lore.kernel.org/patchwork/patch/988007/)

BUG=b:112056767
TEST=verify that the driver starts writing to correct offset.

Change-Id: I6f7621351e53826f40a95028e1cf9e62b6417062
Reviewed-on: https://chromium-review.googlesource.com/1232322
Tested-by: Rajat Jain <rajatja@chromium.org>
Tested-by: Casey G Bowman <casey.g.bowman@intel.com>
Reviewed-by: Matthew S Atwood <matthew.s.atwood@intel.corp-partner.google.com>
Reviewed-by: Dmitry Torokhov <dtor@chromium.org>
Commit-Queue: Rajat Jain <rajatja@chromium.org>
Trybot-Ready: Rajat Jain <rajatja@chromium.org>
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
index 5fd6b07..fbd1639 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -750,86 +750,6 @@
 	.owner = THIS_MODULE,
 };
 
-static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
-	void __iomem *reg;
-	u32 padcfg0;
-
-	reg = intel_get_padcfg(pctrl, offset, PADCFG0);
-	if (!reg)
-		return -EINVAL;
-
-	padcfg0 = readl(reg);
-	if (!(padcfg0 & PADCFG0_GPIOTXDIS))
-		return !!(padcfg0 & PADCFG0_GPIOTXSTATE);
-
-	return !!(padcfg0 & PADCFG0_GPIORXSTATE);
-}
-
-static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
-	unsigned long flags;
-	void __iomem *reg;
-	u32 padcfg0;
-
-	reg = intel_get_padcfg(pctrl, offset, PADCFG0);
-	if (!reg)
-		return;
-
-	raw_spin_lock_irqsave(&pctrl->lock, flags);
-	padcfg0 = readl(reg);
-	if (value)
-		padcfg0 |= PADCFG0_GPIOTXSTATE;
-	else
-		padcfg0 &= ~PADCFG0_GPIOTXSTATE;
-	writel(padcfg0, reg);
-	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
-}
-
-static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
-{
-	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
-	void __iomem *reg;
-	u32 padcfg0;
-
-	reg = intel_get_padcfg(pctrl, offset, PADCFG0);
-	if (!reg)
-		return -EINVAL;
-
-	padcfg0 = readl(reg);
-
-	if (padcfg0 & PADCFG0_PMODE_MASK)
-		return -EINVAL;
-
-	return !!(padcfg0 & PADCFG0_GPIOTXDIS);
-}
-
-static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	return pinctrl_gpio_direction_input(chip->base + offset);
-}
-
-static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
-				       int value)
-{
-	intel_gpio_set(chip, offset, value);
-	return pinctrl_gpio_direction_output(chip->base + offset);
-}
-
-static const struct gpio_chip intel_gpio_chip = {
-	.owner = THIS_MODULE,
-	.request = gpiochip_generic_request,
-	.free = gpiochip_generic_free,
-	.get_direction = intel_gpio_get_direction,
-	.direction_input = intel_gpio_direction_input,
-	.direction_output = intel_gpio_direction_output,
-	.get = intel_gpio_get,
-	.set = intel_gpio_set,
-	.set_config = gpiochip_generic_config,
-};
-
 /**
  * intel_gpio_to_pin() - Translate from GPIO offset to pin number
  * @pctrl: Pinctrl structure
@@ -875,6 +795,101 @@
 	return -EINVAL;
 }
 
+static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
+	void __iomem *reg;
+	u32 padcfg0;
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
+	if (pin < 0)
+		return -EINVAL;
+
+	reg = intel_get_padcfg(pctrl, pin, PADCFG0);
+	if (!reg)
+		return -EINVAL;
+
+	padcfg0 = readl(reg);
+	if (!(padcfg0 & PADCFG0_GPIOTXDIS))
+		return !!(padcfg0 & PADCFG0_GPIOTXSTATE);
+
+	return !!(padcfg0 & PADCFG0_GPIORXSTATE);
+}
+
+static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
+	unsigned long flags;
+	void __iomem *reg;
+	u32 padcfg0;
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
+	if (pin < 0)
+		return;
+
+	reg = intel_get_padcfg(pctrl, pin, PADCFG0);
+	if (!reg)
+		return;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	padcfg0 = readl(reg);
+	if (value)
+		padcfg0 |= PADCFG0_GPIOTXSTATE;
+	else
+		padcfg0 &= ~PADCFG0_GPIOTXSTATE;
+	writel(padcfg0, reg);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
+	void __iomem *reg;
+	u32 padcfg0;
+	int pin;
+
+	pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
+	if (pin < 0)
+		return -EINVAL;
+
+	reg = intel_get_padcfg(pctrl, pin, PADCFG0);
+	if (!reg)
+		return -EINVAL;
+
+	padcfg0 = readl(reg);
+
+	if (padcfg0 & PADCFG0_PMODE_MASK)
+		return -EINVAL;
+
+	return !!(padcfg0 & PADCFG0_GPIOTXDIS);
+}
+
+static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+				       int value)
+{
+	intel_gpio_set(chip, offset, value);
+	return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static const struct gpio_chip intel_gpio_chip = {
+	.owner = THIS_MODULE,
+	.request = gpiochip_generic_request,
+	.free = gpiochip_generic_free,
+	.get_direction = intel_gpio_get_direction,
+	.direction_input = intel_gpio_direction_input,
+	.direction_output = intel_gpio_direction_output,
+	.get = intel_gpio_get,
+	.set = intel_gpio_set,
+	.set_config = gpiochip_generic_config,
+};
+
 static int intel_gpio_irq_reqres(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);