Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10dc890d authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files
Linus writes:
  "Pin control fixes for v4.19:
   - Two fixes for the Intel pin controllers than cause
     problems on laptops."

* tag 'pinctrl-v4.19-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: intel: Do pin translation in other GPIO operations as well
  pinctrl: cannonlake: Fix gpio base for GPP-E
parents a27fb6d9 96147db1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -379,7 +379,7 @@ static const struct intel_padgroup cnlh_community1_gpps[] = {
static const struct intel_padgroup cnlh_community3_gpps[] = {
	CNL_GPP(0, 155, 178, 192),		/* GPP_K */
	CNL_GPP(1, 179, 202, 224),		/* GPP_H */
	CNL_GPP(2, 203, 215, 258),		/* GPP_E */
	CNL_GPP(2, 203, 215, 256),		/* GPP_E */
	CNL_GPP(3, 216, 239, 288),		/* GPP_F */
	CNL_GPP(4, 240, 248, CNL_NO_GPIO),	/* SPI */
};
+63 −48
Original line number Diff line number Diff line
@@ -747,13 +747,63 @@ static const struct pinctrl_desc intel_pinctrl_desc = {
	.owner = THIS_MODULE,
};

/**
 * intel_gpio_to_pin() - Translate from GPIO offset to pin number
 * @pctrl: Pinctrl structure
 * @offset: GPIO offset from gpiolib
 * @commmunity: Community is filled here if not %NULL
 * @padgrp: Pad group is filled here if not %NULL
 *
 * When coming through gpiolib irqchip, the GPIO offset is not
 * automatically translated to pinctrl pin number. This function can be
 * used to find out the corresponding pinctrl pin.
 */
static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
			     const struct intel_community **community,
			     const struct intel_padgroup **padgrp)
{
	int i;

	for (i = 0; i < pctrl->ncommunities; i++) {
		const struct intel_community *comm = &pctrl->communities[i];
		int j;

		for (j = 0; j < comm->ngpps; j++) {
			const struct intel_padgroup *pgrp = &comm->gpps[j];

			if (pgrp->gpio_base < 0)
				continue;

			if (offset >= pgrp->gpio_base &&
			    offset < pgrp->gpio_base + pgrp->size) {
				int pin;

				pin = pgrp->base + offset - pgrp->gpio_base;
				if (community)
					*community = comm;
				if (padgrp)
					*padgrp = pgrp;

				return pin;
			}
		}
	}

	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, offset, PADCFG0);
	reg = intel_get_padcfg(pctrl, pin, PADCFG0);
	if (!reg)
		return -EINVAL;

@@ -770,8 +820,13 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
	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, offset, PADCFG0);
	reg = intel_get_padcfg(pctrl, pin, PADCFG0);
	if (!reg)
		return;

@@ -790,8 +845,13 @@ 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;

	reg = intel_get_padcfg(pctrl, offset, PADCFG0);
	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;

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

/**
 * intel_gpio_to_pin() - Translate from GPIO offset to pin number
 * @pctrl: Pinctrl structure
 * @offset: GPIO offset from gpiolib
 * @commmunity: Community is filled here if not %NULL
 * @padgrp: Pad group is filled here if not %NULL
 *
 * When coming through gpiolib irqchip, the GPIO offset is not
 * automatically translated to pinctrl pin number. This function can be
 * used to find out the corresponding pinctrl pin.
 */
static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
			     const struct intel_community **community,
			     const struct intel_padgroup **padgrp)
{
	int i;

	for (i = 0; i < pctrl->ncommunities; i++) {
		const struct intel_community *comm = &pctrl->communities[i];
		int j;

		for (j = 0; j < comm->ngpps; j++) {
			const struct intel_padgroup *pgrp = &comm->gpps[j];

			if (pgrp->gpio_base < 0)
				continue;

			if (offset >= pgrp->gpio_base &&
			    offset < pgrp->gpio_base + pgrp->size) {
				int pin;

				pin = pgrp->base + offset - pgrp->gpio_base;
				if (community)
					*community = comm;
				if (padgrp)
					*padgrp = pgrp;

				return pin;
			}
		}
	}

	return -EINVAL;
}

static int intel_gpio_irq_reqres(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);