Skip to content

Commit 96147db

Browse files
westerilinusw
authored andcommitted
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: a60eac3 ("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> Tested-by: Rajat Jain <rajatja@google.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 8e2aac3 commit 96147db

File tree

1 file changed

+63
-48
lines changed

1 file changed

+63
-48
lines changed

drivers/pinctrl/intel/pinctrl-intel.c

Lines changed: 63 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -747,13 +747,63 @@ static const struct pinctrl_desc intel_pinctrl_desc = {
747747
.owner = THIS_MODULE,
748748
};
749749

750+
/**
751+
* intel_gpio_to_pin() - Translate from GPIO offset to pin number
752+
* @pctrl: Pinctrl structure
753+
* @offset: GPIO offset from gpiolib
754+
* @commmunity: Community is filled here if not %NULL
755+
* @padgrp: Pad group is filled here if not %NULL
756+
*
757+
* When coming through gpiolib irqchip, the GPIO offset is not
758+
* automatically translated to pinctrl pin number. This function can be
759+
* used to find out the corresponding pinctrl pin.
760+
*/
761+
static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
762+
const struct intel_community **community,
763+
const struct intel_padgroup **padgrp)
764+
{
765+
int i;
766+
767+
for (i = 0; i < pctrl->ncommunities; i++) {
768+
const struct intel_community *comm = &pctrl->communities[i];
769+
int j;
770+
771+
for (j = 0; j < comm->ngpps; j++) {
772+
const struct intel_padgroup *pgrp = &comm->gpps[j];
773+
774+
if (pgrp->gpio_base < 0)
775+
continue;
776+
777+
if (offset >= pgrp->gpio_base &&
778+
offset < pgrp->gpio_base + pgrp->size) {
779+
int pin;
780+
781+
pin = pgrp->base + offset - pgrp->gpio_base;
782+
if (community)
783+
*community = comm;
784+
if (padgrp)
785+
*padgrp = pgrp;
786+
787+
return pin;
788+
}
789+
}
790+
}
791+
792+
return -EINVAL;
793+
}
794+
750795
static int intel_gpio_get(struct gpio_chip *chip, unsigned offset)
751796
{
752797
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
753798
void __iomem *reg;
754799
u32 padcfg0;
800+
int pin;
801+
802+
pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
803+
if (pin < 0)
804+
return -EINVAL;
755805

756-
reg = intel_get_padcfg(pctrl, offset, PADCFG0);
806+
reg = intel_get_padcfg(pctrl, pin, PADCFG0);
757807
if (!reg)
758808
return -EINVAL;
759809

@@ -770,8 +820,13 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
770820
unsigned long flags;
771821
void __iomem *reg;
772822
u32 padcfg0;
823+
int pin;
824+
825+
pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
826+
if (pin < 0)
827+
return;
773828

774-
reg = intel_get_padcfg(pctrl, offset, PADCFG0);
829+
reg = intel_get_padcfg(pctrl, pin, PADCFG0);
775830
if (!reg)
776831
return;
777832

@@ -790,8 +845,13 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
790845
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
791846
void __iomem *reg;
792847
u32 padcfg0;
848+
int pin;
793849

794-
reg = intel_get_padcfg(pctrl, offset, PADCFG0);
850+
pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL);
851+
if (pin < 0)
852+
return -EINVAL;
853+
854+
reg = intel_get_padcfg(pctrl, pin, PADCFG0);
795855
if (!reg)
796856
return -EINVAL;
797857

@@ -827,51 +887,6 @@ static const struct gpio_chip intel_gpio_chip = {
827887
.set_config = gpiochip_generic_config,
828888
};
829889

830-
/**
831-
* intel_gpio_to_pin() - Translate from GPIO offset to pin number
832-
* @pctrl: Pinctrl structure
833-
* @offset: GPIO offset from gpiolib
834-
* @commmunity: Community is filled here if not %NULL
835-
* @padgrp: Pad group is filled here if not %NULL
836-
*
837-
* When coming through gpiolib irqchip, the GPIO offset is not
838-
* automatically translated to pinctrl pin number. This function can be
839-
* used to find out the corresponding pinctrl pin.
840-
*/
841-
static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
842-
const struct intel_community **community,
843-
const struct intel_padgroup **padgrp)
844-
{
845-
int i;
846-
847-
for (i = 0; i < pctrl->ncommunities; i++) {
848-
const struct intel_community *comm = &pctrl->communities[i];
849-
int j;
850-
851-
for (j = 0; j < comm->ngpps; j++) {
852-
const struct intel_padgroup *pgrp = &comm->gpps[j];
853-
854-
if (pgrp->gpio_base < 0)
855-
continue;
856-
857-
if (offset >= pgrp->gpio_base &&
858-
offset < pgrp->gpio_base + pgrp->size) {
859-
int pin;
860-
861-
pin = pgrp->base + offset - pgrp->gpio_base;
862-
if (community)
863-
*community = comm;
864-
if (padgrp)
865-
*padgrp = pgrp;
866-
867-
return pin;
868-
}
869-
}
870-
}
871-
872-
return -EINVAL;
873-
}
874-
875890
static int intel_gpio_irq_reqres(struct irq_data *d)
876891
{
877892
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);

0 commit comments

Comments
 (0)