From 4e7293e3a2a367d0935925988acfd941549ce489 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:44 +0300 Subject: [PATCH 01/24] pinctrl: cherryview: Introduce chv_readl() helper There are plenty of places where we call readl(chv_padreg(pctrl, offset, ...)); Replace them with newly introduced chv_readl() helper chv_readl(pctrl, offset, ...); Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-cherryview.c | 71 +++++++++++----------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 8e3953a223d0..afff7c0fc33f 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -610,6 +610,11 @@ static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset, return pctrl->regs + offset + reg; } +static u32 chv_readl(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int offset) +{ + return readl(chv_padreg(pctrl, pin, offset)); +} + static void chv_writel(u32 value, void __iomem *reg) { writel(value, reg); @@ -620,10 +625,7 @@ static void chv_writel(u32 value, void __iomem *reg) /* When Pad Cfg is locked, driver can only change GPIOTXState or GPIORXState */ static bool chv_pad_locked(struct chv_pinctrl *pctrl, unsigned int offset) { - void __iomem *reg; - - reg = chv_padreg(pctrl, offset, CHV_PADCTRL1); - return readl(reg) & CHV_PADCTRL1_CFGLOCK; + return chv_readl(pctrl, offset, CHV_PADCTRL1) & CHV_PADCTRL1_CFGLOCK; } static int chv_get_groups_count(struct pinctrl_dev *pctldev) @@ -661,8 +663,8 @@ static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); - ctrl1 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL1)); + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); + ctrl1 = chv_readl(pctrl, offset, CHV_PADCTRL1); locked = chv_pad_locked(pctrl, offset); raw_spin_unlock_irqrestore(&chv_lock, flags); @@ -758,7 +760,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, mode &= ~PINMODE_INVERT_OE; reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); - value = readl(reg); + value = chv_readl(pctrl, pin, CHV_PADCTRL0); /* Disable GPIO mode */ value &= ~CHV_PADCTRL0_GPIOEN; /* Set to desired mode */ @@ -768,7 +770,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, /* Update for invert_oe */ reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); - value = readl(reg) & ~CHV_PADCTRL1_INVRXTX_MASK; + value = chv_readl(pctrl, pin, CHV_PADCTRL1) & ~CHV_PADCTRL1_INVRXTX_MASK; if (invert_oe) value |= CHV_PADCTRL1_INVRXTX_TXENABLE; chv_writel(value, reg); @@ -789,7 +791,7 @@ static void chv_gpio_clear_triggering(struct chv_pinctrl *pctrl, u32 value; reg = chv_padreg(pctrl, offset, CHV_PADCTRL1); - value = readl(reg); + value = chv_readl(pctrl, offset, CHV_PADCTRL1); value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; value &= ~CHV_PADCTRL1_INVRXTX_MASK; chv_writel(value, reg); @@ -807,7 +809,7 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, raw_spin_lock_irqsave(&chv_lock, flags); if (chv_pad_locked(pctrl, offset)) { - value = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); + value = chv_readl(pctrl, offset, CHV_PADCTRL0); if (!(value & CHV_PADCTRL0_GPIOEN)) { /* Locked so cannot enable */ raw_spin_unlock_irqrestore(&chv_lock, flags); @@ -828,7 +830,7 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, chv_gpio_clear_triggering(pctrl, offset); reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); - value = readl(reg); + value = chv_readl(pctrl, offset, CHV_PADCTRL0); /* * If the pin is in HiZ mode (both TX and RX buffers are @@ -877,7 +879,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIOCFG_MASK; + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0) & ~CHV_PADCTRL0_GPIOCFG_MASK; if (input) ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; else @@ -910,8 +912,8 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin, u32 term; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); - ctrl1 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1)); + ctrl0 = chv_readl(pctrl, pin, CHV_PADCTRL0); + ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); raw_spin_unlock_irqrestore(&chv_lock, flags); term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT; @@ -987,7 +989,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin, u32 ctrl0, pull; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(reg); + ctrl0 = chv_readl(pctrl, pin, CHV_PADCTRL0); switch (param) { case PIN_CONFIG_BIAS_DISABLE: @@ -1053,7 +1055,7 @@ static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin, u32 ctrl1; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl1 = readl(reg); + ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); if (enable) ctrl1 |= CHV_PADCTRL1_ODEN; @@ -1175,7 +1177,7 @@ static int chv_gpio_get(struct gpio_chip *chip, unsigned int offset) u32 ctrl0, cfg; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); raw_spin_unlock_irqrestore(&chv_lock, flags); cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; @@ -1196,7 +1198,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) raw_spin_lock_irqsave(&chv_lock, flags); reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); - ctrl0 = readl(reg); + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); if (value) ctrl0 |= CHV_PADCTRL0_GPIOTXSTATE; @@ -1215,7 +1217,7 @@ static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) unsigned long flags; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); raw_spin_unlock_irqrestore(&chv_lock, flags); direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; @@ -1259,7 +1261,7 @@ static void chv_gpio_irq_ack(struct irq_data *d) raw_spin_lock(&chv_lock); - intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0); intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT); @@ -1277,7 +1279,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) raw_spin_lock_irqsave(&chv_lock, flags); - intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0); intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; @@ -1322,11 +1324,11 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) u32 intsel, value; raw_spin_lock_irqsave(&chv_lock, flags); - intsel = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + intsel = chv_readl(pctrl, pin, CHV_PADCTRL0); intsel &= CHV_PADCTRL0_INTSEL_MASK; intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; - value = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1)); + value = chv_readl(pctrl, pin, CHV_PADCTRL1); if (value & CHV_PADCTRL1_INTWAKECFG_LEVEL) handler = handle_level_irq; else @@ -1369,7 +1371,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) if (!chv_pad_locked(pctrl, pin)) { void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); - value = readl(reg); + value = chv_readl(pctrl, pin, CHV_PADCTRL1); value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; value &= ~CHV_PADCTRL1_INVRXTX_MASK; @@ -1389,7 +1391,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) chv_writel(value, reg); } - value = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + value = chv_readl(pctrl, pin, CHV_PADCTRL0); value &= CHV_PADCTRL0_INTSEL_MASK; value >>= CHV_PADCTRL0_INTSEL_SHIFT; @@ -1487,7 +1489,7 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip, desc = &community->pins[i]; - intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0)); + intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0); intsel &= CHV_PADCTRL0_INTSEL_MASK; intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; @@ -1721,7 +1723,6 @@ static int chv_pinctrl_suspend_noirq(struct device *dev) for (i = 0; i < pctrl->community->npins; i++) { const struct pinctrl_pin_desc *desc; struct chv_pin_context *ctx; - void __iomem *reg; desc = &pctrl->community->pins[i]; if (chv_pad_locked(pctrl, desc->number)) @@ -1729,11 +1730,10 @@ static int chv_pinctrl_suspend_noirq(struct device *dev) ctx = &pctrl->saved_pin_context[i]; - reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL0); - ctx->padctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIORXSTATE; + ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0); + ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE; - reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL1); - ctx->padctrl1 = readl(reg); + ctx->padctrl1 = chv_readl(pctrl, desc->number, CHV_PADCTRL1); } raw_spin_unlock_irqrestore(&chv_lock, flags); @@ -1770,19 +1770,20 @@ static int chv_pinctrl_resume_noirq(struct device *dev) /* Only restore if our saved state differs from the current */ reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL0); - val = readl(reg) & ~CHV_PADCTRL0_GPIORXSTATE; + val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); + val &= ~CHV_PADCTRL0_GPIORXSTATE; if (ctx->padctrl0 != val) { chv_writel(ctx->padctrl0, reg); dev_dbg(pctrl->dev, "restored pin %2u ctrl0 0x%08x\n", - desc->number, readl(reg)); + desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL0)); } reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL1); - val = readl(reg); + val = chv_readl(pctrl, desc->number, CHV_PADCTRL1); if (ctx->padctrl1 != val) { chv_writel(ctx->padctrl1, reg); dev_dbg(pctrl->dev, "restored pin %2u ctrl1 0x%08x\n", - desc->number, readl(reg)); + desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL1)); } } From 99fd6512278e08a0fb264e3b83eccbbf0ff30967 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:45 +0300 Subject: [PATCH 02/24] pinctrl: cherryview: Introduce helpers to IO with common registers Pin control device and effectively the single community in it has a set of common registers. It's good to have a helpers to IO on them. Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-cherryview.c | 39 ++++++++++++++-------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index afff7c0fc33f..28ed2f3b42a1 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -598,6 +598,20 @@ static const struct chv_community *chv_communities[] = { */ static DEFINE_RAW_SPINLOCK(chv_lock); +static u32 chv_pctrl_readl(struct chv_pinctrl *pctrl, unsigned int offset) +{ + return readl(pctrl->regs + offset); +} + +static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32 value) +{ + void __iomem *reg = pctrl->regs + offset; + + /* Write and simple read back to confirm the bus transferring done */ + writel(value, reg); + readl(reg); +} + static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset, unsigned int reg) { @@ -1264,7 +1278,7 @@ static void chv_gpio_irq_ack(struct irq_data *d) intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0); intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; - chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT); + chv_pctrl_writel(pctrl, CHV_INTSTAT, BIT(intr_line)); raw_spin_unlock(&chv_lock); } @@ -1283,12 +1297,12 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; - value = readl(pctrl->regs + CHV_INTMASK); + value = chv_pctrl_readl(pctrl, CHV_INTMASK); if (mask) value &= ~BIT(intr_line); else value |= BIT(intr_line); - chv_writel(value, pctrl->regs + CHV_INTMASK); + chv_pctrl_writel(pctrl, CHV_INTMASK, value); raw_spin_unlock_irqrestore(&chv_lock, flags); } @@ -1419,7 +1433,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) chained_irq_enter(chip, desc); raw_spin_lock_irqsave(&chv_lock, flags); - pending = readl(pctrl->regs + CHV_INTSTAT); + pending = chv_pctrl_readl(pctrl, CHV_INTSTAT); raw_spin_unlock_irqrestore(&chv_lock, flags); for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) { @@ -1514,12 +1528,11 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip) * Mask all interrupts the community is able to generate * but leave the ones that can only generate GPEs unmasked. */ - chv_writel(GENMASK(31, pctrl->community->nirqs), - pctrl->regs + CHV_INTMASK); + chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, pctrl->community->nirqs)); } /* Clear all interrupts */ - chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); + chv_pctrl_writel(pctrl, CHV_INTSTAT, 0xffff); return 0; } @@ -1618,9 +1631,9 @@ static acpi_status chv_pinctrl_mmio_access_handler(u32 function, raw_spin_lock_irqsave(&chv_lock, flags); if (function == ACPI_WRITE) - chv_writel((u32)(*value), pctrl->regs + (u32)address); + chv_pctrl_writel(pctrl, address, *value); else if (function == ACPI_READ) - *value = readl(pctrl->regs + (u32)address); + *value = chv_pctrl_readl(pctrl, address); else ret = AE_BAD_PARAMETER; @@ -1718,7 +1731,7 @@ static int chv_pinctrl_suspend_noirq(struct device *dev) raw_spin_lock_irqsave(&chv_lock, flags); - pctrl->saved_intmask = readl(pctrl->regs + CHV_INTMASK); + pctrl->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); for (i = 0; i < pctrl->community->npins; i++) { const struct pinctrl_pin_desc *desc; @@ -1754,7 +1767,7 @@ static int chv_pinctrl_resume_noirq(struct device *dev) * registers because we don't know in which state BIOS left them * upon exiting suspend. */ - chv_writel(0, pctrl->regs + CHV_INTMASK); + chv_pctrl_writel(pctrl, CHV_INTMASK, 0x0000); for (i = 0; i < pctrl->community->npins; i++) { const struct pinctrl_pin_desc *desc; @@ -1791,8 +1804,8 @@ static int chv_pinctrl_resume_noirq(struct device *dev) * Now that all pins are restored to known state, we can restore * the interrupt mask register as well. */ - chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); - chv_writel(pctrl->saved_intmask, pctrl->regs + CHV_INTMASK); + chv_pctrl_writel(pctrl, CHV_INTSTAT, 0xffff); + chv_pctrl_writel(pctrl, CHV_INTMASK, pctrl->saved_intmask); raw_spin_unlock_irqrestore(&chv_lock, flags); From bfc8a4baec9377b3fdd2bbeafaf5a7f2c95b1151 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:46 +0300 Subject: [PATCH 03/24] pinctrl: cherryview: Convert chv_writel() to use chv_padreg() chv_writel() is now solely used for cases where we write data to the PAD registers. In order to simplify callers, calculate register address inside chv_writel(). Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-cherryview.c | 48 ++++++++-------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 28ed2f3b42a1..1fc46dfb880e 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -629,10 +629,12 @@ static u32 chv_readl(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int o return readl(chv_padreg(pctrl, pin, offset)); } -static void chv_writel(u32 value, void __iomem *reg) +static void chv_writel(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int offset, u32 value) { + void __iomem *reg = chv_padreg(pctrl, pin, offset); + + /* Write and simple read back to confirm the bus transferring done */ writel(value, reg); - /* simple readback to confirm the bus transferring done */ readl(reg); } @@ -758,7 +760,6 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, for (i = 0; i < grp->npins; i++) { int pin = grp->pins[i]; - void __iomem *reg; unsigned int mode; bool invert_oe; u32 value; @@ -773,21 +774,19 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, invert_oe = mode & PINMODE_INVERT_OE; mode &= ~PINMODE_INVERT_OE; - reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); value = chv_readl(pctrl, pin, CHV_PADCTRL0); /* Disable GPIO mode */ value &= ~CHV_PADCTRL0_GPIOEN; /* Set to desired mode */ value &= ~CHV_PADCTRL0_PMODE_MASK; value |= mode << CHV_PADCTRL0_PMODE_SHIFT; - chv_writel(value, reg); + chv_writel(pctrl, pin, CHV_PADCTRL0, value); /* Update for invert_oe */ - reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); value = chv_readl(pctrl, pin, CHV_PADCTRL1) & ~CHV_PADCTRL1_INVRXTX_MASK; if (invert_oe) value |= CHV_PADCTRL1_INVRXTX_TXENABLE; - chv_writel(value, reg); + chv_writel(pctrl, pin, CHV_PADCTRL1, value); dev_dbg(pctrl->dev, "configured pin %u mode %u OE %sinverted\n", pin, mode, invert_oe ? "" : "not "); @@ -801,14 +800,12 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, static void chv_gpio_clear_triggering(struct chv_pinctrl *pctrl, unsigned int offset) { - void __iomem *reg; u32 value; - reg = chv_padreg(pctrl, offset, CHV_PADCTRL1); value = chv_readl(pctrl, offset, CHV_PADCTRL1); value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; value &= ~CHV_PADCTRL1_INVRXTX_MASK; - chv_writel(value, reg); + chv_writel(pctrl, offset, CHV_PADCTRL1, value); } static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, @@ -817,7 +814,6 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); unsigned long flags; - void __iomem *reg; u32 value; raw_spin_lock_irqsave(&chv_lock, flags); @@ -843,7 +839,6 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, /* Disable interrupt generation */ chv_gpio_clear_triggering(pctrl, offset); - reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); value = chv_readl(pctrl, offset, CHV_PADCTRL0); /* @@ -853,13 +848,12 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, if ((value & CHV_PADCTRL0_GPIOCFG_MASK) == (CHV_PADCTRL0_GPIOCFG_HIZ << CHV_PADCTRL0_GPIOCFG_SHIFT)) { value &= ~CHV_PADCTRL0_GPIOCFG_MASK; - value |= CHV_PADCTRL0_GPIOCFG_GPI << - CHV_PADCTRL0_GPIOCFG_SHIFT; + value |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; } /* Switch to a GPIO mode */ value |= CHV_PADCTRL0_GPIOEN; - chv_writel(value, reg); + chv_writel(pctrl, offset, CHV_PADCTRL0, value); } raw_spin_unlock_irqrestore(&chv_lock, flags); @@ -887,7 +881,6 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, unsigned int offset, bool input) { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - void __iomem *reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); unsigned long flags; u32 ctrl0; @@ -898,7 +891,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; else ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT; - chv_writel(ctrl0, reg); + chv_writel(pctrl, offset, CHV_PADCTRL0, ctrl0); raw_spin_unlock_irqrestore(&chv_lock, flags); @@ -998,7 +991,6 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin, static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin, enum pin_config_param param, u32 arg) { - void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); unsigned long flags; u32 ctrl0, pull; @@ -1055,7 +1047,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin, return -EINVAL; } - chv_writel(ctrl0, reg); + chv_writel(pctrl, pin, CHV_PADCTRL0, ctrl0); raw_spin_unlock_irqrestore(&chv_lock, flags); return 0; @@ -1064,7 +1056,6 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin, static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin, bool enable) { - void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); unsigned long flags; u32 ctrl1; @@ -1076,7 +1067,7 @@ static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin, else ctrl1 &= ~CHV_PADCTRL1_ODEN; - chv_writel(ctrl1, reg); + chv_writel(pctrl, pin, CHV_PADCTRL1, ctrl1); raw_spin_unlock_irqrestore(&chv_lock, flags); return 0; @@ -1206,12 +1197,10 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); unsigned long flags; - void __iomem *reg; u32 ctrl0; raw_spin_lock_irqsave(&chv_lock, flags); - reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); if (value) @@ -1219,7 +1208,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) else ctrl0 &= ~CHV_PADCTRL0_GPIOTXSTATE; - chv_writel(ctrl0, reg); + chv_writel(pctrl, offset, CHV_PADCTRL0, ctrl0); raw_spin_unlock_irqrestore(&chv_lock, flags); } @@ -1383,8 +1372,6 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) * Driver programs the IntWakeCfg bits and save the mapping. */ if (!chv_pad_locked(pctrl, pin)) { - void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); - value = chv_readl(pctrl, pin, CHV_PADCTRL1); value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; value &= ~CHV_PADCTRL1_INVRXTX_MASK; @@ -1402,7 +1389,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) value |= CHV_PADCTRL1_INVRXTX_RXDATA; } - chv_writel(value, reg); + chv_writel(pctrl, pin, CHV_PADCTRL1, value); } value = chv_readl(pctrl, pin, CHV_PADCTRL0); @@ -1772,7 +1759,6 @@ static int chv_pinctrl_resume_noirq(struct device *dev) for (i = 0; i < pctrl->community->npins; i++) { const struct pinctrl_pin_desc *desc; const struct chv_pin_context *ctx; - void __iomem *reg; u32 val; desc = &pctrl->community->pins[i]; @@ -1782,19 +1768,17 @@ static int chv_pinctrl_resume_noirq(struct device *dev) ctx = &pctrl->saved_pin_context[i]; /* Only restore if our saved state differs from the current */ - reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL0); val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); val &= ~CHV_PADCTRL0_GPIORXSTATE; if (ctx->padctrl0 != val) { - chv_writel(ctx->padctrl0, reg); + chv_writel(pctrl, desc->number, CHV_PADCTRL0, ctx->padctrl0); dev_dbg(pctrl->dev, "restored pin %2u ctrl0 0x%08x\n", desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL0)); } - reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL1); val = chv_readl(pctrl, desc->number, CHV_PADCTRL1); if (ctx->padctrl1 != val) { - chv_writel(ctx->padctrl1, reg); + chv_writel(pctrl, desc->number, CHV_PADCTRL1, ctx->padctrl1); dev_dbg(pctrl->dev, "restored pin %2u ctrl1 0x%08x\n", desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL1)); } From 42fecd55c772549b88ec10841b7f4ab2330c44b5 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:47 +0300 Subject: [PATCH 04/24] pinctrl: intel: Allow drivers to define total amount of IRQs per community Some of the pin control devices may not be capable to generate IRQ per each pin in the community. Allow individual drivers to define total amount of IRQs per community. Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index cc78c483518f..0f01ef3fdfdd 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -103,6 +103,7 @@ enum { * @gpps: Pad groups if the controller has variable size pad groups * @ngpps: Number of pad groups in this community * @pad_map: Optional non-linear mapping of the pads + * @nirqs: Optional total number of IRQs this community can generate * @regs: Community specific common registers (reserved for core driver) * @pad_regs: Community specific pad registers (reserved for core driver) * @@ -127,6 +128,7 @@ struct intel_community { const struct intel_padgroup *gpps; size_t ngpps; const unsigned int *pad_map; + unsigned short nirqs; /* Reserved for the core driver */ void __iomem *regs; From c8f8f65ea8ebc50aba7ab9741b3d0343ddf63d7f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:48 +0300 Subject: [PATCH 05/24] pinctrl: intel: Allow drivers to define ACPI address space ID Individual drivers may install ACPI OpRegion handlers based on address space ID which differs from community to community. Add special field in the struct intel_community for that purpose. Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index 0f01ef3fdfdd..4e17308d33e9 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -104,6 +104,7 @@ enum { * @ngpps: Number of pad groups in this community * @pad_map: Optional non-linear mapping of the pads * @nirqs: Optional total number of IRQs this community can generate + * @acpi_space_id: Optional address space ID for ACPI OpRegion handler * @regs: Community specific common registers (reserved for core driver) * @pad_regs: Community specific pad registers (reserved for core driver) * @@ -129,6 +130,7 @@ struct intel_community { size_t ngpps; const unsigned int *pad_map; unsigned short nirqs; + unsigned short acpi_space_id; /* Reserved for the core driver */ void __iomem *regs; From 293428f93260d45f712a2d9f895bc0def0b34a3d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:49 +0300 Subject: [PATCH 06/24] pinctrl: cherryview: Re-use data structures from pinctrl-intel.h (part 3) We have some data structures duplicated across the drivers. Let's deduplicate them by using struct intel_pinctrl_soc_data, struct intel_community and struct intel_pinctrl_context that are being provided by pinctrl-intel.h. Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-cherryview.c | 268 +++++++++++---------- 1 file changed, 138 insertions(+), 130 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 1fc46dfb880e..9ef246145bde 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -2,7 +2,7 @@ /* * Cherryview/Braswell pinctrl driver * - * Copyright (C) 2014, Intel Corporation + * Copyright (C) 2014, 2020 Intel Corporation * Author: Mika Westerberg * * This driver is based on the original Cherryview GPIO driver by @@ -67,35 +67,7 @@ #define CHV_PADCTRL1_INTWAKECFG_BOTH 3 #define CHV_PADCTRL1_INTWAKECFG_LEVEL 4 -/** - * struct chv_community - A community specific configuration - * @uid: ACPI _UID used to match the community - * @pins: All pins in this community - * @npins: Number of pins - * @groups: All groups in this community - * @ngroups: Number of groups - * @functions: All functions in this community - * @nfunctions: Number of functions - * @gpps: Pad groups - * @ngpps: Number of pad groups in this community - * @nirqs: Total number of IRQs this community can generate - * @acpi_space_id: An address space ID for ACPI OpRegion handler - */ -struct chv_community { - const char *uid; - const struct pinctrl_pin_desc *pins; - size_t npins; - const struct intel_pingroup *groups; - size_t ngroups; - const struct intel_function *functions; - size_t nfunctions; - const struct intel_padgroup *gpps; - size_t ngpps; - size_t nirqs; - acpi_adr_space_type acpi_space_id; -}; - -struct chv_pin_context { +struct intel_pad_context { u32 padctrl0; u32 padctrl1; }; @@ -107,13 +79,13 @@ struct chv_pin_context { * @pctldev: Pointer to the pin controller device * @chip: GPIO chip in this pin controller * @irqchip: IRQ chip in this pin controller - * @regs: MMIO registers + * @soc: Community specific pin configuration data + * @communities: All communities in this pin controller + * @ncommunities: Number of communities in this pin controller + * @context: Configuration saved over system sleep * @irq: Our parent irq - * @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO - * offset (in GPIO number space) - * @community: Community this pinctrl instance represents + * @intr_lines: Mapping between 16 HW interrupt wires and GPIO offset (in GPIO number space) * @saved_intmask: Interrupt mask saved for system sleep - * @saved_pin_context: Pointer to a context of the pins saved for system sleep * * The first group in @groups is expected to contain all pins that can be * used as GPIOs. @@ -124,24 +96,34 @@ struct chv_pinctrl { struct pinctrl_dev *pctldev; struct gpio_chip chip; struct irq_chip irqchip; - void __iomem *regs; - unsigned int irq; + const struct intel_pinctrl_soc_data *soc; + struct intel_community *communities; + size_t ncommunities; + struct intel_pinctrl_context context; + int irq; + unsigned int intr_lines[16]; - const struct chv_community *community; u32 saved_intmask; - struct chv_pin_context *saved_pin_context; }; #define PINMODE_INVERT_OE BIT(15) #define PINMODE(m, i) ((m) | ((i) * PINMODE_INVERT_OE)) -#define CHV_GPP(start, end) \ +#define CHV_GPP(start, end) \ { \ .base = (start), \ .size = (end) - (start) + 1, \ } +#define CHV_COMMUNITY(g, i, a) \ + { \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + .nirqs = (i), \ + .acpi_space_id = (a), \ + } + static const struct pinctrl_pin_desc southwest_pins[] = { PINCTRL_PIN(0, "FST_SPI_D2"), PINCTRL_PIN(1, "FST_SPI_D0"), @@ -303,7 +285,15 @@ static const struct intel_padgroup southwest_gpps[] = { CHV_GPP(90, 97), }; -static const struct chv_community southwest_community = { +/* + * Southwest community can generate GPIO interrupts only for the first 8 + * interrupts. The upper half (8-15) can only be used to trigger GPEs. + */ +static const struct intel_community southwest_communities[] = { + CHV_COMMUNITY(southwest_gpps, 8, 0x91), +}; + +static const struct intel_pinctrl_soc_data southwest_soc_data = { .uid = "1", .pins = southwest_pins, .npins = ARRAY_SIZE(southwest_pins), @@ -311,15 +301,8 @@ static const struct chv_community southwest_community = { .ngroups = ARRAY_SIZE(southwest_groups), .functions = southwest_functions, .nfunctions = ARRAY_SIZE(southwest_functions), - .gpps = southwest_gpps, - .ngpps = ARRAY_SIZE(southwest_gpps), - /* - * Southwest community can generate GPIO interrupts only for the - * first 8 interrupts. The upper half (8-15) can only be used to - * trigger GPEs. - */ - .nirqs = 8, - .acpi_space_id = 0x91, + .communities = southwest_communities, + .ncommunities = ARRAY_SIZE(southwest_communities), }; static const struct pinctrl_pin_desc north_pins[] = { @@ -396,19 +379,20 @@ static const struct intel_padgroup north_gpps[] = { CHV_GPP(60, 72), }; -static const struct chv_community north_community = { +/* + * North community can generate GPIO interrupts only for the first 8 + * interrupts. The upper half (8-15) can only be used to trigger GPEs. + */ +static const struct intel_community north_communities[] = { + CHV_COMMUNITY(north_gpps, 8, 0x92), +}; + +static const struct intel_pinctrl_soc_data north_soc_data = { .uid = "2", .pins = north_pins, .npins = ARRAY_SIZE(north_pins), - .gpps = north_gpps, - .ngpps = ARRAY_SIZE(north_gpps), - /* - * North community can generate GPIO interrupts only for the first - * 8 interrupts. The upper half (8-15) can only be used to trigger - * GPEs. - */ - .nirqs = 8, - .acpi_space_id = 0x92, + .communities = north_communities, + .ncommunities = ARRAY_SIZE(north_communities), }; static const struct pinctrl_pin_desc east_pins[] = { @@ -444,14 +428,16 @@ static const struct intel_padgroup east_gpps[] = { CHV_GPP(15, 26), }; -static const struct chv_community east_community = { +static const struct intel_community east_communities[] = { + CHV_COMMUNITY(east_gpps, 16, 0x93), +}; + +static const struct intel_pinctrl_soc_data east_soc_data = { .uid = "3", .pins = east_pins, .npins = ARRAY_SIZE(east_pins), - .gpps = east_gpps, - .ngpps = ARRAY_SIZE(east_gpps), - .nirqs = 16, - .acpi_space_id = 0x93, + .communities = east_communities, + .ncommunities = ARRAY_SIZE(east_communities), }; static const struct pinctrl_pin_desc southeast_pins[] = { @@ -566,7 +552,11 @@ static const struct intel_padgroup southeast_gpps[] = { CHV_GPP(75, 85), }; -static const struct chv_community southeast_community = { +static const struct intel_community southeast_communities[] = { + CHV_COMMUNITY(southeast_gpps, 16, 0x94), +}; + +static const struct intel_pinctrl_soc_data southeast_soc_data = { .uid = "4", .pins = southeast_pins, .npins = ARRAY_SIZE(southeast_pins), @@ -574,17 +564,16 @@ static const struct chv_community southeast_community = { .ngroups = ARRAY_SIZE(southeast_groups), .functions = southeast_functions, .nfunctions = ARRAY_SIZE(southeast_functions), - .gpps = southeast_gpps, - .ngpps = ARRAY_SIZE(southeast_gpps), - .nirqs = 16, - .acpi_space_id = 0x94, + .communities = southeast_communities, + .ncommunities = ARRAY_SIZE(southeast_communities), }; -static const struct chv_community *chv_communities[] = { - &southwest_community, - &north_community, - &east_community, - &southeast_community, +static const struct intel_pinctrl_soc_data *chv_soc_data[] = { + &southwest_soc_data, + &north_soc_data, + &east_soc_data, + &southeast_soc_data, + NULL }; /* @@ -600,12 +589,15 @@ static DEFINE_RAW_SPINLOCK(chv_lock); static u32 chv_pctrl_readl(struct chv_pinctrl *pctrl, unsigned int offset) { - return readl(pctrl->regs + offset); + const struct intel_community *community = &pctrl->communities[0]; + + return readl(community->regs + offset); } static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32 value) { - void __iomem *reg = pctrl->regs + offset; + const struct intel_community *community = &pctrl->communities[0]; + void __iomem *reg = community->regs + offset; /* Write and simple read back to confirm the bus transferring done */ writel(value, reg); @@ -615,13 +607,13 @@ static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32 static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset, unsigned int reg) { + const struct intel_community *community = &pctrl->communities[0]; unsigned int family_no = offset / MAX_FAMILY_PAD_GPIO_NO; unsigned int pad_no = offset % MAX_FAMILY_PAD_GPIO_NO; - offset = FAMILY_PAD_REGS_OFF + FAMILY_PAD_REGS_SIZE * family_no + - GPIO_REGS_SIZE * pad_no; + offset = FAMILY_PAD_REGS_SIZE * family_no + GPIO_REGS_SIZE * pad_no; - return pctrl->regs + offset + reg; + return community->pad_regs + offset + reg; } static u32 chv_readl(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int offset) @@ -648,7 +640,7 @@ static int chv_get_groups_count(struct pinctrl_dev *pctldev) { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - return pctrl->community->ngroups; + return pctrl->soc->ngroups; } static const char *chv_get_group_name(struct pinctrl_dev *pctldev, @@ -656,7 +648,7 @@ static const char *chv_get_group_name(struct pinctrl_dev *pctldev, { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - return pctrl->community->groups[group].name; + return pctrl->soc->groups[group].name; } static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, @@ -664,8 +656,8 @@ static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - *pins = pctrl->community->groups[group].pins; - *npins = pctrl->community->groups[group].npins; + *pins = pctrl->soc->groups[group].pins; + *npins = pctrl->soc->groups[group].npins; return 0; } @@ -713,7 +705,7 @@ static int chv_get_functions_count(struct pinctrl_dev *pctldev) { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - return pctrl->community->nfunctions; + return pctrl->soc->nfunctions; } static const char *chv_get_function_name(struct pinctrl_dev *pctldev, @@ -721,7 +713,7 @@ static const char *chv_get_function_name(struct pinctrl_dev *pctldev, { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - return pctrl->community->functions[function].name; + return pctrl->soc->functions[function].name; } static int chv_get_function_groups(struct pinctrl_dev *pctldev, @@ -731,8 +723,8 @@ static int chv_get_function_groups(struct pinctrl_dev *pctldev, { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - *groups = pctrl->community->functions[function].groups; - *ngroups = pctrl->community->functions[function].ngroups; + *groups = pctrl->soc->functions[function].groups; + *ngroups = pctrl->soc->functions[function].ngroups; return 0; } @@ -744,7 +736,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned long flags; int i; - grp = &pctrl->community->groups[group]; + grp = &pctrl->soc->groups[group]; raw_spin_lock_irqsave(&chv_lock, flags); @@ -1412,6 +1404,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) { struct gpio_chip *gc = irq_desc_get_handler_data(desc); struct chv_pinctrl *pctrl = gpiochip_get_data(gc); + const struct intel_community *community = &pctrl->communities[0]; struct irq_chip *chip = irq_desc_get_chip(desc); unsigned long pending; unsigned long flags; @@ -1423,7 +1416,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) pending = chv_pctrl_readl(pctrl, CHV_INTSTAT); raw_spin_unlock_irqrestore(&chv_lock, flags); - for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) { + for_each_set_bit(intr_line, &pending, community->nirqs) { unsigned int irq, offset; offset = pctrl->intr_lines[intr_line]; @@ -1480,15 +1473,15 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip, unsigned int ngpios) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); - const struct chv_community *community = pctrl->community; + const struct intel_community *community = &pctrl->communities[0]; int i; /* Do not add GPIOs that can only generate GPEs to the IRQ domain */ - for (i = 0; i < community->npins; i++) { + for (i = 0; i < pctrl->soc->npins; i++) { const struct pinctrl_pin_desc *desc; u32 intsel; - desc = &community->pins[i]; + desc = &pctrl->soc->pins[i]; intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0); intsel &= CHV_PADCTRL0_INTSEL_MASK; @@ -1502,6 +1495,7 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip, static int chv_gpio_irq_init_hw(struct gpio_chip *chip) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); + const struct intel_community *community = &pctrl->communities[0]; /* * The same set of machines in chv_no_valid_mask[] have incorrectly @@ -1515,7 +1509,7 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip) * Mask all interrupts the community is able to generate * but leave the ones that can only generate GPEs unmasked. */ - chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, pctrl->community->nirqs)); + chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, community->nirqs)); } /* Clear all interrupts */ @@ -1527,7 +1521,7 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip) static int chv_gpio_add_pin_ranges(struct gpio_chip *chip) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); - const struct chv_community *community = pctrl->community; + const struct intel_community *community = &pctrl->communities[0]; const struct intel_padgroup *gpp; int ret, i; @@ -1547,15 +1541,15 @@ static int chv_gpio_add_pin_ranges(struct gpio_chip *chip) static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) { + const struct intel_community *community = &pctrl->communities[0]; const struct intel_padgroup *gpp; struct gpio_chip *chip = &pctrl->chip; bool need_valid_mask = !dmi_check_system(chv_no_valid_mask); - const struct chv_community *community = pctrl->community; int ret, i, irq_base; *chip = chv_gpio_chip; - chip->ngpio = community->pins[community->npins - 1].number + 1; + chip->ngpio = pctrl->soc->pins[pctrl->soc->npins - 1].number + 1; chip->label = dev_name(pctrl->dev); chip->add_pin_ranges = chv_gpio_add_pin_ranges; chip->parent = pctrl->dev; @@ -1581,7 +1575,7 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) chip->irq.init_valid_mask = chv_init_irq_valid_mask; } else { irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, - community->npins, NUMA_NO_NODE); + pctrl->soc->npins, NUMA_NO_NODE); if (irq_base < 0) { dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); return irq_base; @@ -1631,6 +1625,10 @@ static acpi_status chv_pinctrl_mmio_access_handler(u32 function, static int chv_pinctrl_probe(struct platform_device *pdev) { + const struct intel_pinctrl_soc_data *soc_data = NULL; + const struct intel_pinctrl_soc_data **soc_table; + struct intel_community *community; + struct device *dev = &pdev->dev; struct chv_pinctrl *pctrl; struct acpi_device *adev; acpi_status status; @@ -1640,40 +1638,53 @@ static int chv_pinctrl_probe(struct platform_device *pdev) if (!adev) return -ENODEV; - pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); + soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(dev); + for (i = 0; soc_table[i]; i++) { + if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) { + soc_data = soc_table[i]; + break; + } + } + if (!soc_data) + return -ENODEV; + + pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); if (!pctrl) return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(chv_communities); i++) - if (!strcmp(adev->pnp.unique_id, chv_communities[i]->uid)) { - pctrl->community = chv_communities[i]; - break; - } - if (i == ARRAY_SIZE(chv_communities)) - return -ENODEV; - pctrl->dev = &pdev->dev; + pctrl->soc = soc_data; + + pctrl->ncommunities = pctrl->soc->ncommunities; + pctrl->communities = devm_kmemdup(dev, pctrl->soc->communities, + pctrl->ncommunities * sizeof(*pctrl->communities), + GFP_KERNEL); + if (!pctrl->communities) + return -ENOMEM; + + community = &pctrl->communities[0]; + community->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(community->regs)) + return PTR_ERR(community->regs); + + community->pad_regs = community->regs + FAMILY_PAD_REGS_OFF; #ifdef CONFIG_PM_SLEEP - pctrl->saved_pin_context = devm_kcalloc(pctrl->dev, - pctrl->community->npins, sizeof(*pctrl->saved_pin_context), - GFP_KERNEL); - if (!pctrl->saved_pin_context) + pctrl->context.pads = devm_kcalloc(dev, pctrl->soc->npins, + sizeof(*pctrl->context.pads), + GFP_KERNEL); + if (!pctrl->context.pads) return -ENOMEM; #endif - pctrl->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(pctrl->regs)) - return PTR_ERR(pctrl->regs); - irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; pctrl->pctldesc = chv_pinctrl_desc; pctrl->pctldesc.name = dev_name(&pdev->dev); - pctrl->pctldesc.pins = pctrl->community->pins; - pctrl->pctldesc.npins = pctrl->community->npins; + pctrl->pctldesc.pins = pctrl->soc->pins; + pctrl->pctldesc.npins = pctrl->soc->npins; pctrl->pctldev = devm_pinctrl_register(&pdev->dev, &pctrl->pctldesc, pctrl); @@ -1687,7 +1698,7 @@ static int chv_pinctrl_probe(struct platform_device *pdev) return ret; status = acpi_install_address_space_handler(adev->handle, - pctrl->community->acpi_space_id, + community->acpi_space_id, chv_pinctrl_mmio_access_handler, NULL, pctrl); if (ACPI_FAILURE(status)) @@ -1701,9 +1712,10 @@ static int chv_pinctrl_probe(struct platform_device *pdev) static int chv_pinctrl_remove(struct platform_device *pdev) { struct chv_pinctrl *pctrl = platform_get_drvdata(pdev); + const struct intel_community *community = &pctrl->communities[0]; acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev), - pctrl->community->acpi_space_id, + community->acpi_space_id, chv_pinctrl_mmio_access_handler); return 0; @@ -1720,16 +1732,14 @@ static int chv_pinctrl_suspend_noirq(struct device *dev) pctrl->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); - for (i = 0; i < pctrl->community->npins; i++) { + for (i = 0; i < pctrl->soc->npins; i++) { const struct pinctrl_pin_desc *desc; - struct chv_pin_context *ctx; + struct intel_pad_context *ctx = &pctrl->context.pads[i]; - desc = &pctrl->community->pins[i]; + desc = &pctrl->soc->pins[i]; if (chv_pad_locked(pctrl, desc->number)) continue; - ctx = &pctrl->saved_pin_context[i]; - ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0); ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE; @@ -1756,17 +1766,15 @@ static int chv_pinctrl_resume_noirq(struct device *dev) */ chv_pctrl_writel(pctrl, CHV_INTMASK, 0x0000); - for (i = 0; i < pctrl->community->npins; i++) { + for (i = 0; i < pctrl->soc->npins; i++) { const struct pinctrl_pin_desc *desc; - const struct chv_pin_context *ctx; + struct intel_pad_context *ctx = &pctrl->context.pads[i]; u32 val; - desc = &pctrl->community->pins[i]; + desc = &pctrl->soc->pins[i]; if (chv_pad_locked(pctrl, desc->number)) continue; - ctx = &pctrl->saved_pin_context[i]; - /* Only restore if our saved state differs from the current */ val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); val &= ~CHV_PADCTRL0_GPIORXSTATE; @@ -1803,7 +1811,7 @@ static const struct dev_pm_ops chv_pinctrl_pm_ops = { }; static const struct acpi_device_id chv_pinctrl_acpi_match[] = { - { "INT33FF" }, + { "INT33FF", (kernel_ulong_t)chv_soc_data }, { } }; MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match); From af7e3eeb84e27fcfd1f46a80f111c8c72c206776 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:54 +0300 Subject: [PATCH 07/24] pinctrl: intel: Disable input and output buffer when switching to GPIO It's possible scenario that pin has been in different mode, while the respective GPIO register has a leftover output buffer enabled. In such case when we request GPIO it will switch to GPIO mode, and thus to output with unknown value, followed by switching to input mode. This can produce a glitch on the pin. Disable input and output buffer when switching to GPIO to avoid potential glitches. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 6a274e20d926..9df5a0c0d416 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -435,11 +435,20 @@ static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) { u32 value; + value = readl(padcfg0); + /* Put the pad into GPIO mode */ - value = readl(padcfg0) & ~PADCFG0_PMODE_MASK; + value &= ~PADCFG0_PMODE_MASK; + value |= PADCFG0_PMODE_GPIO; + + /* Disable input and output buffers */ + value &= ~PADCFG0_GPIORXDIS; + value &= ~PADCFG0_GPIOTXDIS; + /* Disable SCI/SMI/NMI generation */ value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI); + writel(value, padcfg0); } @@ -1036,6 +1045,9 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned int type) intel_gpio_set_gpio_mode(reg); + /* Disable TX buffer and enable RX (this will be input) */ + __intel_gpio_set_direction(reg, true); + value = readl(reg); value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV); From f62cdde5483957fc28249a9fc691e892e6b38e85 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:55 +0300 Subject: [PATCH 08/24] pinctrl: intel: Reduce scope of the lock In some cases lock covers unneeded calls and operations. Reduce scope of the lock in such cases. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 9df5a0c0d416..d0b658ba2136 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -460,6 +460,8 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, void __iomem *padcfg0; unsigned long flags; + padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); + raw_spin_lock_irqsave(&pctrl->lock, flags); if (!intel_pad_owned_by_host(pctrl, pin)) { @@ -472,8 +474,6 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, return 0; } - padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); - /* * If pin is already configured in GPIO mode, we assume that * firmware provides correct settings. In such case we avoid @@ -503,11 +503,10 @@ static int intel_gpio_set_direction(struct pinctrl_dev *pctldev, void __iomem *padcfg0; unsigned long flags; - raw_spin_lock_irqsave(&pctrl->lock, flags); - padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); - __intel_gpio_set_direction(padcfg0, input); + raw_spin_lock_irqsave(&pctrl->lock, flags); + __intel_gpio_set_direction(padcfg0, input); raw_spin_unlock_irqrestore(&pctrl->lock, flags); return 0; @@ -622,10 +621,11 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, int ret = 0; u32 value; - raw_spin_lock_irqsave(&pctrl->lock, flags); - community = intel_get_community(pctrl, pin); padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); + + raw_spin_lock_irqsave(&pctrl->lock, flags); + value = readl(padcfg1); switch (param) { From 86851bbce1a332b0658519386041fe430f4e9e39 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:56 +0300 Subject: [PATCH 09/24] pinctrl: intel: Make use of IRQ_RETVAL() Instead of using bitwise operations against returned values, which is a bit fragile, convert IRQ handler to count amount of GPIO groups, where at least one interrupt happened, and convert it to returned value by IRQ_RETVAL() macro. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index d0b658ba2136..e05273a00ff2 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -1093,12 +1093,12 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on) return 0; } -static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, - const struct intel_community *community) +static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, + const struct intel_community *community) { struct gpio_chip *gc = &pctrl->chip; - irqreturn_t ret = IRQ_NONE; - int gpp; + unsigned int gpp; + int ret = 0; for (gpp = 0; gpp < community->ngpps; gpp++) { const struct intel_padgroup *padgrp = &community->gpps[gpp]; @@ -1118,9 +1118,9 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, irq = irq_find_mapping(gc->irq.domain, padgrp->gpio_base + gpp_offset); generic_handle_irq(irq); - - ret |= IRQ_HANDLED; } + + ret += pending ? 1 : 0; } return ret; @@ -1130,16 +1130,16 @@ static irqreturn_t intel_gpio_irq(int irq, void *data) { const struct intel_community *community; struct intel_pinctrl *pctrl = data; - irqreturn_t ret = IRQ_NONE; - int i; + unsigned int i; + int ret = 0; /* Need to check all communities for pending interrupts */ for (i = 0; i < pctrl->ncommunities; i++) { community = &pctrl->communities[i]; - ret |= intel_gpio_community_irq_handler(pctrl, community); + ret += intel_gpio_community_irq_handler(pctrl, community); } - return ret; + return IRQ_RETVAL(ret); } static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl, From bb2f43d49b72c8497dba53a44fc41bea03d4ab9e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:57 +0300 Subject: [PATCH 10/24] pinctrl: intel: Get rid of redundant 'else' in intel_config_set_debounce() In a code like if (...) { ... goto label; } else { ... } the 'else' keyword is redundant. Get rid of it for better readability. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index e05273a00ff2..76b1b899a389 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -719,12 +719,12 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl, if (v < 3 || v > 15) { ret = -EINVAL; goto exit_unlock; - } else { - /* Enable glitch filter and debouncer */ - value0 |= PADCFG0_PREGFRXSEL; - value2 |= v << PADCFG2_DEBOUNCE_SHIFT; - value2 |= PADCFG2_DEBEN; } + + /* Enable glitch filter and debouncer */ + value0 |= PADCFG0_PREGFRXSEL; + value2 |= v << PADCFG2_DEBOUNCE_SHIFT; + value2 |= PADCFG2_DEBEN; } writel(value0, padcfg0); From 8fff0427d1b2b47469496dbcf3f846dab0cccc7b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:58 +0300 Subject: [PATCH 11/24] pinctrl: intel: Drop the only label in the code for consistency Drop the only label in the code, i.e. in intel_config_set_debounce(), for consistency with the rest. In entire driver we use multipoint return. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 76b1b899a389..2bcda48ea29a 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -695,7 +695,6 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl, void __iomem *padcfg0, *padcfg2; unsigned long flags; u32 value0, value2; - int ret = 0; padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); if (!padcfg2) @@ -717,8 +716,8 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl, v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC); if (v < 3 || v > 15) { - ret = -EINVAL; - goto exit_unlock; + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + return -EINVAL; } /* Enable glitch filter and debouncer */ @@ -730,10 +729,9 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl, writel(value0, padcfg0); writel(value2, padcfg2); -exit_unlock: raw_spin_unlock_irqrestore(&pctrl->lock, flags); - return ret; + return 0; } static int intel_config_set(struct pinctrl_dev *pctldev, unsigned int pin, From 81ab5542d7978f41a2b41c0f325b45980a478c6f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:59 +0300 Subject: [PATCH 12/24] pinctrl: intel: Split intel_config_get() to three functions Split intel_config_get() to three functions, i.e. intel_config_get() and two helpers intel_config_get_pull() and intel_config_get_debounce() to be symmetrical with intel_config_set*(). Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 97 ++++++++++++++++++--------- 1 file changed, 65 insertions(+), 32 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 2bcda48ea29a..d6ef012f2cc4 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -521,20 +521,17 @@ static const struct pinmux_ops intel_pinmux_ops = { .gpio_set_direction = intel_gpio_set_direction, }; -static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long *config) +static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin, + enum pin_config_param param, u32 *arg) { - struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - enum pin_config_param param = pinconf_to_config_param(*config); const struct intel_community *community; + void __iomem *padcfg1; u32 value, term; - u32 arg = 0; - - if (!intel_pad_owned_by_host(pctrl, pin)) - return -ENOTSUPP; community = intel_get_community(pctrl, pin); - value = readl(intel_get_padcfg(pctrl, pin, PADCFG1)); + padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); + value = readl(padcfg1); + term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT; switch (param) { @@ -549,16 +546,16 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, switch (term) { case PADCFG1_TERM_1K: - arg = 1000; + *arg = 1000; break; case PADCFG1_TERM_2K: - arg = 2000; + *arg = 2000; break; case PADCFG1_TERM_5K: - arg = 5000; + *arg = 5000; break; case PADCFG1_TERM_20K: - arg = 20000; + *arg = 20000; break; } @@ -572,36 +569,72 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, case PADCFG1_TERM_1K: if (!(community->features & PINCTRL_FEATURE_1K_PD)) return -EINVAL; - arg = 1000; + *arg = 1000; break; case PADCFG1_TERM_5K: - arg = 5000; + *arg = 5000; break; case PADCFG1_TERM_20K: - arg = 20000; + *arg = 20000; break; } break; - case PIN_CONFIG_INPUT_DEBOUNCE: { - void __iomem *padcfg2; - u32 v; - - padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); - if (!padcfg2) - return -ENOTSUPP; - - v = readl(padcfg2); - if (!(v & PADCFG2_DEBEN)) - return -EINVAL; - - v = (v & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT; - arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC; - - break; + default: + return -EINVAL; } + return 0; +} + +static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int pin, + enum pin_config_param param, u32 *arg) +{ + void __iomem *padcfg2; + unsigned long v; + u32 value2; + + padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); + if (!padcfg2) + return -ENOTSUPP; + + value2 = readl(padcfg2); + if (!(value2 & PADCFG2_DEBEN)) + return -EINVAL; + + v = (value2 & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT; + *arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC; + + return 0; +} + +static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + u32 arg = 0; + int ret; + + if (!intel_pad_owned_by_host(pctrl, pin)) + return -ENOTSUPP; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + ret = intel_config_get_pull(pctrl, pin, param, &arg); + if (ret) + return ret; + break; + + case PIN_CONFIG_INPUT_DEBOUNCE: + ret = intel_config_get_debounce(pctrl, pin, param, &arg); + if (ret) + return ret; + break; + default: return -ENOTSUPP; } From e64fbfa51e8fc4eeca2d2bbf0d31a30a15734229 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:50:00 +0300 Subject: [PATCH 13/24] pinctrl: intel: Protect IO in few call backs by lock Protect IO in intel_gpio_get_direction(), intel_gpio_community_irq_handler(), intel_config_get_debounce() and intel_config_get_pull() by lock. Even for simple readl() we better serialize IO to avoid potential problems. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index d6ef012f2cc4..35c88fcb75a2 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -526,11 +526,15 @@ static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin, { const struct intel_community *community; void __iomem *padcfg1; + unsigned long flags; u32 value, term; community = intel_get_community(pctrl, pin); padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); + + raw_spin_lock_irqsave(&pctrl->lock, flags); value = readl(padcfg1); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT; @@ -592,6 +596,7 @@ static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int p enum pin_config_param param, u32 *arg) { void __iomem *padcfg2; + unsigned long flags; unsigned long v; u32 value2; @@ -599,7 +604,9 @@ static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int p if (!padcfg2) return -ENOTSUPP; + raw_spin_lock_irqsave(&pctrl->lock, flags); value2 = readl(padcfg2); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); if (!(value2 & PADCFG2_DEBEN)) return -EINVAL; @@ -934,6 +941,7 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned int offset, static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + unsigned long flags; void __iomem *reg; u32 padcfg0; int pin; @@ -946,8 +954,9 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) if (!reg) return -EINVAL; + raw_spin_lock_irqsave(&pctrl->lock, flags); padcfg0 = readl(reg); - + raw_spin_unlock_irqrestore(&pctrl->lock, flags); if (padcfg0 & PADCFG0_PMODE_MASK) return -EINVAL; @@ -1134,12 +1143,17 @@ static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, for (gpp = 0; gpp < community->ngpps; gpp++) { const struct intel_padgroup *padgrp = &community->gpps[gpp]; unsigned long pending, enabled, gpp_offset; + unsigned long flags; + + raw_spin_lock_irqsave(&pctrl->lock, flags); pending = readl(community->regs + community->is_offset + padgrp->reg_num * 4); enabled = readl(community->regs + community->ie_offset + padgrp->reg_num * 4); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + /* Only interrupts that are enabled */ pending &= enabled; From d1bfd0229ec4deb53e61f95c050b524152fd0d9e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 10 Jun 2020 21:14:49 +0300 Subject: [PATCH 14/24] pinctrl: intel: Make use of for_each_requested_gpio_in_range() Make use of for_each_requested_gpio_in_range() instead of home grown analogue. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 35c88fcb75a2..b64997b303e0 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -1628,19 +1628,6 @@ static void intel_gpio_irq_init(struct intel_pinctrl *pctrl) } } -static u32 -intel_gpio_is_requested(struct gpio_chip *chip, int base, unsigned int size) -{ - u32 requested = 0; - unsigned int i; - - for (i = 0; i < size; i++) - if (gpiochip_is_requested(chip, base + i)) - requested |= BIT(i); - - return requested; -} - static bool intel_gpio_update_reg(void __iomem *reg, u32 mask, u32 value) { u32 curr, updated; @@ -1661,12 +1648,16 @@ static void intel_restore_hostown(struct intel_pinctrl *pctrl, unsigned int c, const struct intel_community *community = &pctrl->communities[c]; const struct intel_padgroup *padgrp = &community->gpps[gpp]; struct device *dev = pctrl->dev; - u32 requested; + const char *dummy; + u32 requested = 0; + unsigned int i; if (padgrp->gpio_base == INTEL_GPIO_BASE_NOMAP) return; - requested = intel_gpio_is_requested(&pctrl->chip, padgrp->gpio_base, padgrp->size); + for_each_requested_gpio_in_range(&pctrl->chip, i, padgrp->gpio_base, padgrp->size, dummy) + requested |= BIT(i); + if (!intel_gpio_update_reg(base + gpp * 4, requested, saved)) return; From f3e7d2812247342c415c76ba75fd79df57ee2a74 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 10 Jun 2020 21:14:49 +0300 Subject: [PATCH 15/24] pinctrl: lynxpoint: Make use of for_each_requested_gpio() Make use of for_each_requested_gpio() instead of home grown analogue. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index a45b8f2182fd..2a3af998b91c 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -919,16 +919,17 @@ static int lp_gpio_runtime_resume(struct device *dev) static int lp_gpio_resume(struct device *dev) { struct intel_pinctrl *lg = dev_get_drvdata(dev); + struct gpio_chip *chip = &lg->chip; + const char *dummy; void __iomem *reg; int i; /* on some hardware suspend clears input sensing, re-enable it here */ - for (i = 0; i < lg->chip.ngpio; i++) { - if (gpiochip_is_requested(&lg->chip, i) != NULL) { - reg = lp_gpio_reg(&lg->chip, i, LP_CONFIG2); - iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); - } + for_each_requested_gpio(chip, i, dummy) { + reg = lp_gpio_reg(chip, i, LP_CONFIG2); + iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); } + return 0; } From 0472567ba86469eb9faabc917f4c3084c08cf0c2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 15 Jun 2020 17:30:15 +0300 Subject: [PATCH 16/24] pinctrl: lynxpoint: Introduce helpers to enable or disable input Introduce couple of helpers to enable or disable input. i.e. lp_gpio_enable_input() and lp_gpio_disable_input(). Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 2a3af998b91c..003d795528e8 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -386,6 +386,16 @@ static int lp_pinmux_set_mux(struct pinctrl_dev *pctldev, return 0; } +static void lp_gpio_enable_input(void __iomem *reg) +{ + iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); +} + +static void lp_gpio_disable_input(void __iomem *reg) +{ + iowrite32(ioread32(reg) | GPINDIS_BIT, reg); +} + static int lp_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int pin) @@ -411,7 +421,7 @@ static int lp_gpio_request_enable(struct pinctrl_dev *pctldev, } /* Enable input sensing */ - iowrite32(ioread32(conf2) & ~GPINDIS_BIT, conf2); + lp_gpio_enable_input(conf2); raw_spin_unlock_irqrestore(&lg->lock, flags); @@ -429,7 +439,7 @@ static void lp_gpio_disable_free(struct pinctrl_dev *pctldev, raw_spin_lock_irqsave(&lg->lock, flags); /* Disable input sensing */ - iowrite32(ioread32(conf2) | GPINDIS_BIT, conf2); + lp_gpio_disable_input(conf2); raw_spin_unlock_irqrestore(&lg->lock, flags); @@ -921,14 +931,11 @@ static int lp_gpio_resume(struct device *dev) struct intel_pinctrl *lg = dev_get_drvdata(dev); struct gpio_chip *chip = &lg->chip; const char *dummy; - void __iomem *reg; int i; /* on some hardware suspend clears input sensing, re-enable it here */ - for_each_requested_gpio(chip, i, dummy) { - reg = lp_gpio_reg(chip, i, LP_CONFIG2); - iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); - } + for_each_requested_gpio(chip, i, dummy) + lp_gpio_enable_input(lp_gpio_reg(chip, i, LP_CONFIG2)); return 0; } From e359a6f03ba3b35bc573c3993173a273041e4bc1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:50:05 +0300 Subject: [PATCH 17/24] pinctrl: lynxpoint: Drop no-op ACPI_PTR() call Since we dependent on ACPI, there is no need to use ACPI_PTR() which is a no-op in this case. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 003d795528e8..96589d01fe35 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -959,7 +959,7 @@ static struct platform_driver lp_gpio_driver = { .driver = { .name = "lp_gpio", .pm = &lp_gpio_pm_ops, - .acpi_match_table = ACPI_PTR(lynxpoint_gpio_acpi_match), + .acpi_match_table = lynxpoint_gpio_acpi_match, }, }; From e87daf0bd83cb82576940d0a6e0e48b01d18c939 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:50:06 +0300 Subject: [PATCH 18/24] pinctrl: baytrail: Drop no-op ACPI_PTR() call Since we dependent on ACPI, there is no need to use ACPI_PTR() which is a no-op in this case. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-baytrail.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 0ff7c55173da..e3ceb3dfeabe 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1757,9 +1757,8 @@ static struct platform_driver byt_gpio_driver = { .driver = { .name = "byt_gpio", .pm = &byt_gpio_pm_ops, + .acpi_match_table = byt_gpio_acpi_match, .suppress_bind_attrs = true, - - .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match), }, }; From 156abe2961601d60a8c2a60c6dc8dd6ce7adcdaf Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 6 Jun 2020 11:31:50 +0200 Subject: [PATCH 19/24] pinctrl: baytrail: Fix pin being driven low for a while on gpiod_get(..., GPIOD_OUT_HIGH) The pins on the Bay Trail SoC have separate input-buffer and output-buffer enable bits and a read of the level bit of the value register will always return the value from the input-buffer. The BIOS of a device may configure a pin in output-only mode, only enabling the output buffer, and write 1 to the level bit to drive the pin high. This 1 written to the level bit will be stored inside the data-latch of the output buffer. But a subsequent read of the value register will return 0 for the level bit because the input-buffer is disabled. This causes a read-modify-write as done by byt_gpio_set_direction() to write 0 to the level bit, driving the pin low! Before this commit byt_gpio_direction_output() relied on pinctrl_gpio_direction_output() to set the direction, followed by a call to byt_gpio_set() to apply the selected value. This causes the pin to go low between the pinctrl_gpio_direction_output() and byt_gpio_set() calls. Change byt_gpio_direction_output() to directly make the register modifications itself instead. Replacing the 2 subsequent writes to the value register with a single write. Note that the pinctrl code does not keep track internally of the direction, so not going through pinctrl_gpio_direction_output() is not an issue. This issue was noticed on a Trekstor SurfTab Twin 10.1. When the panel is already on at boot (no external monitor connected), then the i915 driver does a gpiod_get(..., GPIOD_OUT_HIGH) for the panel-enable GPIO. The temporarily going low of that GPIO was causing the panel to reset itself after which it would not show an image until it was turned off and back on again (until a full modeset was done on it). This commit fixes this. This commit also updates the byt_gpio_direction_input() to use direct register accesses instead of going through pinctrl_gpio_direction_input(), to keep it consistent with byt_gpio_direction_output(). Note for backporting, this commit depends on: commit e2b74419e5cc ("pinctrl: baytrail: Replace WARN with dev_info_once when setting direct-irq pin to output") Cc: stable@vger.kernel.org Fixes: 86e3ef812fe3 ("pinctrl: baytrail: Update gpio chip operations") Signed-off-by: Hans de Goede Acked-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-baytrail.c | 67 +++++++++++++++++++----- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index e3ceb3dfeabe..a917a2df520e 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -800,6 +800,21 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, pm_runtime_put(vg->dev); } +static void byt_gpio_direct_irq_check(struct intel_pinctrl *vg, + unsigned int offset) +{ + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + + /* + * Before making any direction modifications, do a check if gpio is set + * for direct IRQ. On Bay Trail, setting GPIO to output does not make + * sense, so let's at least inform the caller before they shoot + * themselves in the foot. + */ + if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) + dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); +} + static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, struct pinctrl_gpio_range *range, unsigned int offset, @@ -807,7 +822,6 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, { struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); - void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); unsigned long flags; u32 value; @@ -817,14 +831,8 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, value &= ~BYT_DIR_MASK; if (input) value |= BYT_OUTPUT_EN; - else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) - /* - * Before making any direction modifications, do a check if gpio - * is set for direct IRQ. On baytrail, setting GPIO to output - * does not make sense, so let's at least inform the caller before - * they shoot themselves in the foot. - */ - dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); + else + byt_gpio_direct_irq_check(vg, offset); writel(value, val_reg); @@ -1165,19 +1173,50 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { - return pinctrl_gpio_direction_input(chip->base + offset); + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 reg; + + raw_spin_lock_irqsave(&byt_lock, flags); + + reg = readl(val_reg); + reg &= ~BYT_DIR_MASK; + reg |= BYT_OUTPUT_EN; + writel(reg, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); + return 0; } +/* + * Note despite the temptation this MUST NOT be converted into a call to + * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this + * MUST be done as a single BYT_VAL_REG register write. + * See the commit message of the commit adding this comment for details. + */ static int byt_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { - int ret = pinctrl_gpio_direction_output(chip->base + offset); + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 reg; - if (ret) - return ret; + raw_spin_lock_irqsave(&byt_lock, flags); - byt_gpio_set(chip, offset, value); + byt_gpio_direct_irq_check(vg, offset); + reg = readl(val_reg); + reg &= ~BYT_DIR_MASK; + if (value) + reg |= BYT_LEVEL; + else + reg &= ~BYT_LEVEL; + + writel(reg, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } From 503a02b72d457f18eccf58296f9b50df6666d7fc Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 22 Jun 2020 18:56:15 +0300 Subject: [PATCH 20/24] pinctrl: merrifield: Update pin names in accordance with official list Some of the pin names were provided officially to the customers in different spelling. We update pin names in accordance with the official list. Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-merrifield.c | 46 +++++++++++----------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c index 04ca8ae95df8..2c213714df30 100644 --- a/drivers/pinctrl/intel/pinctrl-merrifield.c +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -135,7 +135,7 @@ static const struct pinctrl_pin_desc mrfld_pins[] = { PINCTRL_PIN(43, "GP83_SD_D3"), PINCTRL_PIN(44, "GP84_SD_LS_CLK_FB"), PINCTRL_PIN(45, "GP85_SD_LS_CMD_DIR"), - PINCTRL_PIN(46, "GP86_SD_LVL_D_DIR"), + PINCTRL_PIN(46, "GP86_SD_LS_D_DIR"), PINCTRL_PIN(47, "GP88_SD_LS_SEL"), PINCTRL_PIN(48, "GP87_SD_PD"), PINCTRL_PIN(49, "GP89_SD_WP"), @@ -171,28 +171,28 @@ static const struct pinctrl_pin_desc mrfld_pins[] = { PINCTRL_PIN(77, "GP42_I2S_2_RXD"), PINCTRL_PIN(78, "GP43_I2S_2_TXD"), /* Family 6: GP SSP (22 pins) */ - PINCTRL_PIN(79, "GP120_SPI_3_CLK"), - PINCTRL_PIN(80, "GP121_SPI_3_SS"), - PINCTRL_PIN(81, "GP122_SPI_3_RXD"), - PINCTRL_PIN(82, "GP123_SPI_3_TXD"), - PINCTRL_PIN(83, "GP102_SPI_4_CLK"), - PINCTRL_PIN(84, "GP103_SPI_4_SS_0"), - PINCTRL_PIN(85, "GP104_SPI_4_SS_1"), - PINCTRL_PIN(86, "GP105_SPI_4_SS_2"), - PINCTRL_PIN(87, "GP106_SPI_4_SS_3"), - PINCTRL_PIN(88, "GP107_SPI_4_RXD"), - PINCTRL_PIN(89, "GP108_SPI_4_TXD"), - PINCTRL_PIN(90, "GP109_SPI_5_CLK"), - PINCTRL_PIN(91, "GP110_SPI_5_SS_0"), - PINCTRL_PIN(92, "GP111_SPI_5_SS_1"), - PINCTRL_PIN(93, "GP112_SPI_5_SS_2"), - PINCTRL_PIN(94, "GP113_SPI_5_SS_3"), - PINCTRL_PIN(95, "GP114_SPI_5_RXD"), - PINCTRL_PIN(96, "GP115_SPI_5_TXD"), - PINCTRL_PIN(97, "GP116_SPI_6_CLK"), - PINCTRL_PIN(98, "GP117_SPI_6_SS"), - PINCTRL_PIN(99, "GP118_SPI_6_RXD"), - PINCTRL_PIN(100, "GP119_SPI_6_TXD"), + PINCTRL_PIN(79, "GP120_SPI_0_CLK"), + PINCTRL_PIN(80, "GP121_SPI_0_SS"), + PINCTRL_PIN(81, "GP122_SPI_0_RXD"), + PINCTRL_PIN(82, "GP123_SPI_0_TXD"), + PINCTRL_PIN(83, "GP102_SPI_1_CLK"), + PINCTRL_PIN(84, "GP103_SPI_1_SS0"), + PINCTRL_PIN(85, "GP104_SPI_1_SS1"), + PINCTRL_PIN(86, "GP105_SPI_1_SS2"), + PINCTRL_PIN(87, "GP106_SPI_1_SS3"), + PINCTRL_PIN(88, "GP107_SPI_1_RXD"), + PINCTRL_PIN(89, "GP108_SPI_1_TXD"), + PINCTRL_PIN(90, "GP109_SPI_2_CLK"), + PINCTRL_PIN(91, "GP110_SPI_2_SS0"), + PINCTRL_PIN(92, "GP111_SPI_2_SS1"), + PINCTRL_PIN(93, "GP112_SPI_2_SS2"), + PINCTRL_PIN(94, "GP113_SPI_2_SS3"), + PINCTRL_PIN(95, "GP114_SPI_2_RXD"), + PINCTRL_PIN(96, "GP115_SPI_2_TXD"), + PINCTRL_PIN(97, "GP116_SPI_3_CLK"), + PINCTRL_PIN(98, "GP117_SPI_3_SS"), + PINCTRL_PIN(99, "GP118_SPI_3_RXD"), + PINCTRL_PIN(100, "GP119_SPI_3_TXD"), /* Family 7: I2C (14 pins) */ PINCTRL_PIN(101, "GP19_I2C_1_SCL"), PINCTRL_PIN(102, "GP20_I2C_1_SDA"), From 169efc3bf4dde79a8e15d71f45f1150bec46b663 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 4 Jun 2020 12:28:07 +0300 Subject: [PATCH 21/24] =?UTF-8?q?pinctrl:=20merrifield:=20Add=20I=C2=B2S?= =?UTF-8?q?=20bus=202=20pins=20to=20groups=20and=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is useful to control I²S bus 2 pins if we would like to connect an audio codec. Reported-by: mouse Reported-by: Pierre-Louis Bossart Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-merrifield.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c index 2c213714df30..e4ff8da1b894 100644 --- a/drivers/pinctrl/intel/pinctrl-merrifield.c +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -340,6 +340,7 @@ static const struct pinctrl_pin_desc mrfld_pins[] = { }; static const unsigned int mrfld_sdio_pins[] = { 50, 51, 52, 53, 54, 55, 56 }; +static const unsigned int mrfld_i2s2_pins[] = { 75, 76, 77, 78 }; static const unsigned int mrfld_spi5_pins[] = { 90, 91, 92, 93, 94, 95, 96 }; static const unsigned int mrfld_uart0_pins[] = { 115, 116, 117, 118 }; static const unsigned int mrfld_uart1_pins[] = { 119, 120, 121, 122 }; @@ -351,6 +352,7 @@ static const unsigned int mrfld_pwm3_pins[] = { 133 }; static const struct intel_pingroup mrfld_groups[] = { PIN_GROUP("sdio_grp", mrfld_sdio_pins, 1), + PIN_GROUP("i2s2_grp", mrfld_i2s2_pins, 1), PIN_GROUP("spi5_grp", mrfld_spi5_pins, 1), PIN_GROUP("uart0_grp", mrfld_uart0_pins, 1), PIN_GROUP("uart1_grp", mrfld_uart1_pins, 1), @@ -362,6 +364,7 @@ static const struct intel_pingroup mrfld_groups[] = { }; static const char * const mrfld_sdio_groups[] = { "sdio_grp" }; +static const char * const mrfld_i2s2_groups[] = { "i2s2_grp" }; static const char * const mrfld_spi5_groups[] = { "spi5_grp" }; static const char * const mrfld_uart0_groups[] = { "uart0_grp" }; static const char * const mrfld_uart1_groups[] = { "uart1_grp" }; @@ -373,6 +376,7 @@ static const char * const mrfld_pwm3_groups[] = { "pwm3_grp" }; static const struct intel_function mrfld_functions[] = { FUNCTION("sdio", mrfld_sdio_groups), + FUNCTION("i2s2", mrfld_i2s2_groups), FUNCTION("spi5", mrfld_spi5_groups), FUNCTION("uart0", mrfld_uart0_groups), FUNCTION("uart1", mrfld_uart1_groups), From 653d96455e1e30811f4b9ec44d3b9df9bd7a55a3 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 25 Jun 2020 16:20:53 +0300 Subject: [PATCH 22/24] pinctrl: tigerlake: Add support for Tiger Lake-H Intel Tiger Lake-H has different pin layout than the -LP variant so add support for this to the existing Tiger Lake driver. Signed-off-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-tigerlake.c | 358 ++++++++++++++++++++++ 1 file changed, 358 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-tigerlake.c b/drivers/pinctrl/intel/pinctrl-tigerlake.c index bcfd7548e282..8c162dd5f5a1 100644 --- a/drivers/pinctrl/intel/pinctrl-tigerlake.c +++ b/drivers/pinctrl/intel/pinctrl-tigerlake.c @@ -380,8 +380,366 @@ static const struct intel_pinctrl_soc_data tgllp_soc_data = { .ncommunities = ARRAY_SIZE(tgllp_communities), }; +/* Tiger Lake-H */ +static const struct pinctrl_pin_desc tglh_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "SPI0_IO_2"), + PINCTRL_PIN(1, "SPI0_IO_3"), + PINCTRL_PIN(2, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(3, "SPI0_MISO_IO_1"), + PINCTRL_PIN(4, "SPI0_TPM_CSB"), + PINCTRL_PIN(5, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(6, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(7, "SPI0_CLK"), + PINCTRL_PIN(8, "ESPI_IO_0"), + PINCTRL_PIN(9, "ESPI_IO_1"), + PINCTRL_PIN(10, "ESPI_IO_2"), + PINCTRL_PIN(11, "ESPI_IO_3"), + PINCTRL_PIN(12, "ESPI_CS0B"), + PINCTRL_PIN(13, "ESPI_CLK"), + PINCTRL_PIN(14, "ESPI_RESETB"), + PINCTRL_PIN(15, "ESPI_CS1B"), + PINCTRL_PIN(16, "ESPI_CS2B"), + PINCTRL_PIN(17, "ESPI_CS3B"), + PINCTRL_PIN(18, "ESPI_ALERT0B"), + PINCTRL_PIN(19, "ESPI_ALERT1B"), + PINCTRL_PIN(20, "ESPI_ALERT2B"), + PINCTRL_PIN(21, "ESPI_ALERT3B"), + PINCTRL_PIN(22, "GPPC_A_14"), + PINCTRL_PIN(23, "SPI0_CLK_LOOPBK"), + PINCTRL_PIN(24, "ESPI_CLK_LOOPBK"), + /* GPP_R */ + PINCTRL_PIN(25, "HDA_BCLK"), + PINCTRL_PIN(26, "HDA_SYNC"), + PINCTRL_PIN(27, "HDA_SDO"), + PINCTRL_PIN(28, "HDA_SDI_0"), + PINCTRL_PIN(29, "HDA_RSTB"), + PINCTRL_PIN(30, "HDA_SDI_1"), + PINCTRL_PIN(31, "GPP_R_6"), + PINCTRL_PIN(32, "GPP_R_7"), + PINCTRL_PIN(33, "GPP_R_8"), + PINCTRL_PIN(34, "PCIE_LNK_DOWN"), + PINCTRL_PIN(35, "ISH_UART0_RTSB"), + PINCTRL_PIN(36, "SX_EXIT_HOLDOFFB"), + PINCTRL_PIN(37, "CLKOUT_48"), + PINCTRL_PIN(38, "ISH_GP_7"), + PINCTRL_PIN(39, "ISH_GP_0"), + PINCTRL_PIN(40, "ISH_GP_1"), + PINCTRL_PIN(41, "ISH_GP_2"), + PINCTRL_PIN(42, "ISH_GP_3"), + PINCTRL_PIN(43, "ISH_GP_4"), + PINCTRL_PIN(44, "ISH_GP_5"), + /* GPP_B */ + PINCTRL_PIN(45, "GSPI0_CS1B"), + PINCTRL_PIN(46, "GSPI1_CS1B"), + PINCTRL_PIN(47, "VRALERTB"), + PINCTRL_PIN(48, "CPU_GP_2"), + PINCTRL_PIN(49, "CPU_GP_3"), + PINCTRL_PIN(50, "SRCCLKREQB_0"), + PINCTRL_PIN(51, "SRCCLKREQB_1"), + PINCTRL_PIN(52, "SRCCLKREQB_2"), + PINCTRL_PIN(53, "SRCCLKREQB_3"), + PINCTRL_PIN(54, "SRCCLKREQB_4"), + PINCTRL_PIN(55, "SRCCLKREQB_5"), + PINCTRL_PIN(56, "I2S_MCLK"), + PINCTRL_PIN(57, "SLP_S0B"), + PINCTRL_PIN(58, "PLTRSTB"), + PINCTRL_PIN(59, "SPKR"), + PINCTRL_PIN(60, "GSPI0_CS0B"), + PINCTRL_PIN(61, "GSPI0_CLK"), + PINCTRL_PIN(62, "GSPI0_MISO"), + PINCTRL_PIN(63, "GSPI0_MOSI"), + PINCTRL_PIN(64, "GSPI1_CS0B"), + PINCTRL_PIN(65, "GSPI1_CLK"), + PINCTRL_PIN(66, "GSPI1_MISO"), + PINCTRL_PIN(67, "GSPI1_MOSI"), + PINCTRL_PIN(68, "SML1ALERTB"), + PINCTRL_PIN(69, "GSPI0_CLK_LOOPBK"), + PINCTRL_PIN(70, "GSPI1_CLK_LOOPBK"), + /* vGPIO_0 */ + PINCTRL_PIN(71, "ESPI_USB_OCB_0"), + PINCTRL_PIN(72, "ESPI_USB_OCB_1"), + PINCTRL_PIN(73, "ESPI_USB_OCB_2"), + PINCTRL_PIN(74, "ESPI_USB_OCB_3"), + PINCTRL_PIN(75, "USB_CPU_OCB_0"), + PINCTRL_PIN(76, "USB_CPU_OCB_1"), + PINCTRL_PIN(77, "USB_CPU_OCB_2"), + PINCTRL_PIN(78, "USB_CPU_OCB_3"), + /* GPP_D */ + PINCTRL_PIN(79, "SPI1_CSB"), + PINCTRL_PIN(80, "SPI1_CLK"), + PINCTRL_PIN(81, "SPI1_MISO_IO_1"), + PINCTRL_PIN(82, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(83, "SML1CLK"), + PINCTRL_PIN(84, "I2S2_SFRM"), + PINCTRL_PIN(85, "I2S2_TXD"), + PINCTRL_PIN(86, "I2S2_RXD"), + PINCTRL_PIN(87, "I2S2_SCLK"), + PINCTRL_PIN(88, "SML0CLK"), + PINCTRL_PIN(89, "SML0DATA"), + PINCTRL_PIN(90, "GPP_D_11"), + PINCTRL_PIN(91, "ISH_UART0_CTSB"), + PINCTRL_PIN(92, "SPI1_IO_2"), + PINCTRL_PIN(93, "SPI1_IO_3"), + PINCTRL_PIN(94, "SML1DATA"), + PINCTRL_PIN(95, "GSPI3_CS0B"), + PINCTRL_PIN(96, "GSPI3_CLK"), + PINCTRL_PIN(97, "GSPI3_MISO"), + PINCTRL_PIN(98, "GSPI3_MOSI"), + PINCTRL_PIN(99, "UART3_RXD"), + PINCTRL_PIN(100, "UART3_TXD"), + PINCTRL_PIN(101, "UART3_RTSB"), + PINCTRL_PIN(102, "UART3_CTSB"), + PINCTRL_PIN(103, "SPI1_CLK_LOOPBK"), + PINCTRL_PIN(104, "GSPI3_CLK_LOOPBK"), + /* GPP_C */ + PINCTRL_PIN(105, "SMBCLK"), + PINCTRL_PIN(106, "SMBDATA"), + PINCTRL_PIN(107, "SMBALERTB"), + PINCTRL_PIN(108, "ISH_UART0_RXD"), + PINCTRL_PIN(109, "ISH_UART0_TXD"), + PINCTRL_PIN(110, "SML0ALERTB"), + PINCTRL_PIN(111, "ISH_I2C2_SDA"), + PINCTRL_PIN(112, "ISH_I2C2_SCL"), + PINCTRL_PIN(113, "UART0_RXD"), + PINCTRL_PIN(114, "UART0_TXD"), + PINCTRL_PIN(115, "UART0_RTSB"), + PINCTRL_PIN(116, "UART0_CTSB"), + PINCTRL_PIN(117, "UART1_RXD"), + PINCTRL_PIN(118, "UART1_TXD"), + PINCTRL_PIN(119, "UART1_RTSB"), + PINCTRL_PIN(120, "UART1_CTSB"), + PINCTRL_PIN(121, "I2C0_SDA"), + PINCTRL_PIN(122, "I2C0_SCL"), + PINCTRL_PIN(123, "I2C1_SDA"), + PINCTRL_PIN(124, "I2C1_SCL"), + PINCTRL_PIN(125, "UART2_RXD"), + PINCTRL_PIN(126, "UART2_TXD"), + PINCTRL_PIN(127, "UART2_RTSB"), + PINCTRL_PIN(128, "UART2_CTSB"), + /* GPP_S */ + PINCTRL_PIN(129, "SNDW1_CLK"), + PINCTRL_PIN(130, "SNDW1_DATA"), + PINCTRL_PIN(131, "SNDW2_CLK"), + PINCTRL_PIN(132, "SNDW2_DATA"), + PINCTRL_PIN(133, "SNDW3_CLK"), + PINCTRL_PIN(134, "SNDW3_DATA"), + PINCTRL_PIN(135, "SNDW4_CLK"), + PINCTRL_PIN(136, "SNDW4_DATA"), + /* GPP_G */ + PINCTRL_PIN(137, "DDPA_CTRLCLK"), + PINCTRL_PIN(138, "DDPA_CTRLDATA"), + PINCTRL_PIN(139, "DNX_FORCE_RELOAD"), + PINCTRL_PIN(140, "GMII_MDC_0"), + PINCTRL_PIN(141, "GMII_MDIO_0"), + PINCTRL_PIN(142, "SLP_DRAMB"), + PINCTRL_PIN(143, "GPPC_G_6"), + PINCTRL_PIN(144, "GPPC_G_7"), + PINCTRL_PIN(145, "ISH_SPI_CSB"), + PINCTRL_PIN(146, "ISH_SPI_CLK"), + PINCTRL_PIN(147, "ISH_SPI_MISO"), + PINCTRL_PIN(148, "ISH_SPI_MOSI"), + PINCTRL_PIN(149, "DDP1_CTRLCLK"), + PINCTRL_PIN(150, "DDP1_CTRLDATA"), + PINCTRL_PIN(151, "DDP2_CTRLCLK"), + PINCTRL_PIN(152, "DDP2_CTRLDATA"), + PINCTRL_PIN(153, "GSPI2_CLK_LOOPBK"), + /* vGPIO */ + PINCTRL_PIN(154, "CNV_BTEN"), + PINCTRL_PIN(155, "CNV_BT_HOST_WAKEB"), + PINCTRL_PIN(156, "CNV_BT_IF_SELECT"), + PINCTRL_PIN(157, "vCNV_BT_UART_TXD"), + PINCTRL_PIN(158, "vCNV_BT_UART_RXD"), + PINCTRL_PIN(159, "vCNV_BT_UART_CTS_B"), + PINCTRL_PIN(160, "vCNV_BT_UART_RTS_B"), + PINCTRL_PIN(161, "vCNV_MFUART1_TXD"), + PINCTRL_PIN(162, "vCNV_MFUART1_RXD"), + PINCTRL_PIN(163, "vCNV_MFUART1_CTS_B"), + PINCTRL_PIN(164, "vCNV_MFUART1_RTS_B"), + PINCTRL_PIN(165, "vUART0_TXD"), + PINCTRL_PIN(166, "vUART0_RXD"), + PINCTRL_PIN(167, "vUART0_CTS_B"), + PINCTRL_PIN(168, "vUART0_RTS_B"), + PINCTRL_PIN(169, "vISH_UART0_TXD"), + PINCTRL_PIN(170, "vISH_UART0_RXD"), + PINCTRL_PIN(171, "vISH_UART0_CTS_B"), + PINCTRL_PIN(172, "vISH_UART0_RTS_B"), + PINCTRL_PIN(173, "vCNV_BT_I2S_BCLK"), + PINCTRL_PIN(174, "vCNV_BT_I2S_WS_SYNC"), + PINCTRL_PIN(175, "vCNV_BT_I2S_SDO"), + PINCTRL_PIN(176, "vCNV_BT_I2S_SDI"), + PINCTRL_PIN(177, "vI2S2_SCLK"), + PINCTRL_PIN(178, "vI2S2_SFRM"), + PINCTRL_PIN(179, "vI2S2_TXD"), + PINCTRL_PIN(180, "vI2S2_RXD"), + /* GPP_E */ + PINCTRL_PIN(181, "SATAXPCIE_0"), + PINCTRL_PIN(182, "SATAXPCIE_1"), + PINCTRL_PIN(183, "SATAXPCIE_2"), + PINCTRL_PIN(184, "CPU_GP_0"), + PINCTRL_PIN(185, "SATA_DEVSLP_0"), + PINCTRL_PIN(186, "SATA_DEVSLP_1"), + PINCTRL_PIN(187, "SATA_DEVSLP_2"), + PINCTRL_PIN(188, "CPU_GP_1"), + PINCTRL_PIN(189, "SATA_LEDB"), + PINCTRL_PIN(190, "USB2_OCB_0"), + PINCTRL_PIN(191, "USB2_OCB_1"), + PINCTRL_PIN(192, "USB2_OCB_2"), + PINCTRL_PIN(193, "USB2_OCB_3"), + /* GPP_F */ + PINCTRL_PIN(194, "SATAXPCIE_3"), + PINCTRL_PIN(195, "SATAXPCIE_4"), + PINCTRL_PIN(196, "SATAXPCIE_5"), + PINCTRL_PIN(197, "SATAXPCIE_6"), + PINCTRL_PIN(198, "SATAXPCIE_7"), + PINCTRL_PIN(199, "SATA_DEVSLP_3"), + PINCTRL_PIN(200, "SATA_DEVSLP_4"), + PINCTRL_PIN(201, "SATA_DEVSLP_5"), + PINCTRL_PIN(202, "SATA_DEVSLP_6"), + PINCTRL_PIN(203, "SATA_DEVSLP_7"), + PINCTRL_PIN(204, "SATA_SCLOCK"), + PINCTRL_PIN(205, "SATA_SLOAD"), + PINCTRL_PIN(206, "SATA_SDATAOUT1"), + PINCTRL_PIN(207, "SATA_SDATAOUT0"), + PINCTRL_PIN(208, "PS_ONB"), + PINCTRL_PIN(209, "M2_SKT2_CFG_0"), + PINCTRL_PIN(210, "M2_SKT2_CFG_1"), + PINCTRL_PIN(211, "M2_SKT2_CFG_2"), + PINCTRL_PIN(212, "M2_SKT2_CFG_3"), + PINCTRL_PIN(213, "L_VDDEN"), + PINCTRL_PIN(214, "L_BKLTEN"), + PINCTRL_PIN(215, "L_BKLTCTL"), + PINCTRL_PIN(216, "VNN_CTRL"), + PINCTRL_PIN(217, "GPP_F_23"), + /* GPP_H */ + PINCTRL_PIN(218, "SRCCLKREQB_6"), + PINCTRL_PIN(219, "SRCCLKREQB_7"), + PINCTRL_PIN(220, "SRCCLKREQB_8"), + PINCTRL_PIN(221, "SRCCLKREQB_9"), + PINCTRL_PIN(222, "SRCCLKREQB_10"), + PINCTRL_PIN(223, "SRCCLKREQB_11"), + PINCTRL_PIN(224, "SRCCLKREQB_12"), + PINCTRL_PIN(225, "SRCCLKREQB_13"), + PINCTRL_PIN(226, "SRCCLKREQB_14"), + PINCTRL_PIN(227, "SRCCLKREQB_15"), + PINCTRL_PIN(228, "SML2CLK"), + PINCTRL_PIN(229, "SML2DATA"), + PINCTRL_PIN(230, "SML2ALERTB"), + PINCTRL_PIN(231, "SML3CLK"), + PINCTRL_PIN(232, "SML3DATA"), + PINCTRL_PIN(233, "SML3ALERTB"), + PINCTRL_PIN(234, "SML4CLK"), + PINCTRL_PIN(235, "SML4DATA"), + PINCTRL_PIN(236, "SML4ALERTB"), + PINCTRL_PIN(237, "ISH_I2C0_SDA"), + PINCTRL_PIN(238, "ISH_I2C0_SCL"), + PINCTRL_PIN(239, "ISH_I2C1_SDA"), + PINCTRL_PIN(240, "ISH_I2C1_SCL"), + PINCTRL_PIN(241, "TIME_SYNC_0"), + /* GPP_J */ + PINCTRL_PIN(242, "CNV_PA_BLANKING"), + PINCTRL_PIN(243, "CPU_C10_GATEB"), + PINCTRL_PIN(244, "CNV_BRI_DT"), + PINCTRL_PIN(245, "CNV_BRI_RSP"), + PINCTRL_PIN(246, "CNV_RGI_DT"), + PINCTRL_PIN(247, "CNV_RGI_RSP"), + PINCTRL_PIN(248, "CNV_MFUART2_RXD"), + PINCTRL_PIN(249, "CNV_MFUART2_TXD"), + PINCTRL_PIN(250, "GPP_J_8"), + PINCTRL_PIN(251, "GPP_J_9"), + /* GPP_K */ + PINCTRL_PIN(252, "GSXDOUT"), + PINCTRL_PIN(253, "GSXSLOAD"), + PINCTRL_PIN(254, "GSXDIN"), + PINCTRL_PIN(255, "GSXSRESETB"), + PINCTRL_PIN(256, "GSXCLK"), + PINCTRL_PIN(257, "ADR_COMPLETE"), + PINCTRL_PIN(258, "DDSP_HPD_A"), + PINCTRL_PIN(259, "DDSP_HPD_B"), + PINCTRL_PIN(260, "CORE_VID_0"), + PINCTRL_PIN(261, "CORE_VID_1"), + PINCTRL_PIN(262, "DDSP_HPD_C"), + PINCTRL_PIN(263, "GPP_K_11"), + PINCTRL_PIN(264, "SYS_PWROK"), + PINCTRL_PIN(265, "SYS_RESETB"), + PINCTRL_PIN(266, "MLK_RSTB"), + /* GPP_I */ + PINCTRL_PIN(267, "PMCALERTB"), + PINCTRL_PIN(268, "DDSP_HPD_1"), + PINCTRL_PIN(269, "DDSP_HPD_2"), + PINCTRL_PIN(270, "DDSP_HPD_3"), + PINCTRL_PIN(271, "DDSP_HPD_4"), + PINCTRL_PIN(272, "DDPB_CTRLCLK"), + PINCTRL_PIN(273, "DDPB_CTRLDATA"), + PINCTRL_PIN(274, "DDPC_CTRLCLK"), + PINCTRL_PIN(275, "DDPC_CTRLDATA"), + PINCTRL_PIN(276, "FUSA_DIAGTEST_EN"), + PINCTRL_PIN(277, "FUSA_DIAGTEST_MODE"), + PINCTRL_PIN(278, "USB2_OCB_4"), + PINCTRL_PIN(279, "USB2_OCB_5"), + PINCTRL_PIN(280, "USB2_OCB_6"), + PINCTRL_PIN(281, "USB2_OCB_7"), + /* JTAG */ + PINCTRL_PIN(282, "JTAG_TDO"), + PINCTRL_PIN(283, "JTAGX"), + PINCTRL_PIN(284, "PRDYB"), + PINCTRL_PIN(285, "PREQB"), + PINCTRL_PIN(286, "JTAG_TDI"), + PINCTRL_PIN(287, "JTAG_TMS"), + PINCTRL_PIN(288, "JTAG_TCK"), + PINCTRL_PIN(289, "DBG_PMODE"), + PINCTRL_PIN(290, "CPU_TRSTB"), +}; + +static const struct intel_padgroup tglh_community0_gpps[] = { + TGL_GPP(0, 0, 24, 0), /* GPP_A */ + TGL_GPP(1, 25, 44, 128), /* GPP_R */ + TGL_GPP(2, 45, 70, 32), /* GPP_B */ + TGL_GPP(3, 71, 78, INTEL_GPIO_BASE_NOMAP), /* vGPIO_0 */ +}; + +static const struct intel_padgroup tglh_community1_gpps[] = { + TGL_GPP(0, 79, 104, 96), /* GPP_D */ + TGL_GPP(1, 105, 128, 64), /* GPP_C */ + TGL_GPP(2, 129, 136, 160), /* GPP_S */ + TGL_GPP(3, 137, 153, 192), /* GPP_G */ + TGL_GPP(4, 154, 180, 224), /* vGPIO */ +}; + +static const struct intel_padgroup tglh_community3_gpps[] = { + TGL_GPP(0, 181, 193, 256), /* GPP_E */ + TGL_GPP(1, 194, 217, 288), /* GPP_F */ +}; + +static const struct intel_padgroup tglh_community4_gpps[] = { + TGL_GPP(0, 218, 241, 320), /* GPP_H */ + TGL_GPP(1, 242, 251, 384), /* GPP_J */ + TGL_GPP(2, 252, 266, 352), /* GPP_K */ +}; + +static const struct intel_padgroup tglh_community5_gpps[] = { + TGL_GPP(0, 267, 281, 416), /* GPP_I */ + TGL_GPP(1, 282, 290, INTEL_GPIO_BASE_NOMAP), /* JTAG */ +}; + +static const struct intel_community tglh_communities[] = { + TGL_COMMUNITY(0, 0, 78, tglh_community0_gpps), + TGL_COMMUNITY(1, 79, 180, tglh_community1_gpps), + TGL_COMMUNITY(2, 181, 217, tglh_community3_gpps), + TGL_COMMUNITY(3, 218, 266, tglh_community4_gpps), + TGL_COMMUNITY(4, 267, 290, tglh_community5_gpps), +}; + +static const struct intel_pinctrl_soc_data tglh_soc_data = { + .pins = tglh_pins, + .npins = ARRAY_SIZE(tglh_pins), + .communities = tglh_communities, + .ncommunities = ARRAY_SIZE(tglh_communities), +}; + static const struct acpi_device_id tgl_pinctrl_acpi_match[] = { { "INT34C5", (kernel_ulong_t)&tgllp_soc_data }, + { "INT34C6", (kernel_ulong_t)&tglh_soc_data }, { } }; MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match); From 0a0930206762b34c74bf14242765dc52d56f2792 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 16 Jul 2020 16:19:19 -0500 Subject: [PATCH 23/24] pinctrl: baytrail: Use fallthrough pseudo-keyword Replace the existing /* fall through */ comments and its variants with the new pseudo-keyword macro fallthrough[1]. [1] https://www.kernel.org/doc/html/latest/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through Signed-off-by: Gustavo A. R. Silva Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-baytrail.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index a917a2df520e..d6e35cba3065 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1372,13 +1372,13 @@ static void byt_irq_unmask(struct irq_data *d) switch (irqd_get_trigger_type(d)) { case IRQ_TYPE_LEVEL_HIGH: value |= BYT_TRIG_LVL; - /* fall through */ + fallthrough; case IRQ_TYPE_EDGE_RISING: value |= BYT_TRIG_POS; break; case IRQ_TYPE_LEVEL_LOW: value |= BYT_TRIG_LVL; - /* fall through */ + fallthrough; case IRQ_TYPE_EDGE_FALLING: value |= BYT_TRIG_NEG; break; From b4f2fcb534875e2e57c96a0358267f2109d68004 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 16 Jul 2020 15:42:44 +0300 Subject: [PATCH 24/24] pinctrl: intel: Add Intel Emmitsburg pin controller support This driver adds pinctrl/GPIO support for Intel Emmitsburg PCH. The GPIO controller is based on the next generation GPIO hardware but still compatible with the one supported by the Intel core pinctrl/GPIO driver. Signed-off-by: Andy Shevchenko Reviewed-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/Kconfig | 8 + drivers/pinctrl/intel/Makefile | 1 + drivers/pinctrl/intel/pinctrl-emmitsburg.c | 387 +++++++++++++++++++++ 3 files changed, 396 insertions(+) create mode 100644 drivers/pinctrl/intel/pinctrl-emmitsburg.c diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index 787833e343a4..b3e6060db52d 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig @@ -95,6 +95,14 @@ config PINCTRL_DENVERTON This pinctrl driver provides an interface that allows configuring of Intel Denverton SoC pins and using them as GPIOs. +config PINCTRL_EMMITSBURG + tristate "Intel Emmitsburg pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Emmitsburg pins and using them as GPIOs. + config PINCTRL_GEMINILAKE tristate "Intel Gemini Lake SoC pinctrl and GPIO driver" depends on ACPI diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile index f6f63eb8100f..1c1c316f98b9 100644 --- a/drivers/pinctrl/intel/Makefile +++ b/drivers/pinctrl/intel/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o obj-$(CONFIG_PINCTRL_CANNONLAKE) += pinctrl-cannonlake.o obj-$(CONFIG_PINCTRL_CEDARFORK) += pinctrl-cedarfork.o obj-$(CONFIG_PINCTRL_DENVERTON) += pinctrl-denverton.o +obj-$(CONFIG_PINCTRL_EMMITSBURG) += pinctrl-emmitsburg.o obj-$(CONFIG_PINCTRL_GEMINILAKE) += pinctrl-geminilake.o obj-$(CONFIG_PINCTRL_ICELAKE) += pinctrl-icelake.o obj-$(CONFIG_PINCTRL_JASPERLAKE) += pinctrl-jasperlake.o diff --git a/drivers/pinctrl/intel/pinctrl-emmitsburg.c b/drivers/pinctrl/intel/pinctrl-emmitsburg.c new file mode 100644 index 000000000000..f6114dbf7520 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-emmitsburg.c @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Emmitsburg PCH pinctrl/GPIO driver + * + * Copyright (C) 2020, Intel Corporation + * Author: Andy Shevchenko + */ + +#include +#include +#include + +#include + +#include "pinctrl-intel.h" + +#define EBG_PAD_OWN 0x0a0 +#define EBG_PADCFGLOCK 0x100 +#define EBG_HOSTSW_OWN 0x130 +#define EBG_GPI_IS 0x200 +#define EBG_GPI_IE 0x210 + +#define EBG_GPP(r, s, e) \ + { \ + .reg_num = (r), \ + .base = (s), \ + .size = ((e) - (s) + 1), \ + } + +#define EBG_COMMUNITY(b, s, e, g) \ + { \ + .barno = (b), \ + .padown_offset = EBG_PAD_OWN, \ + .padcfglock_offset = EBG_PADCFGLOCK, \ + .hostown_offset = EBG_HOSTSW_OWN, \ + .is_offset = EBG_GPI_IS, \ + .ie_offset = EBG_GPI_IE, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + } + +/* Emmitsburg */ +static const struct pinctrl_pin_desc ebg_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "ESPI_ALERT0B"), + PINCTRL_PIN(1, "ESPI_ALERT1B"), + PINCTRL_PIN(2, "ESPI_IO_0"), + PINCTRL_PIN(3, "ESPI_IO_1"), + PINCTRL_PIN(4, "ESPI_IO_2"), + PINCTRL_PIN(5, "ESPI_IO_3"), + PINCTRL_PIN(6, "ESPI_CS0B"), + PINCTRL_PIN(7, "ESPI_CS1B"), + PINCTRL_PIN(8, "ESPI_RESETB"), + PINCTRL_PIN(9, "ESPI_CLK"), + PINCTRL_PIN(10, "SRCCLKREQB_0"), + PINCTRL_PIN(11, "SRCCLKREQB_1"), + PINCTRL_PIN(12, "SRCCLKREQB_2"), + PINCTRL_PIN(13, "SRCCLKREQB_3"), + PINCTRL_PIN(14, "SRCCLKREQB_4"), + PINCTRL_PIN(15, "SRCCLKREQB_5"), + PINCTRL_PIN(16, "SRCCLKREQB_6"), + PINCTRL_PIN(17, "SRCCLKREQB_7"), + PINCTRL_PIN(18, "SRCCLKREQB_8"), + PINCTRL_PIN(19, "SRCCLKREQB_9"), + PINCTRL_PIN(20, "ESPI_CLK_LOOPBK"), + /* GPP_B */ + PINCTRL_PIN(21, "GSXDOUT"), + PINCTRL_PIN(22, "GSXSLOAD"), + PINCTRL_PIN(23, "GSXDIN"), + PINCTRL_PIN(24, "GSXSRESETB"), + PINCTRL_PIN(25, "GSXCLK"), + PINCTRL_PIN(26, "USB2_OCB_0"), + PINCTRL_PIN(27, "USB2_OCB_1"), + PINCTRL_PIN(28, "USB2_OCB_2"), + PINCTRL_PIN(29, "USB2_OCB_3"), + PINCTRL_PIN(30, "USB2_OCB_4"), + PINCTRL_PIN(31, "USB2_OCB_5"), + PINCTRL_PIN(32, "USB2_OCB_6"), + PINCTRL_PIN(33, "HS_UART0_RXD"), + PINCTRL_PIN(34, "HS_UART0_TXD"), + PINCTRL_PIN(35, "HS_UART0_RTSB"), + PINCTRL_PIN(36, "HS_UART0_CTSB"), + PINCTRL_PIN(37, "HS_UART1_RXD"), + PINCTRL_PIN(38, "HS_UART1_TXD"), + PINCTRL_PIN(39, "HS_UART1_RTSB"), + PINCTRL_PIN(40, "HS_UART1_CTSB"), + PINCTRL_PIN(41, "GPPC_B_20"), + PINCTRL_PIN(42, "GPPC_B_21"), + PINCTRL_PIN(43, "GPPC_B_22"), + PINCTRL_PIN(44, "PS_ONB"), + /* SPI */ + PINCTRL_PIN(45, "SPI0_IO_2"), + PINCTRL_PIN(46, "SPI0_IO_3"), + PINCTRL_PIN(47, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(48, "SPI0_MISO_IO_1"), + PINCTRL_PIN(49, "SPI0_TPM_CSB"), + PINCTRL_PIN(50, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(51, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(52, "SPI0_CLK"), + PINCTRL_PIN(53, "TIME_SYNC_0"), + PINCTRL_PIN(54, "SPKR"), + PINCTRL_PIN(55, "CPU_GP_0"), + PINCTRL_PIN(56, "CPU_GP_1"), + PINCTRL_PIN(57, "CPU_GP_2"), + PINCTRL_PIN(58, "CPU_GP_3"), + PINCTRL_PIN(59, "SUSWARNB_SUSPWRDNACK"), + PINCTRL_PIN(60, "SUSACKB"), + PINCTRL_PIN(61, "NMIB"), + PINCTRL_PIN(62, "SMIB"), + PINCTRL_PIN(63, "GPPC_S_10"), + PINCTRL_PIN(64, "GPPC_S_11"), + PINCTRL_PIN(65, "SPI_CLK_LOOPBK"), + /* GPP_C */ + PINCTRL_PIN(66, "ME_SML0CLK"), + PINCTRL_PIN(67, "ME_SML0DATA"), + PINCTRL_PIN(68, "ME_SML0ALERTB"), + PINCTRL_PIN(69, "ME_SML0BDATA"), + PINCTRL_PIN(70, "ME_SML0BCLK"), + PINCTRL_PIN(71, "ME_SML0BALERTB"), + PINCTRL_PIN(72, "ME_SML1CLK"), + PINCTRL_PIN(73, "ME_SML1DATA"), + PINCTRL_PIN(74, "ME_SML1ALERTB"), + PINCTRL_PIN(75, "ME_SML2CLK"), + PINCTRL_PIN(76, "ME_SML2DATA"), + PINCTRL_PIN(77, "ME_SML2ALERTB"), + PINCTRL_PIN(78, "ME_SML3CLK"), + PINCTRL_PIN(79, "ME_SML3DATA"), + PINCTRL_PIN(80, "ME_SML3ALERTB"), + PINCTRL_PIN(81, "ME_SML4CLK"), + PINCTRL_PIN(82, "ME_SML4DATA"), + PINCTRL_PIN(83, "ME_SML4ALERTB"), + PINCTRL_PIN(84, "GPPC_C_18"), + PINCTRL_PIN(85, "MC_SMBCLK"), + PINCTRL_PIN(86, "MC_SMBDATA"), + PINCTRL_PIN(87, "MC_SMBALERTB"), + /* GPP_D */ + PINCTRL_PIN(88, "HS_SMBCLK"), + PINCTRL_PIN(89, "HS_SMBDATA"), + PINCTRL_PIN(90, "HS_SMBALERTB"), + PINCTRL_PIN(91, "GBE_SMB_ALRT_N"), + PINCTRL_PIN(92, "GBE_SMB_CLK"), + PINCTRL_PIN(93, "GBE_SMB_DATA"), + PINCTRL_PIN(94, "GBE_GPIO10"), + PINCTRL_PIN(95, "GBE_GPIO11"), + PINCTRL_PIN(96, "CRASHLOG_TRIG_N"), + PINCTRL_PIN(97, "PMEB"), + PINCTRL_PIN(98, "BM_BUSYB"), + PINCTRL_PIN(99, "PLTRSTB"), + PINCTRL_PIN(100, "PCHHOTB"), + PINCTRL_PIN(101, "ADR_COMPLETE"), + PINCTRL_PIN(102, "ADR_TRIGGER_N"), + PINCTRL_PIN(103, "VRALERTB"), + PINCTRL_PIN(104, "ADR_ACK"), + PINCTRL_PIN(105, "THERMTRIP_N"), + PINCTRL_PIN(106, "MEMTRIP_N"), + PINCTRL_PIN(107, "MSMI_N"), + PINCTRL_PIN(108, "CATERR_N"), + PINCTRL_PIN(109, "GLB_RST_WARN_B"), + PINCTRL_PIN(110, "USB2_OCB_7"), + PINCTRL_PIN(111, "GPP_D_23"), + /* GPP_E */ + PINCTRL_PIN(112, "SATA1_XPCIE_0"), + PINCTRL_PIN(113, "SATA1_XPCIE_1"), + PINCTRL_PIN(114, "SATA1_XPCIE_2"), + PINCTRL_PIN(115, "SATA1_XPCIE_3"), + PINCTRL_PIN(116, "SATA0_XPCIE_2"), + PINCTRL_PIN(117, "SATA0_XPCIE_3"), + PINCTRL_PIN(118, "SATA0_USB3_XPCIE_0"), + PINCTRL_PIN(119, "SATA0_USB3_XPCIE_1"), + PINCTRL_PIN(120, "SATA0_SCLOCK"), + PINCTRL_PIN(121, "SATA0_SLOAD"), + PINCTRL_PIN(122, "SATA0_SDATAOUT"), + PINCTRL_PIN(123, "SATA1_SCLOCK"), + PINCTRL_PIN(124, "SATA1_SLOAD"), + PINCTRL_PIN(125, "SATA1_SDATAOUT"), + PINCTRL_PIN(126, "SATA2_SCLOCK"), + PINCTRL_PIN(127, "SATA2_SLOAD"), + PINCTRL_PIN(128, "SATA2_SDATAOUT"), + PINCTRL_PIN(129, "ERR0_N"), + PINCTRL_PIN(130, "ERR1_N"), + PINCTRL_PIN(131, "ERR2_N"), + PINCTRL_PIN(132, "GBE_UART_RXD"), + PINCTRL_PIN(133, "GBE_UART_TXD"), + PINCTRL_PIN(134, "GBE_UART_RTSB"), + PINCTRL_PIN(135, "GBE_UART_CTSB"), + /* JTAG */ + PINCTRL_PIN(136, "JTAG_TDO"), + PINCTRL_PIN(137, "JTAG_TDI"), + PINCTRL_PIN(138, "JTAG_TCK"), + PINCTRL_PIN(139, "JTAG_TMS"), + PINCTRL_PIN(140, "JTAGX"), + PINCTRL_PIN(141, "PRDYB"), + PINCTRL_PIN(142, "PREQB"), + PINCTRL_PIN(143, "GLB_PC_DISABLE"), + PINCTRL_PIN(144, "DBG_PMODE"), + PINCTRL_PIN(145, "GLB_EXT_ACC_DISABLE"), + /* GPP_H */ + PINCTRL_PIN(146, "GBE_GPIO12"), + PINCTRL_PIN(147, "GBE_GPIO13"), + PINCTRL_PIN(148, "GBE_SDP_TIMESYNC0_S2N"), + PINCTRL_PIN(149, "GBE_SDP_TIMESYNC1_S2N"), + PINCTRL_PIN(150, "GBE_SDP_TIMESYNC2_S2N"), + PINCTRL_PIN(151, "GBE_SDP_TIMESYNC3_S2N"), + PINCTRL_PIN(152, "GPPC_H_6"), + PINCTRL_PIN(153, "GPPC_H_7"), + PINCTRL_PIN(154, "NCSI_CLK_IN"), + PINCTRL_PIN(155, "NCSI_CRS_DV"), + PINCTRL_PIN(156, "NCSI_RXD0"), + PINCTRL_PIN(157, "NCSI_RXD1"), + PINCTRL_PIN(158, "NCSI_TX_EN"), + PINCTRL_PIN(159, "NCSI_TXD0"), + PINCTRL_PIN(160, "NCSI_TXD1"), + PINCTRL_PIN(161, "NAC_NCSI_CLK_OUT_0"), + PINCTRL_PIN(162, "NAC_NCSI_CLK_OUT_1"), + PINCTRL_PIN(163, "NAC_NCSI_CLK_OUT_2"), + PINCTRL_PIN(164, "PMCALERTB"), + PINCTRL_PIN(165, "GPPC_H_19"), + /* GPP_J */ + PINCTRL_PIN(166, "CPUPWRGD"), + PINCTRL_PIN(167, "CPU_THRMTRIP_N"), + PINCTRL_PIN(168, "PLTRST_CPUB"), + PINCTRL_PIN(169, "TRIGGER0_N"), + PINCTRL_PIN(170, "TRIGGER1_N"), + PINCTRL_PIN(171, "CPU_PWR_DEBUG_N"), + PINCTRL_PIN(172, "CPU_MEMTRIP_N"), + PINCTRL_PIN(173, "CPU_MSMI_N"), + PINCTRL_PIN(174, "ME_PECI"), + PINCTRL_PIN(175, "NAC_SPARE0"), + PINCTRL_PIN(176, "NAC_SPARE1"), + PINCTRL_PIN(177, "NAC_SPARE2"), + PINCTRL_PIN(178, "CPU_ERR0_N"), + PINCTRL_PIN(179, "CPU_CATERR_N"), + PINCTRL_PIN(180, "CPU_ERR1_N"), + PINCTRL_PIN(181, "CPU_ERR2_N"), + PINCTRL_PIN(182, "GPP_J_16"), + PINCTRL_PIN(183, "GPP_J_17"), + /* GPP_I */ + PINCTRL_PIN(184, "GBE_GPIO4"), + PINCTRL_PIN(185, "GBE_GPIO5"), + PINCTRL_PIN(186, "GBE_GPIO6"), + PINCTRL_PIN(187, "GBE_GPIO7"), + PINCTRL_PIN(188, "GBE1_LED1"), + PINCTRL_PIN(189, "GBE1_LED2"), + PINCTRL_PIN(190, "GBE2_LED0"), + PINCTRL_PIN(191, "GBE2_LED1"), + PINCTRL_PIN(192, "GBE2_LED2"), + PINCTRL_PIN(193, "GBE3_LED0"), + PINCTRL_PIN(194, "GBE3_LED1"), + PINCTRL_PIN(195, "GBE3_LED2"), + PINCTRL_PIN(196, "GBE0_I2C_CLK"), + PINCTRL_PIN(197, "GBE0_I2C_DATA"), + PINCTRL_PIN(198, "GBE1_I2C_CLK"), + PINCTRL_PIN(199, "GBE1_I2C_DATA"), + PINCTRL_PIN(200, "GBE2_I2C_CLK"), + PINCTRL_PIN(201, "GBE2_I2C_DATA"), + PINCTRL_PIN(202, "GBE3_I2C_CLK"), + PINCTRL_PIN(203, "GBE3_I2C_DATA"), + PINCTRL_PIN(204, "GBE4_I2C_CLK"), + PINCTRL_PIN(205, "GBE4_I2C_DATA"), + PINCTRL_PIN(206, "GBE_GPIO8"), + PINCTRL_PIN(207, "GBE_GPIO9"), + /* GPP_L */ + PINCTRL_PIN(208, "PM_SYNC_0"), + PINCTRL_PIN(209, "PM_DOWN_0"), + PINCTRL_PIN(210, "PM_SYNC_CLK_0"), + PINCTRL_PIN(211, "GPP_L_3"), + PINCTRL_PIN(212, "GPP_L_4"), + PINCTRL_PIN(213, "GPP_L_5"), + PINCTRL_PIN(214, "GPP_L_6"), + PINCTRL_PIN(215, "GPP_L_7"), + PINCTRL_PIN(216, "GPP_L_8"), + PINCTRL_PIN(217, "NAC_GBE_GPIO0_S2N"), + PINCTRL_PIN(218, "NAC_GBE_GPIO1_S2N"), + PINCTRL_PIN(219, "NAC_GBE_GPIO2_S2N"), + PINCTRL_PIN(220, "NAC_GBE_GPIO3_S2N"), + PINCTRL_PIN(221, "NAC_GBE_SMB_DATA_IN"), + PINCTRL_PIN(222, "NAC_GBE_SMB_DATA_OUT"), + PINCTRL_PIN(223, "NAC_GBE_SMB_ALRT_N"), + PINCTRL_PIN(224, "NAC_GBE_SMB_CLK_IN"), + PINCTRL_PIN(225, "NAC_GBE_SMB_CLK_OUT"), + /* GPP_M */ + PINCTRL_PIN(226, "GPP_M_0"), + PINCTRL_PIN(227, "GPP_M_1"), + PINCTRL_PIN(228, "GPP_M_2"), + PINCTRL_PIN(229, "GPP_M_3"), + PINCTRL_PIN(230, "NAC_WAKE_N"), + PINCTRL_PIN(231, "GPP_M_5"), + PINCTRL_PIN(232, "GPP_M_6"), + PINCTRL_PIN(233, "GPP_M_7"), + PINCTRL_PIN(234, "GPP_M_8"), + PINCTRL_PIN(235, "NAC_SBLINK_S2N"), + PINCTRL_PIN(236, "NAC_SBLINK_N2S"), + PINCTRL_PIN(237, "NAC_SBLINK_CLK_N2S"), + PINCTRL_PIN(238, "NAC_SBLINK_CLK_S2N"), + PINCTRL_PIN(239, "NAC_XTAL_VALID"), + PINCTRL_PIN(240, "NAC_RESET_NAC_N"), + PINCTRL_PIN(241, "GPP_M_15"), + PINCTRL_PIN(242, "GPP_M_16"), + PINCTRL_PIN(243, "GPP_M_17"), + /* GPP_N */ + PINCTRL_PIN(244, "GPP_N_0"), + PINCTRL_PIN(245, "NAC_NCSI_TXD0"), + PINCTRL_PIN(246, "GPP_N_2"), + PINCTRL_PIN(247, "GPP_N_3"), + PINCTRL_PIN(248, "NAC_NCSI_REFCLK_IN"), + PINCTRL_PIN(249, "GPP_N_5"), + PINCTRL_PIN(250, "GPP_N_6"), + PINCTRL_PIN(251, "GPP_N_7"), + PINCTRL_PIN(252, "NAC_NCSI_RXD0"), + PINCTRL_PIN(253, "NAC_NCSI_RXD1"), + PINCTRL_PIN(254, "NAC_NCSI_CRS_DV"), + PINCTRL_PIN(255, "NAC_NCSI_CLK_IN"), + PINCTRL_PIN(256, "NAC_NCSI_REFCLK_OUT"), + PINCTRL_PIN(257, "NAC_NCSI_TX_EN"), + PINCTRL_PIN(258, "NAC_NCSI_TXD1"), + PINCTRL_PIN(259, "NAC_NCSI_OE_N"), + PINCTRL_PIN(260, "NAC_GR_N"), + PINCTRL_PIN(261, "NAC_INIT_SX_WAKE_N"), +}; + +static const struct intel_padgroup ebg_community0_gpps[] = { + EBG_GPP(0, 0, 20), /* GPP_A */ + EBG_GPP(1, 21, 44), /* GPP_B */ + EBG_GPP(2, 45, 65), /* SPI */ +}; + +static const struct intel_padgroup ebg_community1_gpps[] = { + EBG_GPP(0, 66, 87), /* GPP_C */ + EBG_GPP(1, 88, 111), /* GPP_D */ +}; + +static const struct intel_padgroup ebg_community3_gpps[] = { + EBG_GPP(0, 112, 135), /* GPP_E */ + EBG_GPP(1, 136, 145), /* JTAG */ +}; + +static const struct intel_padgroup ebg_community4_gpps[] = { + EBG_GPP(0, 146, 165), /* GPP_H */ + EBG_GPP(1, 166, 183), /* GPP_J */ +}; + +static const struct intel_padgroup ebg_community5_gpps[] = { + EBG_GPP(0, 184, 207), /* GPP_I */ + EBG_GPP(1, 208, 225), /* GPP_L */ + EBG_GPP(2, 226, 243), /* GPP_M */ + EBG_GPP(3, 244, 261), /* GPP_N */ +}; + +static const struct intel_community ebg_communities[] = { + EBG_COMMUNITY(0, 0, 65, ebg_community0_gpps), + EBG_COMMUNITY(1, 66, 111, ebg_community1_gpps), + EBG_COMMUNITY(2, 112, 145, ebg_community3_gpps), + EBG_COMMUNITY(3, 146, 183, ebg_community4_gpps), + EBG_COMMUNITY(4, 184, 261, ebg_community5_gpps), +}; + +static const struct intel_pinctrl_soc_data ebg_soc_data = { + .pins = ebg_pins, + .npins = ARRAY_SIZE(ebg_pins), + .communities = ebg_communities, + .ncommunities = ARRAY_SIZE(ebg_communities), +}; + +static const struct acpi_device_id ebg_pinctrl_acpi_match[] = { + { "INTC1071", (kernel_ulong_t)&ebg_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, ebg_pinctrl_acpi_match); + +static INTEL_PINCTRL_PM_OPS(ebg_pinctrl_pm_ops); + +static struct platform_driver ebg_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "emmitsburg-pinctrl", + .acpi_match_table = ebg_pinctrl_acpi_match, + .pm = &ebg_pinctrl_pm_ops, + }, +}; + +module_platform_driver(ebg_pinctrl_driver); + +MODULE_AUTHOR("Andy Shevchenko "); +MODULE_DESCRIPTION("Intel Emmitsburg PCH pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2");