From 539d8bde72c22d760013bf81436d6bb94eb67aed Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 24 Oct 2019 17:33:42 +0300 Subject: [PATCH 01/41] pinctrl: baytrail: Allocate IRQ chip dynamic Keeping the IRQ chip definition static shares it with multiple instances of the GPIO chip in the system. This is bad and now we get this warning from GPIO library: "detected irqchip that is shared with multiple gpiochips: please fix the driver." Hence, move the IRQ chip definition from being driver static into the struct intel_pinctrl. So a unique IRQ chip is used for each GPIO chip instance. Fixes: 9f573b98ca50 ("pinctrl: baytrail: Update irq chip operations") Depends-on: ca8a958e2acb ("pinctrl: baytrail: Pass irqchip when adding gpiochip") Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-baytrail.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 55141d5de29e..72ffd19448e5 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -107,6 +107,7 @@ struct byt_gpio_pin_context { struct byt_gpio { struct gpio_chip chip; + struct irq_chip irqchip; struct platform_device *pdev; struct pinctrl_dev *pctl_dev; struct pinctrl_desc pctl_desc; @@ -1395,15 +1396,6 @@ static int byt_irq_type(struct irq_data *d, unsigned int type) return 0; } -static struct irq_chip byt_irqchip = { - .name = "BYT-GPIO", - .irq_ack = byt_irq_ack, - .irq_mask = byt_irq_mask, - .irq_unmask = byt_irq_unmask, - .irq_set_type = byt_irq_type, - .flags = IRQCHIP_SKIP_SET_WAKE, -}; - static void byt_gpio_irq_handler(struct irq_desc *desc) { struct irq_data *data = irq_desc_get_irq_data(desc); @@ -1551,8 +1543,15 @@ static int byt_gpio_probe(struct byt_gpio *vg) if (irq_rc && irq_rc->start) { struct gpio_irq_chip *girq; + vg->irqchip.name = "BYT-GPIO", + vg->irqchip.irq_ack = byt_irq_ack, + vg->irqchip.irq_mask = byt_irq_mask, + vg->irqchip.irq_unmask = byt_irq_unmask, + vg->irqchip.irq_set_type = byt_irq_type, + vg->irqchip.flags = IRQCHIP_SKIP_SET_WAKE, + girq = &gc->irq; - girq->chip = &byt_irqchip; + girq->chip = &vg->irqchip; girq->init_hw = byt_gpio_irq_init_hw; girq->parent_handler = byt_gpio_irq_handler; girq->num_parents = 1; From ab68b220e81fd03383c0d9e1a87b51f9bbe4db77 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 24 Oct 2019 17:33:43 +0300 Subject: [PATCH 02/41] pinctrl: baytrail: Group GPIO IRQ chip initialization After commit 5ea422750a9f ("pinctrl: baytrail: Pass irqchip when adding gpiochip") the GPIO IRQ chip structure is being initialized under conditional when IRQ resource has been discovered. But that commit left aside the assignment of ->init_valid_mask() callback that is done unconditionally. For sake of consistency and preventing some garbage in GPIO IRQ chip structure group initialization together. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-baytrail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 72ffd19448e5..d829843314ba 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1529,7 +1529,6 @@ static int byt_gpio_probe(struct byt_gpio *vg) gc->add_pin_ranges = byt_gpio_add_pin_ranges; gc->parent = &vg->pdev->dev; gc->ngpio = vg->soc_data->npins; - gc->irq.init_valid_mask = byt_init_irq_valid_mask; #ifdef CONFIG_PM_SLEEP vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio, @@ -1553,6 +1552,7 @@ static int byt_gpio_probe(struct byt_gpio *vg) girq = &gc->irq; girq->chip = &vg->irqchip; girq->init_hw = byt_gpio_irq_init_hw; + girq->init_valid_mask = byt_init_irq_valid_mask; girq->parent_handler = byt_gpio_irq_handler; girq->num_parents = 1; girq->parents = devm_kcalloc(&vg->pdev->dev, girq->num_parents, From e70982b3abec4fb6e2ce9489f071080ca84e4bc7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 5 Nov 2019 16:23:24 +0200 Subject: [PATCH 03/41] pinctrl: baytrail: Move IRQ valid mask initialization to a dedicated callback There is a logical continuation of the commit 5fbe5b5883f8 ("gpio: Initialize the irqchip valid_mask with a callback") to split IRQ initialization to hardware and valid mask setup parts. Acked-by: Hans de Goede Acked-by: Mika Westerberg Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-baytrail.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index d829843314ba..ea61a19857c1 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1432,23 +1432,11 @@ static void byt_gpio_irq_handler(struct irq_desc *desc) static void byt_init_irq_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask, unsigned int ngpios) -{ - /* - * FIXME: currently the valid_mask is filled in as part of - * initializing the irq_chip below in byt_gpio_irq_init_hw(). - * when converting this driver to the new way of passing the - * gpio_irq_chip along when adding the gpio_chip, move the - * mask initialization into this callback instead. Right now - * this callback is here to make sure the mask gets allocated. - */ -} - -static int byt_gpio_irq_init_hw(struct gpio_chip *chip) { struct byt_gpio *vg = gpiochip_get_data(chip); struct device *dev = &vg->pdev->dev; void __iomem *reg; - u32 base, value; + u32 value; int i; /* @@ -1469,13 +1457,20 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip) value = readl(reg); if (value & BYT_DIRECT_IRQ_EN) { - clear_bit(i, chip->irq.valid_mask); + clear_bit(i, valid_mask); dev_dbg(dev, "excluding GPIO %d from IRQ domain\n", i); } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) { byt_gpio_clear_triggering(vg, i); dev_dbg(dev, "disabling GPIO %d\n", i); } } +} + +static int byt_gpio_irq_init_hw(struct gpio_chip *chip) +{ + struct byt_gpio *vg = gpiochip_get_data(chip); + void __iomem *reg; + u32 base, value; /* clear interrupt status trigger registers */ for (base = 0; base < vg->soc_data->npins; base += 32) { From faf86c0c572ad134003a5f5895a42a4749dae5f3 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Thu, 12 Dec 2019 08:35:52 +0200 Subject: [PATCH 04/41] pinctrl: baytrail: Use GPIO direction definitions Use new GPIO_LINE_DIRECTION_IN and GPIO_LINE_DIRECTION_OUT when returning GPIO direction to GPIO framework. Signed-off-by: Matti Vaittinen Acked-by: Andy Shevchenko Acked-by: Mika Westerberg 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 ea61a19857c1..0e131d2e094d 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1162,9 +1162,9 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) raw_spin_unlock_irqrestore(&byt_lock, flags); if (!(value & BYT_OUTPUT_EN)) - return 0; + return GPIO_LINE_DIRECTION_OUT; if (!(value & BYT_INPUT_EN)) - return 1; + return GPIO_LINE_DIRECTION_IN; return -EINVAL; } From 90a1eb18503d916ca5b089ef79d783c6dc6a5836 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Thu, 12 Dec 2019 08:35:19 +0200 Subject: [PATCH 05/41] pinctrl: cherryview: Use GPIO direction definitions Use new GPIO_LINE_DIRECTION_IN and GPIO_LINE_DIRECTION_OUT when returning GPIO direction to GPIO framework. Signed-off-by: Matti Vaittinen Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-cherryview.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 60527b93a711..4c74fdde576d 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1289,7 +1289,10 @@ static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT; - return direction != CHV_PADCTRL0_GPIOCFG_GPO; + if (direction == CHV_PADCTRL0_GPIOCFG_GPO) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; } static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) From 6a304752eb6934e4bfa236a346ae440c74e02e07 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Thu, 12 Dec 2019 08:34:32 +0200 Subject: [PATCH 06/41] pinctrl: intel: Use GPIO direction definitions Use new GPIO_LINE_DIRECTION_IN and GPIO_LINE_DIRECTION_OUT when returning GPIO direction to GPIO framework. Signed-off-by: Matti Vaittinen Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 4860bc9a4e48..2ba2ad8a55d9 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -944,7 +944,10 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) if (padcfg0 & PADCFG0_PMODE_MASK) return -EINVAL; - return !!(padcfg0 & PADCFG0_GPIOTXDIS); + if (padcfg0 & PADCFG0_GPIOTXDIS) + return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_OUT; } static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) From 66c812d22ecdca74015477429a271697655dbfd4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 25 Oct 2019 12:10:28 +0300 Subject: [PATCH 07/41] pinctrl: intel: Share struct intel_pinctrl for wider use There are few drivers for Intel SoC GPIO which may utilize the same data structure to describe this IP. Share struct intel_pinctrl for wider user. Acked-by: Hans de Goede Acked-by: Mika Westerberg Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-intel.c | 35 +-------------------- drivers/pinctrl/intel/pinctrl-intel.h | 44 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 2ba2ad8a55d9..06be75a636ba 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -8,8 +8,8 @@ */ #include -#include #include +#include #include #include #include @@ -85,39 +85,6 @@ struct intel_community_context { u32 *hostown; }; -struct intel_pinctrl_context { - struct intel_pad_context *pads; - struct intel_community_context *communities; -}; - -/** - * struct intel_pinctrl - Intel pinctrl private structure - * @dev: Pointer to the device structure - * @lock: Lock to serialize register access - * @pctldesc: Pin controller description - * @pctldev: Pointer to the pin controller device - * @chip: GPIO chip in this pin controller - * @irqchip: IRQ chip in this pin controller - * @soc: SoC/PCH 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: pinctrl/GPIO chip irq number - */ -struct intel_pinctrl { - struct device *dev; - raw_spinlock_t lock; - struct pinctrl_desc pctldesc; - struct pinctrl_dev *pctldev; - struct gpio_chip chip; - struct irq_chip irqchip; - const struct intel_pinctrl_soc_data *soc; - struct intel_community *communities; - size_t ncommunities; - struct intel_pinctrl_context context; - int irq; -}; - #define pin_to_padno(c, p) ((p) - (c)->pin_base) #define padgroup_offset(g, p) ((p) - (g)->base) diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index 34b38a321760..c6f066f6d3fb 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -10,7 +10,10 @@ #ifndef PINCTRL_INTEL_H #define PINCTRL_INTEL_H +#include +#include #include +#include struct pinctrl_pin_desc; struct platform_device; @@ -174,6 +177,47 @@ struct intel_pinctrl_soc_data { size_t ncommunities; }; +struct intel_pad_context; +struct intel_community_context; + +/** + * struct intel_pinctrl_context - context to be saved during suspend-resume + * @pads: Opaque context per pad (driver dependent) + * @communities: Opaque context per community (driver dependent) + */ +struct intel_pinctrl_context { + struct intel_pad_context *pads; + struct intel_community_context *communities; +}; + +/** + * struct intel_pinctrl - Intel pinctrl private structure + * @dev: Pointer to the device structure + * @lock: Lock to serialize register access + * @pctldesc: Pin controller description + * @pctldev: Pointer to the pin controller device + * @chip: GPIO chip in this pin controller + * @irqchip: IRQ chip in this pin controller + * @soc: SoC/PCH 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: pinctrl/GPIO chip irq number + */ +struct intel_pinctrl { + struct device *dev; + raw_spinlock_t lock; + struct pinctrl_desc pctldesc; + struct pinctrl_dev *pctldev; + struct gpio_chip chip; + struct irq_chip irqchip; + const struct intel_pinctrl_soc_data *soc; + struct intel_community *communities; + size_t ncommunities; + struct intel_pinctrl_context context; + int irq; +}; + int intel_pinctrl_probe_by_hid(struct platform_device *pdev); int intel_pinctrl_probe_by_uid(struct platform_device *pdev); From 990ec243cb77c682e12bb84c98906880536132aa Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 17:56:41 +0200 Subject: [PATCH 08/41] pinctrl: baytrail: Keep pointer to struct device instead of its container There is no need to keep pointer to struct platform_device, which is container of struct device, because the latter is what have been used everywhere outside of ->probe() path. In any case we may derive pointer to the container when needed. Acked-by: Hans de Goede Acked-by: Mika Westerberg Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-baytrail.c | 58 ++++++++++++------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 0e131d2e094d..6e79138fc7f5 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -106,9 +106,9 @@ struct byt_gpio_pin_context { } struct byt_gpio { + struct device *dev; struct gpio_chip chip; struct irq_chip irqchip; - struct platform_device *pdev; struct pinctrl_dev *pctl_dev; struct pinctrl_desc pctl_desc; const struct intel_pinctrl_soc_data *soc_data; @@ -668,7 +668,7 @@ static void byt_set_group_simple_mux(struct byt_gpio *vg, padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); if (!padcfg0) { - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "Group %s, pin %i not muxed (no padcfg0)\n", group.name, i); continue; @@ -698,7 +698,7 @@ static void byt_set_group_mixed_mux(struct byt_gpio *vg, padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); if (!padcfg0) { - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "Group %s, pin %i not muxed (no padcfg0)\n", group.name, i); continue; @@ -785,13 +785,12 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, value |= gpio_mux; writel(value, reg); - dev_warn(&vg->pdev->dev, FW_BUG - "pin %u forcibly re-configured as GPIO\n", offset); + dev_warn(vg->dev, FW_BUG "pin %u forcibly re-configured as GPIO\n", offset); } raw_spin_unlock_irqrestore(&byt_lock, flags); - pm_runtime_get(&vg->pdev->dev); + pm_runtime_get(vg->dev); return 0; } @@ -803,7 +802,7 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); byt_gpio_clear_triggering(vg, offset); - pm_runtime_put(&vg->pdev->dev); + pm_runtime_put(vg->dev); } static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, @@ -1013,7 +1012,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, if (val & BYT_INPUT_EN) { val &= ~BYT_INPUT_EN; writel(val, val_reg); - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "pin %u forcibly set to input mode\n", offset); } @@ -1035,7 +1034,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, if (val & BYT_INPUT_EN) { val &= ~BYT_INPUT_EN; writel(val, val_reg); - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "pin %u forcibly set to input mode\n", offset); } @@ -1412,7 +1411,7 @@ static void byt_gpio_irq_handler(struct irq_desc *desc) reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); if (!reg) { - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "Pin %i: could not retrieve interrupt status register\n", base); continue; @@ -1434,7 +1433,6 @@ static void byt_init_irq_valid_mask(struct gpio_chip *chip, unsigned int ngpios) { struct byt_gpio *vg = gpiochip_get_data(chip); - struct device *dev = &vg->pdev->dev; void __iomem *reg; u32 value; int i; @@ -1449,7 +1447,7 @@ static void byt_init_irq_valid_mask(struct gpio_chip *chip, reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); if (!reg) { - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "Pin %i: could not retrieve conf0 register\n", i); continue; @@ -1458,10 +1456,10 @@ static void byt_init_irq_valid_mask(struct gpio_chip *chip, value = readl(reg); if (value & BYT_DIRECT_IRQ_EN) { clear_bit(i, valid_mask); - dev_dbg(dev, "excluding GPIO %d from IRQ domain\n", i); + dev_dbg(vg->dev, "excluding GPIO %d from IRQ domain\n", i); } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) { byt_gpio_clear_triggering(vg, i); - dev_dbg(dev, "disabling GPIO %d\n", i); + dev_dbg(vg->dev, "disabling GPIO %d\n", i); } } } @@ -1477,7 +1475,7 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip) reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); if (!reg) { - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "Pin %i: could not retrieve irq status reg\n", base); continue; @@ -1488,7 +1486,7 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip) might be misconfigured in bios */ value = readl(reg); if (value) - dev_err(&vg->pdev->dev, + dev_err(vg->dev, "GPIO interrupt error, pins misconfigured. INT_STAT%u: 0x%08x\n", base / 32, value); } @@ -1499,7 +1497,7 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip) static int byt_gpio_add_pin_ranges(struct gpio_chip *chip) { struct byt_gpio *vg = gpiochip_get_data(chip); - struct device *dev = &vg->pdev->dev; + struct device *dev = vg->dev; int ret; ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc_data->npins); @@ -1511,6 +1509,7 @@ static int byt_gpio_add_pin_ranges(struct gpio_chip *chip) static int byt_gpio_probe(struct byt_gpio *vg) { + struct platform_device *pdev = to_platform_device(vg->dev); struct gpio_chip *gc; struct resource *irq_rc; int ret; @@ -1518,22 +1517,22 @@ static int byt_gpio_probe(struct byt_gpio *vg) /* Set up gpio chip */ vg->chip = byt_gpio_chip; gc = &vg->chip; - gc->label = dev_name(&vg->pdev->dev); + gc->label = dev_name(vg->dev); gc->base = -1; gc->can_sleep = false; gc->add_pin_ranges = byt_gpio_add_pin_ranges; - gc->parent = &vg->pdev->dev; + gc->parent = vg->dev; gc->ngpio = vg->soc_data->npins; #ifdef CONFIG_PM_SLEEP - vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio, + vg->saved_context = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->saved_context), GFP_KERNEL); if (!vg->saved_context) return -ENOMEM; #endif /* set up interrupts */ - irq_rc = platform_get_resource(vg->pdev, IORESOURCE_IRQ, 0); + irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (irq_rc && irq_rc->start) { struct gpio_irq_chip *girq; @@ -1550,7 +1549,7 @@ static int byt_gpio_probe(struct byt_gpio *vg) girq->init_valid_mask = byt_init_irq_valid_mask; girq->parent_handler = byt_gpio_irq_handler; girq->num_parents = 1; - girq->parents = devm_kcalloc(&vg->pdev->dev, girq->num_parents, + girq->parents = devm_kcalloc(vg->dev, girq->num_parents, sizeof(*girq->parents), GFP_KERNEL); if (!girq->parents) return -ENOMEM; @@ -1559,9 +1558,9 @@ static int byt_gpio_probe(struct byt_gpio *vg) girq->handler = handle_bad_irq; } - ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg); + ret = devm_gpiochip_add_data(vg->dev, gc, vg); if (ret) { - dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n"); + dev_err(vg->dev, "failed adding byt-gpio chip\n"); return ret; } @@ -1571,10 +1570,11 @@ static int byt_gpio_probe(struct byt_gpio *vg) static int byt_set_soc_data(struct byt_gpio *vg, const struct intel_pinctrl_soc_data *soc_data) { + struct platform_device *pdev = to_platform_device(vg->dev); int i; vg->soc_data = soc_data; - vg->communities_copy = devm_kcalloc(&vg->pdev->dev, + vg->communities_copy = devm_kcalloc(vg->dev, soc_data->ncommunities, sizeof(*vg->communities_copy), GFP_KERNEL); @@ -1586,7 +1586,7 @@ static int byt_set_soc_data(struct byt_gpio *vg, *comm = vg->soc_data->communities[i]; - comm->pad_regs = devm_platform_ioremap_resource(vg->pdev, 0); + comm->pad_regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(comm->pad_regs)) return PTR_ERR(comm->pad_regs); } @@ -1628,7 +1628,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev) if (!vg) return -ENOMEM; - vg->pdev = pdev; + vg->dev = &pdev->dev; ret = byt_set_soc_data(vg, soc_data); if (ret) { dev_err(&pdev->dev, "failed to set soc data\n"); @@ -1672,7 +1672,7 @@ static int byt_gpio_suspend(struct device *dev) reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); if (!reg) { - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "Pin %i: could not retrieve conf0 register\n", i); continue; @@ -1704,7 +1704,7 @@ static int byt_gpio_resume(struct device *dev) reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); if (!reg) { - dev_warn(&vg->pdev->dev, + dev_warn(vg->dev, "Pin %i: could not retrieve conf0 register\n", i); continue; From 2c02af709bff42e7a85e25c7ba8af7c55f034f27 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 18:34:43 +0200 Subject: [PATCH 09/41] pinctrl: baytrail: Use local variable to keep device pointer Use local variable to keep device pointer in order to increase readability of the driver. Acked-by: Hans de Goede Acked-by: Mika Westerberg Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-baytrail.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 6e79138fc7f5..f6c9132b3b14 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1604,15 +1604,16 @@ static int byt_pinctrl_probe(struct platform_device *pdev) { const struct intel_pinctrl_soc_data *soc_data = NULL; const struct intel_pinctrl_soc_data **soc_table; + struct device *dev = &pdev->dev; struct acpi_device *acpi_dev; struct byt_gpio *vg; int i, ret; - acpi_dev = ACPI_COMPANION(&pdev->dev); + acpi_dev = ACPI_COMPANION(dev); if (!acpi_dev) return -ENODEV; - soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(&pdev->dev); + soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(dev); for (i = 0; soc_table[i]; i++) { if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) { @@ -1624,25 +1625,25 @@ static int byt_pinctrl_probe(struct platform_device *pdev) if (!soc_data) return -ENODEV; - vg = devm_kzalloc(&pdev->dev, sizeof(*vg), GFP_KERNEL); + vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL); if (!vg) return -ENOMEM; - vg->dev = &pdev->dev; + vg->dev = dev; ret = byt_set_soc_data(vg, soc_data); if (ret) { - dev_err(&pdev->dev, "failed to set soc data\n"); + dev_err(dev, "failed to set soc data\n"); return ret; } vg->pctl_desc = byt_pinctrl_desc; - vg->pctl_desc.name = dev_name(&pdev->dev); + vg->pctl_desc.name = dev_name(dev); vg->pctl_desc.pins = vg->soc_data->pins; vg->pctl_desc.npins = vg->soc_data->npins; - vg->pctl_dev = devm_pinctrl_register(&pdev->dev, &vg->pctl_desc, vg); + vg->pctl_dev = devm_pinctrl_register(dev, &vg->pctl_desc, vg); if (IS_ERR(vg->pctl_dev)) { - dev_err(&pdev->dev, "failed to register pinctrl driver\n"); + dev_err(dev, "failed to register pinctrl driver\n"); return PTR_ERR(vg->pctl_dev); } @@ -1651,7 +1652,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev) return ret; platform_set_drvdata(pdev, vg); - pm_runtime_enable(&pdev->dev); + pm_runtime_enable(dev); return 0; } From 5d33e0eb7ffa2a4f4c431af1deca49f433faba8a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 18:37:22 +0200 Subject: [PATCH 10/41] pinctrl: baytrail: Reuse struct intel_pinctrl in the driver We may use now available struct intel_pinctrl in the driver. No functional change implied. Acked-by: Hans de Goede Acked-by: Mika Westerberg Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-baytrail.c | 186 +++++++++++------------ 1 file changed, 87 insertions(+), 99 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index f6c9132b3b14..cb0c04c5269c 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -93,7 +93,7 @@ #define BYT_DEFAULT_GPIO_MUX 0 #define BYT_ALTER_GPIO_MUX 1 -struct byt_gpio_pin_context { +struct intel_pad_context { u32 conf0; u32 val; }; @@ -105,17 +105,6 @@ struct byt_gpio_pin_context { .pad_map = (map),\ } -struct byt_gpio { - struct device *dev; - struct gpio_chip chip; - struct irq_chip irqchip; - struct pinctrl_dev *pctl_dev; - struct pinctrl_desc pctl_desc; - const struct intel_pinctrl_soc_data *soc_data; - struct intel_community *communities_copy; - struct byt_gpio_pin_context *saved_context; -}; - /* SCORE pins, aka GPIOC_ or GPIO_S0_SC[] */ static const struct pinctrl_pin_desc byt_score_pins[] = { PINCTRL_PIN(0, "SATA_GP0"), @@ -551,14 +540,14 @@ static const struct intel_pinctrl_soc_data *byt_soc_data[] = { static DEFINE_RAW_SPINLOCK(byt_lock); -static struct intel_community *byt_get_community(struct byt_gpio *vg, +static struct intel_community *byt_get_community(struct intel_pinctrl *vg, unsigned int pin) { struct intel_community *comm; int i; - for (i = 0; i < vg->soc_data->ncommunities; i++) { - comm = vg->communities_copy + i; + for (i = 0; i < vg->ncommunities; i++) { + comm = vg->communities + i; if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) return comm; } @@ -566,7 +555,7 @@ static struct intel_community *byt_get_community(struct byt_gpio *vg, return NULL; } -static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, +static void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset, int reg) { struct intel_community *comm = byt_get_community(vg, offset); @@ -593,17 +582,17 @@ static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, static int byt_get_groups_count(struct pinctrl_dev *pctldev) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - return vg->soc_data->ngroups; + return vg->soc->ngroups; } static const char *byt_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - return vg->soc_data->groups[selector].name; + return vg->soc->groups[selector].name; } static int byt_get_group_pins(struct pinctrl_dev *pctldev, @@ -611,10 +600,10 @@ static int byt_get_group_pins(struct pinctrl_dev *pctldev, const unsigned int **pins, unsigned int *num_pins) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - *pins = vg->soc_data->groups[selector].pins; - *num_pins = vg->soc_data->groups[selector].npins; + *pins = vg->soc->groups[selector].pins; + *num_pins = vg->soc->groups[selector].npins; return 0; } @@ -627,17 +616,17 @@ static const struct pinctrl_ops byt_pinctrl_ops = { static int byt_get_functions_count(struct pinctrl_dev *pctldev) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - return vg->soc_data->nfunctions; + return vg->soc->nfunctions; } static const char *byt_get_function_name(struct pinctrl_dev *pctldev, unsigned int selector) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - return vg->soc_data->functions[selector].name; + return vg->soc->functions[selector].name; } static int byt_get_function_groups(struct pinctrl_dev *pctldev, @@ -645,15 +634,15 @@ static int byt_get_function_groups(struct pinctrl_dev *pctldev, const char * const **groups, unsigned int *num_groups) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); - *groups = vg->soc_data->functions[selector].groups; - *num_groups = vg->soc_data->functions[selector].ngroups; + *groups = vg->soc->functions[selector].groups; + *num_groups = vg->soc->functions[selector].ngroups; return 0; } -static void byt_set_group_simple_mux(struct byt_gpio *vg, +static void byt_set_group_simple_mux(struct intel_pinctrl *vg, const struct intel_pingroup group, unsigned int func) { @@ -683,7 +672,7 @@ static void byt_set_group_simple_mux(struct byt_gpio *vg, raw_spin_unlock_irqrestore(&byt_lock, flags); } -static void byt_set_group_mixed_mux(struct byt_gpio *vg, +static void byt_set_group_mixed_mux(struct intel_pinctrl *vg, const struct intel_pingroup group, const unsigned int *func) { @@ -716,9 +705,9 @@ static void byt_set_group_mixed_mux(struct byt_gpio *vg, static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, unsigned int group_selector) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); - const struct intel_function func = vg->soc_data->functions[func_selector]; - const struct intel_pingroup group = vg->soc_data->groups[group_selector]; + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); + const struct intel_function func = vg->soc->functions[func_selector]; + const struct intel_pingroup group = vg->soc->groups[group_selector]; if (group.modes) byt_set_group_mixed_mux(vg, group, group.modes); @@ -730,22 +719,22 @@ static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, return 0; } -static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned int offset) +static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset) { /* SCORE pin 92-93 */ - if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) && + if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) && offset >= 92 && offset <= 93) return BYT_ALTER_GPIO_MUX; /* SUS pin 11-21 */ - if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) && + if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) && offset >= 11 && offset <= 21) return BYT_ALTER_GPIO_MUX; return BYT_DEFAULT_GPIO_MUX; } -static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset) +static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset) { void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); unsigned long flags; @@ -762,7 +751,7 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, struct pinctrl_gpio_range *range, unsigned int offset) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); u32 value, gpio_mux; unsigned long flags; @@ -799,7 +788,7 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, struct pinctrl_gpio_range *range, unsigned int offset) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); byt_gpio_clear_triggering(vg, offset); pm_runtime_put(vg->dev); @@ -810,7 +799,7 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, unsigned int offset, bool input) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(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; @@ -893,7 +882,7 @@ static int byt_set_pull_strength(u32 *reg, u16 strength) static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, unsigned long *config) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); enum pin_config_param param = pinconf_to_config_param(*config); void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); @@ -978,7 +967,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, unsigned long *configs, unsigned int num_configs) { - struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); unsigned int param, arg; void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); @@ -1115,7 +1104,7 @@ static const struct pinctrl_desc byt_pinctrl_desc = { static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; u32 val; @@ -1129,7 +1118,7 @@ static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset) static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; u32 old_val; @@ -1148,7 +1137,7 @@ static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); unsigned long flags; u32 value; @@ -1188,11 +1177,11 @@ static int byt_gpio_direction_output(struct gpio_chip *chip, static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); int i; u32 conf0, val; - for (i = 0; i < vg->soc_data->npins; i++) { + for (i = 0; i < vg->soc->npins; i++) { const struct intel_community *comm; const char *pull_str = NULL; const char *pull = NULL; @@ -1202,7 +1191,7 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) unsigned int pin; raw_spin_lock_irqsave(&byt_lock, flags); - pin = vg->soc_data->pins[i].number; + pin = vg->soc->pins[i].number; reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); if (!reg) { seq_printf(s, @@ -1297,7 +1286,7 @@ static const struct gpio_chip byt_gpio_chip = { static void byt_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct byt_gpio *vg = gpiochip_get_data(gc); + struct intel_pinctrl *vg = gpiochip_get_data(gc); unsigned int offset = irqd_to_hwirq(d); void __iomem *reg; @@ -1313,7 +1302,7 @@ static void byt_irq_ack(struct irq_data *d) static void byt_irq_mask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct byt_gpio *vg = gpiochip_get_data(gc); + struct intel_pinctrl *vg = gpiochip_get_data(gc); byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); } @@ -1321,7 +1310,7 @@ static void byt_irq_mask(struct irq_data *d) static void byt_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct byt_gpio *vg = gpiochip_get_data(gc); + struct intel_pinctrl *vg = gpiochip_get_data(gc); unsigned int offset = irqd_to_hwirq(d); unsigned long flags; void __iomem *reg; @@ -1359,7 +1348,7 @@ static void byt_irq_unmask(struct irq_data *d) static int byt_irq_type(struct irq_data *d, unsigned int type) { - struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); + struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); u32 offset = irqd_to_hwirq(d); u32 value; unsigned long flags; @@ -1398,8 +1387,7 @@ static int byt_irq_type(struct irq_data *d, unsigned int type) static void byt_gpio_irq_handler(struct irq_desc *desc) { struct irq_data *data = irq_desc_get_irq_data(desc); - struct byt_gpio *vg = gpiochip_get_data( - irq_desc_get_handler_data(desc)); + struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc)); struct irq_chip *chip = irq_data_get_irq_chip(data); u32 base, pin; void __iomem *reg; @@ -1432,7 +1420,7 @@ static void byt_init_irq_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask, unsigned int ngpios) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); void __iomem *reg; u32 value; int i; @@ -1442,8 +1430,8 @@ static void byt_init_irq_valid_mask(struct gpio_chip *chip, * do not use direct IRQ mode. This will prevent spurious * interrupts from misconfigured pins. */ - for (i = 0; i < vg->soc_data->npins; i++) { - unsigned int pin = vg->soc_data->pins[i].number; + for (i = 0; i < vg->soc->npins; i++) { + unsigned int pin = vg->soc->pins[i].number; reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); if (!reg) { @@ -1466,12 +1454,12 @@ static void byt_init_irq_valid_mask(struct gpio_chip *chip, static int byt_gpio_irq_init_hw(struct gpio_chip *chip) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); void __iomem *reg; u32 base, value; /* clear interrupt status trigger registers */ - for (base = 0; base < vg->soc_data->npins; base += 32) { + for (base = 0; base < vg->soc->npins; base += 32) { reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); if (!reg) { @@ -1496,18 +1484,18 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip) static int byt_gpio_add_pin_ranges(struct gpio_chip *chip) { - struct byt_gpio *vg = gpiochip_get_data(chip); + struct intel_pinctrl *vg = gpiochip_get_data(chip); struct device *dev = vg->dev; int ret; - ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc_data->npins); + ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins); if (ret) dev_err(dev, "failed to add GPIO pin range\n"); return ret; } -static int byt_gpio_probe(struct byt_gpio *vg) +static int byt_gpio_probe(struct intel_pinctrl *vg) { struct platform_device *pdev = to_platform_device(vg->dev); struct gpio_chip *gc; @@ -1522,12 +1510,12 @@ static int byt_gpio_probe(struct byt_gpio *vg) gc->can_sleep = false; gc->add_pin_ranges = byt_gpio_add_pin_ranges; gc->parent = vg->dev; - gc->ngpio = vg->soc_data->npins; + gc->ngpio = vg->soc->npins; #ifdef CONFIG_PM_SLEEP - vg->saved_context = devm_kcalloc(vg->dev, gc->ngpio, - sizeof(*vg->saved_context), GFP_KERNEL); - if (!vg->saved_context) + vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads), + GFP_KERNEL); + if (!vg->context.pads) return -ENOMEM; #endif @@ -1567,24 +1555,24 @@ static int byt_gpio_probe(struct byt_gpio *vg) return ret; } -static int byt_set_soc_data(struct byt_gpio *vg, - const struct intel_pinctrl_soc_data *soc_data) +static int byt_set_soc_data(struct intel_pinctrl *vg, + const struct intel_pinctrl_soc_data *soc) { struct platform_device *pdev = to_platform_device(vg->dev); int i; - vg->soc_data = soc_data; - vg->communities_copy = devm_kcalloc(vg->dev, - soc_data->ncommunities, - sizeof(*vg->communities_copy), - GFP_KERNEL); - if (!vg->communities_copy) + vg->soc = soc; + + vg->ncommunities = vg->soc->ncommunities; + vg->communities = devm_kcalloc(vg->dev, vg->ncommunities, + sizeof(*vg->communities), GFP_KERNEL); + if (!vg->communities) return -ENOMEM; - for (i = 0; i < soc_data->ncommunities; i++) { - struct intel_community *comm = vg->communities_copy + i; + for (i = 0; i < vg->soc->ncommunities; i++) { + struct intel_community *comm = vg->communities + i; - *comm = vg->soc_data->communities[i]; + *comm = vg->soc->communities[i]; comm->pad_regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(comm->pad_regs)) @@ -1606,7 +1594,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev) const struct intel_pinctrl_soc_data **soc_table; struct device *dev = &pdev->dev; struct acpi_device *acpi_dev; - struct byt_gpio *vg; + struct intel_pinctrl *vg; int i, ret; acpi_dev = ACPI_COMPANION(dev); @@ -1636,15 +1624,15 @@ static int byt_pinctrl_probe(struct platform_device *pdev) return ret; } - vg->pctl_desc = byt_pinctrl_desc; - vg->pctl_desc.name = dev_name(dev); - vg->pctl_desc.pins = vg->soc_data->pins; - vg->pctl_desc.npins = vg->soc_data->npins; + vg->pctldesc = byt_pinctrl_desc; + vg->pctldesc.name = dev_name(dev); + vg->pctldesc.pins = vg->soc->pins; + vg->pctldesc.npins = vg->soc->npins; - vg->pctl_dev = devm_pinctrl_register(dev, &vg->pctl_desc, vg); - if (IS_ERR(vg->pctl_dev)) { + vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg); + if (IS_ERR(vg->pctldev)) { dev_err(dev, "failed to register pinctrl driver\n"); - return PTR_ERR(vg->pctl_dev); + return PTR_ERR(vg->pctldev); } ret = byt_gpio_probe(vg); @@ -1660,16 +1648,16 @@ static int byt_pinctrl_probe(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int byt_gpio_suspend(struct device *dev) { - struct byt_gpio *vg = dev_get_drvdata(dev); + struct intel_pinctrl *vg = dev_get_drvdata(dev); unsigned long flags; int i; raw_spin_lock_irqsave(&byt_lock, flags); - for (i = 0; i < vg->soc_data->npins; i++) { + for (i = 0; i < vg->soc->npins; i++) { void __iomem *reg; u32 value; - unsigned int pin = vg->soc_data->pins[i].number; + unsigned int pin = vg->soc->pins[i].number; reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); if (!reg) { @@ -1679,11 +1667,11 @@ static int byt_gpio_suspend(struct device *dev) continue; } value = readl(reg) & BYT_CONF0_RESTORE_MASK; - vg->saved_context[i].conf0 = value; + vg->context.pads[i].conf0 = value; reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); value = readl(reg) & BYT_VAL_RESTORE_MASK; - vg->saved_context[i].val = value; + vg->context.pads[i].val = value; } raw_spin_unlock_irqrestore(&byt_lock, flags); @@ -1692,16 +1680,16 @@ static int byt_gpio_suspend(struct device *dev) static int byt_gpio_resume(struct device *dev) { - struct byt_gpio *vg = dev_get_drvdata(dev); + struct intel_pinctrl *vg = dev_get_drvdata(dev); unsigned long flags; int i; raw_spin_lock_irqsave(&byt_lock, flags); - for (i = 0; i < vg->soc_data->npins; i++) { + for (i = 0; i < vg->soc->npins; i++) { void __iomem *reg; u32 value; - unsigned int pin = vg->soc_data->pins[i].number; + unsigned int pin = vg->soc->pins[i].number; reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); if (!reg) { @@ -1712,9 +1700,9 @@ static int byt_gpio_resume(struct device *dev) } value = readl(reg); if ((value & BYT_CONF0_RESTORE_MASK) != - vg->saved_context[i].conf0) { + vg->context.pads[i].conf0) { value &= ~BYT_CONF0_RESTORE_MASK; - value |= vg->saved_context[i].conf0; + value |= vg->context.pads[i].conf0; writel(value, reg); dev_info(dev, "restored pin %d conf0 %#08x", i, value); } @@ -1722,11 +1710,11 @@ static int byt_gpio_resume(struct device *dev) reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); value = readl(reg); if ((value & BYT_VAL_RESTORE_MASK) != - vg->saved_context[i].val) { + vg->context.pads[i].val) { u32 v; v = value & ~BYT_VAL_RESTORE_MASK; - v |= vg->saved_context[i].val; + v |= vg->context.pads[i].val; if (v != value) { writel(v, reg); dev_dbg(dev, "restored pin %d val %#08x\n", From eb83479e18999e34b3b800f54aa31137f7f41c33 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 22 Aug 2019 18:40:50 +0300 Subject: [PATCH 11/41] pinctrl: lynxpoint: Move GPIO driver to pin controller folder Move Lynxpoint GPIO driver under Intel pin control umbrella for further transformation to a real pin control driver. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- MAINTAINERS | 1 - drivers/gpio/Kconfig | 8 -------- drivers/gpio/Makefile | 1 - drivers/pinctrl/intel/Kconfig | 10 ++++++++++ drivers/pinctrl/intel/Makefile | 1 + .../intel/pinctrl-lynxpoint.c} | 0 6 files changed, 11 insertions(+), 10 deletions(-) rename drivers/{gpio/gpio-lynxpoint.c => pinctrl/intel/pinctrl-lynxpoint.c} (100%) diff --git a/MAINTAINERS b/MAINTAINERS index bd5847e802de..6ea3cba0a9b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8344,7 +8344,6 @@ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git F: drivers/gpio/gpio-ich.c F: drivers/gpio/gpio-intel-mid.c -F: drivers/gpio/gpio-lynxpoint.c F: drivers/gpio/gpio-merrifield.c F: drivers/gpio/gpio-ml-ioh.c F: drivers/gpio/gpio-pch.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 8adffd42f8cb..6923142fd874 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -335,14 +335,6 @@ config GPIO_LPC32XX Select this option to enable GPIO driver for NXP LPC32XX devices. -config GPIO_LYNXPOINT - tristate "Intel Lynxpoint GPIO support" - depends on ACPI && X86 - select GPIOLIB_IRQCHIP - help - driver for GPIO functionality on Intel Lynxpoint PCH chipset - Requires ACPI device enumeration code to set up a platform device. - config GPIO_MB86S7X tristate "GPIO support for Fujitsu MB86S7x Platforms" help diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 34eb8b2b12dd..55b2b645391e 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -76,7 +76,6 @@ obj-$(CONFIG_GPIO_LP873X) += gpio-lp873x.o obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o obj-$(CONFIG_GPIO_LPC18XX) += gpio-lpc18xx.o obj-$(CONFIG_GPIO_LPC32XX) += gpio-lpc32xx.o -obj-$(CONFIG_GPIO_LYNXPOINT) += gpio-lynxpoint.o obj-$(CONFIG_GPIO_MADERA) += gpio-madera.o obj-$(CONFIG_GPIO_MAX3191X) += gpio-max3191x.o obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index 6091947a8f51..c2e6bc9e3e04 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig @@ -31,6 +31,16 @@ config PINCTRL_CHERRYVIEW Cherryview/Braswell pinctrl driver provides an interface that allows configuring of SoC pins and using them as GPIOs. +config PINCTRL_LYNXPOINT + tristate "Intel Lynxpoint pinctrl and GPIO driver" + depends on ACPI + select GPIOLIB + select GPIOLIB_IRQCHIP + help + Lynxpoint is the PCH of Intel Haswell. This pinctrl driver + provides an interface that allows configuring of PCH pins and + using them as GPIOs. + config PINCTRL_MERRIFIELD tristate "Intel Merrifield pinctrl driver" depends on X86_INTEL_MID diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile index 7e620b471ef6..f60f99cfa7aa 100644 --- a/drivers/pinctrl/intel/Makefile +++ b/drivers/pinctrl/intel/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o +obj-$(CONFIG_PINCTRL_LYNXPOINT) += pinctrl-lynxpoint.o obj-$(CONFIG_PINCTRL_MERRIFIELD) += pinctrl-merrifield.o obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c similarity index 100% rename from drivers/gpio/gpio-lynxpoint.c rename to drivers/pinctrl/intel/pinctrl-lynxpoint.c From b2e05d63c295529879aabeb8781f947e1e2dca7b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 18 Nov 2019 20:04:54 +0200 Subject: [PATCH 12/41] pinctrl: lynxpoint: Use raw_spinlock for locking The Intel Lynxpoint pinctrl driver implements irqchip callbacks which are called with desc->lock raw_spinlock held. In mainline this is fine because spinlock resolves to raw_spinlock. However, running the same code in -rt we will get a BUG() asserted. This is because in -rt spinlocks are preemptible so taking the driver private spinlock in irqchip callbacks causes might_sleep() to trigger. In order to keep -rt happy but at the same time make sure that register accesses get serialized, convert the driver to use raw_spinlock instead. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 28 +++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 490ce7bae25e..c30fd86846a7 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -47,7 +47,7 @@ struct lp_gpio { struct gpio_chip chip; struct platform_device *pdev; - spinlock_t lock; + raw_spinlock_t lock; unsigned long reg_base; }; @@ -144,7 +144,7 @@ static int lp_irq_type(struct irq_data *d, unsigned type) if (hwirq >= lg->chip.ngpio) return -EINVAL; - spin_lock_irqsave(&lg->lock, flags); + raw_spin_lock_irqsave(&lg->lock, flags); value = inl(reg); /* set both TRIG_SEL and INV bits to 0 for rising edge */ @@ -170,7 +170,7 @@ static int lp_irq_type(struct irq_data *d, unsigned type) else if (type & IRQ_TYPE_LEVEL_MASK) irq_set_handler_locked(d, handle_level_irq); - spin_unlock_irqrestore(&lg->lock, flags); + raw_spin_unlock_irqrestore(&lg->lock, flags); return 0; } @@ -187,14 +187,14 @@ static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value) unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); unsigned long flags; - spin_lock_irqsave(&lg->lock, flags); + raw_spin_lock_irqsave(&lg->lock, flags); if (value) outl(inl(reg) | OUT_LVL_BIT, reg); else outl(inl(reg) & ~OUT_LVL_BIT, reg); - spin_unlock_irqrestore(&lg->lock, flags); + raw_spin_unlock_irqrestore(&lg->lock, flags); } static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset) @@ -203,9 +203,9 @@ static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset) unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); unsigned long flags; - spin_lock_irqsave(&lg->lock, flags); + raw_spin_lock_irqsave(&lg->lock, flags); outl(inl(reg) | DIR_BIT, reg); - spin_unlock_irqrestore(&lg->lock, flags); + raw_spin_unlock_irqrestore(&lg->lock, flags); return 0; } @@ -219,9 +219,9 @@ static int lp_gpio_direction_output(struct gpio_chip *chip, lp_gpio_set(chip, offset, value); - spin_lock_irqsave(&lg->lock, flags); + raw_spin_lock_irqsave(&lg->lock, flags); outl(inl(reg) & ~DIR_BIT, reg); - spin_unlock_irqrestore(&lg->lock, flags); + raw_spin_unlock_irqrestore(&lg->lock, flags); return 0; } @@ -272,9 +272,9 @@ static void lp_irq_enable(struct irq_data *d) unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); unsigned long flags; - spin_lock_irqsave(&lg->lock, flags); + raw_spin_lock_irqsave(&lg->lock, flags); outl(inl(reg) | BIT(hwirq % 32), reg); - spin_unlock_irqrestore(&lg->lock, flags); + raw_spin_unlock_irqrestore(&lg->lock, flags); } static void lp_irq_disable(struct irq_data *d) @@ -285,9 +285,9 @@ static void lp_irq_disable(struct irq_data *d) unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); unsigned long flags; - spin_lock_irqsave(&lg->lock, flags); + raw_spin_lock_irqsave(&lg->lock, flags); outl(inl(reg) & ~BIT(hwirq % 32), reg); - spin_unlock_irqrestore(&lg->lock, flags); + raw_spin_unlock_irqrestore(&lg->lock, flags); } static struct irq_chip lp_irqchip = { @@ -351,7 +351,7 @@ static int lp_gpio_probe(struct platform_device *pdev) return -EBUSY; } - spin_lock_init(&lg->lock); + raw_spin_lock_init(&lg->lock); gc = &lg->chip; gc->label = dev_name(dev); From 7c0bc7bb39ac89a454317d55262c06ec0048628b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 25 Oct 2019 21:25:43 +0300 Subject: [PATCH 13/41] pinctrl: lynxpoint: Correct amount of pins When we count from 0 it's possible to get into off-by-one error. That's what had happened to this driver. So, correct amount of pins and related typos in the code. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index c30fd86846a7..162fc38c929d 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -18,9 +18,9 @@ #include #include -/* LynxPoint chipset has support for 94 gpio pins */ +/* LynxPoint chipset has support for 95 GPIO pins */ -#define LP_NUM_GPIO 94 +#define LP_NUM_GPIO 95 /* Bitmapped register offsets */ #define LP_ACPI_OWNED 0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */ @@ -54,11 +54,11 @@ struct lp_gpio { /* * Lynxpoint gpios are controlled through both bitmapped registers and * per gpio specific registers. The bitmapped registers are in chunks of - * 3 x 32bit registers to cover all 94 gpios + * 3 x 32bit registers to cover all 95 GPIOs * * per gpio specific registers consist of two 32bit registers per gpio - * (LP_CONFIG1 and LP_CONFIG2), with 94 gpios there's a total of - * 188 config registers. + * (LP_CONFIG1 and LP_CONFIG2), with 95 GPIOs there's a total of + * 190 config registers. * * A simplified view of the register layout look like this: * @@ -67,7 +67,7 @@ struct lp_gpio { * LP_ACPI_OWNED[94:64] gpio ownerships for gpios 63-94 * ... * LP_INT_ENABLE[31:0] ... - * LP_INT_ENABLE[63:31] ... + * LP_INT_ENABLE[63:32] ... * LP_INT_ENABLE[94:64] ... * LP0_CONFIG1 (gpio 0) config1 reg for gpio 0 (per gpio registers) * LP0_CONFIG2 (gpio 0) config2 reg for gpio 0 From 3b4c2d8ef0bd88828336e0690459d1b2120eb9e4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 18:01:19 +0200 Subject: [PATCH 14/41] pinctrl: lynxpoint: Drop useless assignment There is no need to assign ret variable in ->probe(). Drop useless assignment. Reviewed-by: Linus Walleij 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 162fc38c929d..6f074323e00e 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -325,7 +325,7 @@ static int lp_gpio_probe(struct platform_device *pdev) struct resource *io_rc, *irq_rc; struct device *dev = &pdev->dev; unsigned long reg_len; - int ret = -ENODEV; + int ret; lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL); if (!lg) From caedcbd053bca446f8d66faf74adeb8eb3d2913f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 25 Oct 2019 20:23:46 +0300 Subject: [PATCH 15/41] pinctrl: lynxpoint: Use %pR to print IO resource Replace explicit casting by pointer to struct resource with specifier replacement to %pR to print the IO resource. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 6f074323e00e..36978a7c2a85 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -346,8 +346,7 @@ static int lp_gpio_probe(struct platform_device *pdev) reg_len = resource_size(io_rc); if (!devm_request_region(dev, lg->reg_base, reg_len, "lp-gpio")) { - dev_err(dev, "failed requesting IO region 0x%x\n", - (unsigned int)lg->reg_base); + dev_err(dev, "failed requesting IO region %pR\n", &io_rc); return -EBUSY; } From a718e68ede16957e091ee8f35f7b73765e51a092 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 18:26:35 +0200 Subject: [PATCH 16/41] pinctrl: lynxpoint: Use standard pattern for memory allocation The pattern foo = kmalloc(sizeof(*foo), GFP_KERNEL); has an advantage when foo type is changed. Since we are planning a such, better to be prepared by using standard pattern for memory allocation. Reviewed-by: Linus Walleij 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 36978a7c2a85..17a7843c8dc9 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -327,7 +327,7 @@ static int lp_gpio_probe(struct platform_device *pdev) unsigned long reg_len; int ret; - lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL); + lg = devm_kzalloc(dev, sizeof(*lg), GFP_KERNEL); if (!lg) return -ENOMEM; From 76347d7ad250b46c4dbeb0e1fe629ed3c72cf004 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 19:15:34 +0200 Subject: [PATCH 17/41] pinctrl: lynxpoint: Assume 2 bits for mode selector New generations can use 2 bits for mode selector. Update the code to support it. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 17a7843c8dc9..4b2e3f298641 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -38,7 +38,9 @@ #define TRIG_SEL_BIT BIT(4) /* 0: Edge, 1: Level */ #define INT_INV_BIT BIT(3) /* Invert interrupt triggering */ #define DIR_BIT BIT(2) /* 0: Output, 1: Input */ -#define USE_SEL_BIT BIT(0) /* 0: Native, 1: GPIO */ +#define USE_SEL_MASK GENMASK(1, 0) /* 0: Native, 1: GPIO, ... */ +#define USE_SEL_NATIVE (0 << 0) +#define USE_SEL_GPIO (1 << 0) /* LP_CONFIG2 reg bits */ #define GPINDIS_BIT BIT(2) /* disable input sensing */ @@ -111,7 +113,7 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) return -EBUSY; } /* Fail if pin is in alternate function mode (not GPIO mode) */ - if (!(inl(reg) & USE_SEL_BIT)) + if ((inl(reg) & USE_SEL_MASK) != USE_SEL_GPIO) return -ENODEV; /* enable input sensing */ From 03fb681badafa3035d2af4cb48870f69ad993dcb Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 19:19:56 +0200 Subject: [PATCH 18/41] pinctrl: lynxpoint: Relax GPIO request rules A pin in native mode still can be requested as GPIO, though we assume that firmware has configured it properly, which sometimes is not the case. Here we allow turning the pin as GPIO to avoid potential issues, but issue warning that something might be wrong. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 4b2e3f298641..3ac95f9d6a7f 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -104,6 +104,7 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); unsigned long conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); unsigned long acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED); + u32 value; pm_runtime_get(&lg->pdev->dev); /* should we put if failed */ @@ -112,9 +113,16 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) dev_err(&lg->pdev->dev, "gpio %d reserved for ACPI\n", offset); return -EBUSY; } - /* Fail if pin is in alternate function mode (not GPIO mode) */ - if ((inl(reg) & USE_SEL_MASK) != USE_SEL_GPIO) - return -ENODEV; + + /* + * Reconfigure pin to GPIO mode if needed and issue a warning, + * since we expect firmware to configure it properly. + */ + value = inl(reg); + if ((value & USE_SEL_MASK) != USE_SEL_GPIO) { + outl((value & USE_SEL_MASK) | USE_SEL_GPIO, reg); + dev_warn(&lg->pdev->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", offset); + } /* enable input sensing */ outl(inl(conf2) & ~GPINDIS_BIT, conf2); From 1e78ea71226b68cec24dca53c53e673de60211bf Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 25 Oct 2019 11:56:11 +0300 Subject: [PATCH 19/41] pinctrl: lynxpoint: Keep pointer to struct device instead of its container There is no need to keep pointer to struct platform_device, which is container of struct device, because the latter is what have been used everywhere outside of ->probe() path. In any case we may derive pointer to the container when needed. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 3ac95f9d6a7f..1d5f5053fe14 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -48,7 +48,7 @@ struct lp_gpio { struct gpio_chip chip; - struct platform_device *pdev; + struct device *dev; raw_spinlock_t lock; unsigned long reg_base; }; @@ -106,11 +106,11 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) unsigned long acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED); u32 value; - pm_runtime_get(&lg->pdev->dev); /* should we put if failed */ + pm_runtime_get(lg->dev); /* should we put if failed */ /* Fail if BIOS reserved pin for ACPI use */ if (!(inl(acpi_use) & BIT(offset % 32))) { - dev_err(&lg->pdev->dev, "gpio %d reserved for ACPI\n", offset); + dev_err(lg->dev, "gpio %d reserved for ACPI\n", offset); return -EBUSY; } @@ -121,7 +121,7 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) value = inl(reg); if ((value & USE_SEL_MASK) != USE_SEL_GPIO) { outl((value & USE_SEL_MASK) | USE_SEL_GPIO, reg); - dev_warn(&lg->pdev->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", offset); + dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", offset); } /* enable input sensing */ @@ -139,7 +139,7 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned offset) /* disable input sensing */ outl(inl(conf2) | GPINDIS_BIT, conf2); - pm_runtime_put(&lg->pdev->dev); + pm_runtime_put(lg->dev); } static int lp_irq_type(struct irq_data *d, unsigned type) @@ -341,7 +341,7 @@ static int lp_gpio_probe(struct platform_device *pdev) if (!lg) return -ENOMEM; - lg->pdev = pdev; + lg->dev = dev; platform_set_drvdata(pdev, lg); io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0); @@ -385,7 +385,7 @@ static int lp_gpio_probe(struct platform_device *pdev) girq->init_hw = lp_gpio_irq_init_hw; girq->parent_handler = lp_gpio_irq_handler; girq->num_parents = 1; - girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents, + girq->parents = devm_kcalloc(dev, girq->num_parents, sizeof(*girq->parents), GFP_KERNEL); if (!girq->parents) From e1940adeb17b33bb30ce02abe257c80a492f1707 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 19:30:31 +0200 Subject: [PATCH 20/41] pinctrl: lynxpoint: Switch to memory mapped IO accessors Convert driver to use memory mapped IO accessors. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 88 +++++++++++------------ 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 1d5f5053fe14..4ed2d4daea19 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -50,7 +50,7 @@ struct lp_gpio { struct gpio_chip chip; struct device *dev; raw_spinlock_t lock; - unsigned long reg_base; + void __iomem *regs; }; /* @@ -82,7 +82,7 @@ struct lp_gpio { * LP94_CONFIG2 (gpio 94) ... */ -static unsigned long lp_gpio_reg(struct gpio_chip *chip, unsigned offset, +static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned offset, int reg) { struct lp_gpio *lg = gpiochip_get_data(chip); @@ -95,21 +95,21 @@ static unsigned long lp_gpio_reg(struct gpio_chip *chip, unsigned offset, /* bitmapped registers */ reg_offset = (offset / 32) * 4; - return lg->reg_base + reg + reg_offset; + return lg->regs + reg + reg_offset; } static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) { struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); - unsigned long conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); - unsigned long acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED); + void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); + void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); + void __iomem *acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED); u32 value; pm_runtime_get(lg->dev); /* should we put if failed */ /* Fail if BIOS reserved pin for ACPI use */ - if (!(inl(acpi_use) & BIT(offset % 32))) { + if (!(ioread32(acpi_use) & BIT(offset % 32))) { dev_err(lg->dev, "gpio %d reserved for ACPI\n", offset); return -EBUSY; } @@ -118,14 +118,14 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) * Reconfigure pin to GPIO mode if needed and issue a warning, * since we expect firmware to configure it properly. */ - value = inl(reg); + value = ioread32(reg); if ((value & USE_SEL_MASK) != USE_SEL_GPIO) { - outl((value & USE_SEL_MASK) | USE_SEL_GPIO, reg); + iowrite32((value & USE_SEL_MASK) | USE_SEL_GPIO, reg); dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", offset); } /* enable input sensing */ - outl(inl(conf2) & ~GPINDIS_BIT, conf2); + iowrite32(ioread32(conf2) & ~GPINDIS_BIT, conf2); return 0; @@ -134,10 +134,10 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) static void lp_gpio_free(struct gpio_chip *chip, unsigned offset) { struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); + void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); /* disable input sensing */ - outl(inl(conf2) | GPINDIS_BIT, conf2); + iowrite32(ioread32(conf2) | GPINDIS_BIT, conf2); pm_runtime_put(lg->dev); } @@ -147,15 +147,15 @@ static int lp_irq_type(struct irq_data *d, unsigned type) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct lp_gpio *lg = gpiochip_get_data(gc); u32 hwirq = irqd_to_hwirq(d); + void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1); unsigned long flags; u32 value; - unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1); if (hwirq >= lg->chip.ngpio) return -EINVAL; raw_spin_lock_irqsave(&lg->lock, flags); - value = inl(reg); + value = ioread32(reg); /* set both TRIG_SEL and INV bits to 0 for rising edge */ if (type & IRQ_TYPE_EDGE_RISING) @@ -173,7 +173,7 @@ static int lp_irq_type(struct irq_data *d, unsigned type) if (type & IRQ_TYPE_LEVEL_HIGH) value |= TRIG_SEL_BIT | INT_INV_BIT; - outl(value, reg); + iowrite32(value, reg); if (type & IRQ_TYPE_EDGE_BOTH) irq_set_handler_locked(d, handle_edge_irq); @@ -187,22 +187,22 @@ static int lp_irq_type(struct irq_data *d, unsigned type) static int lp_gpio_get(struct gpio_chip *chip, unsigned offset) { - unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); - return !!(inl(reg) & IN_LVL_BIT); + void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); + return !!(ioread32(reg) & IN_LVL_BIT); } static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); + void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); unsigned long flags; raw_spin_lock_irqsave(&lg->lock, flags); if (value) - outl(inl(reg) | OUT_LVL_BIT, reg); + iowrite32(ioread32(reg) | OUT_LVL_BIT, reg); else - outl(inl(reg) & ~OUT_LVL_BIT, reg); + iowrite32(ioread32(reg) & ~OUT_LVL_BIT, reg); raw_spin_unlock_irqrestore(&lg->lock, flags); } @@ -210,11 +210,11 @@ static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); + void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); unsigned long flags; raw_spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) | DIR_BIT, reg); + iowrite32(ioread32(reg) | DIR_BIT, reg); raw_spin_unlock_irqrestore(&lg->lock, flags); return 0; @@ -224,13 +224,13 @@ static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1); + void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); unsigned long flags; lp_gpio_set(chip, offset, value); raw_spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) & ~DIR_BIT, reg); + iowrite32(ioread32(reg) & ~DIR_BIT, reg); raw_spin_unlock_irqrestore(&lg->lock, flags); return 0; @@ -242,7 +242,8 @@ static void lp_gpio_irq_handler(struct irq_desc *desc) struct gpio_chip *gc = irq_desc_get_handler_data(desc); struct lp_gpio *lg = gpiochip_get_data(gc); struct irq_chip *chip = irq_data_get_irq_chip(data); - unsigned long reg, ena, pending; + void __iomem *reg, *ena; + unsigned long pending; u32 base, pin; /* check from GPIO controller which pin triggered the interrupt */ @@ -251,13 +252,13 @@ static void lp_gpio_irq_handler(struct irq_desc *desc) ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE); /* Only interrupts that are enabled */ - pending = inl(reg) & inl(ena); + pending = ioread32(reg) & ioread32(ena); for_each_set_bit(pin, &pending, 32) { unsigned irq; /* Clear before handling so we don't lose an edge */ - outl(BIT(pin), reg); + iowrite32(BIT(pin), reg); irq = irq_find_mapping(lg->chip.irq.domain, base + pin); generic_handle_irq(irq); @@ -279,11 +280,11 @@ static void lp_irq_enable(struct irq_data *d) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct lp_gpio *lg = gpiochip_get_data(gc); u32 hwirq = irqd_to_hwirq(d); - unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); + void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); unsigned long flags; raw_spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) | BIT(hwirq % 32), reg); + iowrite32(ioread32(reg) | BIT(hwirq % 32), reg); raw_spin_unlock_irqrestore(&lg->lock, flags); } @@ -292,11 +293,11 @@ static void lp_irq_disable(struct irq_data *d) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct lp_gpio *lg = gpiochip_get_data(gc); u32 hwirq = irqd_to_hwirq(d); - unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); + void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); unsigned long flags; raw_spin_lock_irqsave(&lg->lock, flags); - outl(inl(reg) & ~BIT(hwirq % 32), reg); + iowrite32(ioread32(reg) & ~BIT(hwirq % 32), reg); raw_spin_unlock_irqrestore(&lg->lock, flags); } @@ -313,16 +314,16 @@ static struct irq_chip lp_irqchip = { static int lp_gpio_irq_init_hw(struct gpio_chip *chip) { struct lp_gpio *lg = gpiochip_get_data(chip); - unsigned long reg; + void __iomem *reg; unsigned base; for (base = 0; base < lg->chip.ngpio; base += 32) { /* disable gpio pin interrupts */ reg = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE); - outl(0, reg); + iowrite32(0, reg); /* Clear interrupt status register */ reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); - outl(0xffffffff, reg); + iowrite32(0xffffffff, reg); } return 0; @@ -334,7 +335,7 @@ static int lp_gpio_probe(struct platform_device *pdev) struct gpio_chip *gc; struct resource *io_rc, *irq_rc; struct device *dev = &pdev->dev; - unsigned long reg_len; + void __iomem *regs; int ret; lg = devm_kzalloc(dev, sizeof(*lg), GFP_KERNEL); @@ -345,21 +346,19 @@ static int lp_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, lg); io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0); - irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!io_rc) { dev_err(dev, "missing IO resources\n"); return -EINVAL; } - lg->reg_base = io_rc->start; - reg_len = resource_size(io_rc); - - if (!devm_request_region(dev, lg->reg_base, reg_len, "lp-gpio")) { - dev_err(dev, "failed requesting IO region %pR\n", &io_rc); + regs = devm_ioport_map(dev, io_rc->start, resource_size(io_rc)); + if (!regs) { + dev_err(dev, "failed mapping IO region %pR\n", &io_rc); return -EBUSY; } + lg->regs = regs; + raw_spin_lock_init(&lg->lock); gc = &lg->chip; @@ -377,6 +376,7 @@ static int lp_gpio_probe(struct platform_device *pdev) gc->parent = dev; /* set up interrupts */ + irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (irq_rc && irq_rc->start) { struct gpio_irq_chip *girq; @@ -419,14 +419,14 @@ static int lp_gpio_runtime_resume(struct device *dev) static int lp_gpio_resume(struct device *dev) { struct lp_gpio *lg = dev_get_drvdata(dev); - unsigned long reg; + 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); - outl(inl(reg) & ~GPINDIS_BIT, reg); + iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); } } return 0; From c35f463a966221f3d6c6bc48fbea27a8d68aafc3 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 17:50:27 +0300 Subject: [PATCH 21/41] pinctrl: lynxpoint: Convert unsigned to unsigned int Simple type conversion with no functional change implied. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 4ed2d4daea19..3c8241ed8bc2 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -82,7 +82,7 @@ struct lp_gpio { * LP94_CONFIG2 (gpio 94) ... */ -static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned offset, +static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset, int reg) { struct lp_gpio *lg = gpiochip_get_data(chip); @@ -98,7 +98,7 @@ static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned offset, return lg->regs + reg + reg_offset; } -static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) +static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset) { struct lp_gpio *lg = gpiochip_get_data(chip); void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); @@ -131,7 +131,7 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned offset) return 0; } -static void lp_gpio_free(struct gpio_chip *chip, unsigned offset) +static void lp_gpio_free(struct gpio_chip *chip, unsigned int offset) { struct lp_gpio *lg = gpiochip_get_data(chip); void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); @@ -142,7 +142,7 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned offset) pm_runtime_put(lg->dev); } -static int lp_irq_type(struct irq_data *d, unsigned type) +static int lp_irq_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct lp_gpio *lg = gpiochip_get_data(gc); @@ -185,13 +185,13 @@ static int lp_irq_type(struct irq_data *d, unsigned type) return 0; } -static int lp_gpio_get(struct gpio_chip *chip, unsigned offset) +static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset) { void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); return !!(ioread32(reg) & IN_LVL_BIT); } -static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct lp_gpio *lg = gpiochip_get_data(chip); void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); @@ -207,7 +207,7 @@ static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value) raw_spin_unlock_irqrestore(&lg->lock, flags); } -static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { struct lp_gpio *lg = gpiochip_get_data(chip); void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); @@ -220,8 +220,8 @@ static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset) return 0; } -static int lp_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) +static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, + int value) { struct lp_gpio *lg = gpiochip_get_data(chip); void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); @@ -255,7 +255,7 @@ static void lp_gpio_irq_handler(struct irq_desc *desc) pending = ioread32(reg) & ioread32(ena); for_each_set_bit(pin, &pending, 32) { - unsigned irq; + unsigned int irq; /* Clear before handling so we don't lose an edge */ iowrite32(BIT(pin), reg); @@ -315,7 +315,7 @@ static int lp_gpio_irq_init_hw(struct gpio_chip *chip) { struct lp_gpio *lg = gpiochip_get_data(chip); void __iomem *reg; - unsigned base; + unsigned int base; for (base = 0; base < lg->chip.ngpio; base += 32) { /* disable gpio pin interrupts */ @@ -390,7 +390,7 @@ static int lp_gpio_probe(struct platform_device *pdev) GFP_KERNEL); if (!girq->parents) return -ENOMEM; - girq->parents[0] = (unsigned)irq_rc->start; + girq->parents[0] = (unsigned int)irq_rc->start; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_bad_irq; } From 21a06495d0e757b8a52774ce62e9cfdf07838971 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 19:27:34 +0200 Subject: [PATCH 22/41] pinctrl: lynxpoint: Extract lp_gpio_acpi_use() for future use We may need this function for other features in the pin control driver. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 3c8241ed8bc2..d40360728140 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -98,18 +98,28 @@ static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset, return lg->regs + reg + reg_offset; } +static bool lp_gpio_acpi_use(struct lp_gpio *lg, unsigned int pin) +{ + void __iomem *acpi_use; + + acpi_use = lp_gpio_reg(&lg->chip, pin, LP_ACPI_OWNED); + if (!acpi_use) + return true; + + return !(ioread32(acpi_use) & BIT(pin % 32)); +} + static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset) { struct lp_gpio *lg = gpiochip_get_data(chip); void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); - void __iomem *acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED); u32 value; pm_runtime_get(lg->dev); /* should we put if failed */ /* Fail if BIOS reserved pin for ACPI use */ - if (!(ioread32(acpi_use) & BIT(offset % 32))) { + if (lp_gpio_acpi_use(lg, offset)) { dev_err(lg->dev, "gpio %d reserved for ACPI\n", offset); return -EBUSY; } From d0f2df4070b59662b7d03bbcb22dccbfbd717158 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 25 Oct 2019 20:53:58 +0300 Subject: [PATCH 23/41] pinctrl: lynxpoint: Move ->remove closer to ->probe() Consolidate ->remove and ->probe() callbacks for better maintenance. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index d40360728140..83b5b2590778 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -416,6 +416,12 @@ static int lp_gpio_probe(struct platform_device *pdev) return 0; } +static int lp_gpio_remove(struct platform_device *pdev) +{ + pm_runtime_disable(&pdev->dev); + return 0; +} + static int lp_gpio_runtime_suspend(struct device *dev) { return 0; @@ -455,12 +461,6 @@ static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match); -static int lp_gpio_remove(struct platform_device *pdev) -{ - pm_runtime_disable(&pdev->dev); - return 0; -} - static struct platform_driver lp_gpio_driver = { .probe = lp_gpio_probe, .remove = lp_gpio_remove, From 095f2a67cdaf0aba6868504e963dda2e4d09a3f8 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 18 Nov 2019 20:08:57 +0200 Subject: [PATCH 24/41] pinctrl: lynxpoint: Move lp_irq_type() closer to IRQ related routines Consolidate IRQ routines for better maintenance. While here, rename lp_irq_type() to lp_irq_set_type() to be in align with a callback name. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 88 +++++++++++------------ 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 83b5b2590778..19e8f8f1f7aa 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -152,49 +152,6 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned int offset) pm_runtime_put(lg->dev); } -static int lp_irq_type(struct irq_data *d, unsigned int type) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct lp_gpio *lg = gpiochip_get_data(gc); - u32 hwirq = irqd_to_hwirq(d); - void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1); - unsigned long flags; - u32 value; - - if (hwirq >= lg->chip.ngpio) - return -EINVAL; - - raw_spin_lock_irqsave(&lg->lock, flags); - value = ioread32(reg); - - /* set both TRIG_SEL and INV bits to 0 for rising edge */ - if (type & IRQ_TYPE_EDGE_RISING) - value &= ~(TRIG_SEL_BIT | INT_INV_BIT); - - /* TRIG_SEL bit 0, INV bit 1 for falling edge */ - if (type & IRQ_TYPE_EDGE_FALLING) - value = (value | INT_INV_BIT) & ~TRIG_SEL_BIT; - - /* TRIG_SEL bit 1, INV bit 0 for level low */ - if (type & IRQ_TYPE_LEVEL_LOW) - value = (value | TRIG_SEL_BIT) & ~INT_INV_BIT; - - /* TRIG_SEL bit 1, INV bit 1 for level high */ - if (type & IRQ_TYPE_LEVEL_HIGH) - value |= TRIG_SEL_BIT | INT_INV_BIT; - - iowrite32(value, reg); - - if (type & IRQ_TYPE_EDGE_BOTH) - irq_set_handler_locked(d, handle_edge_irq); - else if (type & IRQ_TYPE_LEVEL_MASK) - irq_set_handler_locked(d, handle_level_irq); - - raw_spin_unlock_irqrestore(&lg->lock, flags); - - return 0; -} - static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset) { void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); @@ -311,13 +268,56 @@ static void lp_irq_disable(struct irq_data *d) raw_spin_unlock_irqrestore(&lg->lock, flags); } +static int lp_irq_set_type(struct irq_data *d, unsigned int type) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct lp_gpio *lg = gpiochip_get_data(gc); + u32 hwirq = irqd_to_hwirq(d); + void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1); + unsigned long flags; + u32 value; + + if (hwirq >= lg->chip.ngpio) + return -EINVAL; + + raw_spin_lock_irqsave(&lg->lock, flags); + value = ioread32(reg); + + /* set both TRIG_SEL and INV bits to 0 for rising edge */ + if (type & IRQ_TYPE_EDGE_RISING) + value &= ~(TRIG_SEL_BIT | INT_INV_BIT); + + /* TRIG_SEL bit 0, INV bit 1 for falling edge */ + if (type & IRQ_TYPE_EDGE_FALLING) + value = (value | INT_INV_BIT) & ~TRIG_SEL_BIT; + + /* TRIG_SEL bit 1, INV bit 0 for level low */ + if (type & IRQ_TYPE_LEVEL_LOW) + value = (value | TRIG_SEL_BIT) & ~INT_INV_BIT; + + /* TRIG_SEL bit 1, INV bit 1 for level high */ + if (type & IRQ_TYPE_LEVEL_HIGH) + value |= TRIG_SEL_BIT | INT_INV_BIT; + + iowrite32(value, reg); + + if (type & IRQ_TYPE_EDGE_BOTH) + irq_set_handler_locked(d, handle_edge_irq); + else if (type & IRQ_TYPE_LEVEL_MASK) + irq_set_handler_locked(d, handle_level_irq); + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + return 0; +} + static struct irq_chip lp_irqchip = { .name = "LP-GPIO", .irq_mask = lp_irq_mask, .irq_unmask = lp_irq_unmask, .irq_enable = lp_irq_enable, .irq_disable = lp_irq_disable, - .irq_set_type = lp_irq_type, + .irq_set_type = lp_irq_set_type, .flags = IRQCHIP_SKIP_SET_WAKE, }; From 540bff18daf4aa3d67004e8bb02a0ea5b3818451 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 19:28:14 +0200 Subject: [PATCH 25/41] pinctrl: lynxpoint: Move ownership check to IRQ chip There is nothing wrong with requesting pin that owned by ACPI. The only difference is how interrupt status will be reflected. It means that in ACPI mode we may not use pin as GPIO-backed IRQ. Taking above into consideration, move the check from GPIO to IRQ chip callback. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 19e8f8f1f7aa..ddb201e5d78f 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -118,12 +118,6 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset) pm_runtime_get(lg->dev); /* should we put if failed */ - /* Fail if BIOS reserved pin for ACPI use */ - if (lp_gpio_acpi_use(lg, offset)) { - dev_err(lg->dev, "gpio %d reserved for ACPI\n", offset); - return -EBUSY; - } - /* * Reconfigure pin to GPIO mode if needed and issue a warning, * since we expect firmware to configure it properly. @@ -280,6 +274,12 @@ static int lp_irq_set_type(struct irq_data *d, unsigned int type) if (hwirq >= lg->chip.ngpio) return -EINVAL; + /* Fail if BIOS reserved pin for ACPI use */ + if (lp_gpio_acpi_use(lg, hwirq)) { + dev_err(lg->dev, "pin %u can't be used as IRQ\n", hwirq); + return -EBUSY; + } + raw_spin_lock_irqsave(&lg->lock, flags); value = ioread32(reg); From 5931e6edfdd01c97b4cf8354e68f74df97580e49 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 22 Nov 2019 16:50:05 +0200 Subject: [PATCH 26/41] pinctrl: lynxpoint: Implement ->irq_ack() callback Instead of playing tricks with registers in the interrupt handler, utilize the IRQ chip core for ACKing interrupts properly. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index ddb201e5d78f..3b0dfe9a51ba 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -218,9 +218,6 @@ static void lp_gpio_irq_handler(struct irq_desc *desc) for_each_set_bit(pin, &pending, 32) { unsigned int irq; - /* Clear before handling so we don't lose an edge */ - iowrite32(BIT(pin), reg); - irq = irq_find_mapping(lg->chip.irq.domain, base + pin); generic_handle_irq(irq); } @@ -228,6 +225,19 @@ static void lp_gpio_irq_handler(struct irq_desc *desc) chip->irq_eoi(data); } +static void lp_irq_ack(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct lp_gpio *lg = gpiochip_get_data(gc); + u32 hwirq = irqd_to_hwirq(d); + void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_STAT); + unsigned long flags; + + raw_spin_lock_irqsave(&lg->lock, flags); + iowrite32(BIT(hwirq % 32), reg); + raw_spin_unlock_irqrestore(&lg->lock, flags); +} + static void lp_irq_unmask(struct irq_data *d) { } @@ -313,6 +323,7 @@ static int lp_irq_set_type(struct irq_data *d, unsigned int type) static struct irq_chip lp_irqchip = { .name = "LP-GPIO", + .irq_ack = lp_irq_ack, .irq_mask = lp_irq_mask, .irq_unmask = lp_irq_unmask, .irq_enable = lp_irq_enable, From 54d371cf73d9029a6adade3ec9423653d7790ef0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Nov 2019 17:36:48 +0200 Subject: [PATCH 27/41] pinctrl: lynxpoint: Implement intel_gpio_get_direction callback Allows querying GPIO direction from the pad config register. If the pad is not in GPIO mode, return an error. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 3b0dfe9a51ba..3c1b71204bbe 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -197,6 +197,16 @@ static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, return 0; } +static int lp_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); + + if (ioread32(reg) & DIR_BIT) + return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_OUT; +} + static void lp_gpio_irq_handler(struct irq_desc *desc) { struct irq_data *data = irq_desc_get_irq_data(desc); @@ -391,6 +401,7 @@ static int lp_gpio_probe(struct platform_device *pdev) gc->direction_output = lp_gpio_direction_output; gc->get = lp_gpio_get; gc->set = lp_gpio_set; + gc->get_direction = lp_gpio_get_direction; gc->base = -1; gc->ngpio = LP_NUM_GPIO; gc->can_sleep = false; From cecddda7ca4e7e94256e3be972bd7f14960bd64c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 25 Oct 2019 21:26:21 +0300 Subject: [PATCH 28/41] pinctrl: lynxpoint: Add pin control data structures In order to implement pin control for Intel Lynxpoint, we need data structures in which to store and pass along pin, community and SoC data information. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 126 +++++++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 3c1b71204bbe..ea46bd64226d 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -18,6 +18,128 @@ #include #include +#include +#include +#include +#include + +#include "pinctrl-intel.h" + +#define COMMUNITY(p, n) \ + { \ + .pin_base = (p), \ + .npins = (n), \ + } + +static const struct pinctrl_pin_desc lptlp_pins[] = { + PINCTRL_PIN(0, "GP0_UART1_RXD"), + PINCTRL_PIN(1, "GP1_UART1_TXD"), + PINCTRL_PIN(2, "GP2_UART1_RTSB"), + PINCTRL_PIN(3, "GP3_UART1_CTSB"), + PINCTRL_PIN(4, "GP4_I2C0_SDA"), + PINCTRL_PIN(5, "GP5_I2C0_SCL"), + PINCTRL_PIN(6, "GP6_I2C1_SDA"), + PINCTRL_PIN(7, "GP7_I2C1_SCL"), + PINCTRL_PIN(8, "GP8"), + PINCTRL_PIN(9, "GP9"), + PINCTRL_PIN(10, "GP10"), + PINCTRL_PIN(11, "GP11_SMBALERTB"), + PINCTRL_PIN(12, "GP12_LANPHYPC"), + PINCTRL_PIN(13, "GP13"), + PINCTRL_PIN(14, "GP14"), + PINCTRL_PIN(15, "GP15"), + PINCTRL_PIN(16, "GP16_MGPIO9"), + PINCTRL_PIN(17, "GP17_MGPIO10"), + PINCTRL_PIN(18, "GP18_SRC0CLKRQB"), + PINCTRL_PIN(19, "GP19_SRC1CLKRQB"), + PINCTRL_PIN(20, "GP20_SRC2CLKRQB"), + PINCTRL_PIN(21, "GP21_SRC3CLKRQB"), + PINCTRL_PIN(22, "GP22_SRC4CLKRQB_TRST2"), + PINCTRL_PIN(23, "GP23_SRC5CLKRQB_TDI2"), + PINCTRL_PIN(24, "GP24_MGPIO0"), + PINCTRL_PIN(25, "GP25_USBWAKEOUTB"), + PINCTRL_PIN(26, "GP26_MGPIO5"), + PINCTRL_PIN(27, "GP27_MGPIO6"), + PINCTRL_PIN(28, "GP28_MGPIO7"), + PINCTRL_PIN(29, "GP29_SLP_WLANB_MGPIO3"), + PINCTRL_PIN(30, "GP30_SUSWARNB_SUSPWRDNACK_MGPIO1"), + PINCTRL_PIN(31, "GP31_ACPRESENT_MGPIO2"), + PINCTRL_PIN(32, "GP32_CLKRUNB"), + PINCTRL_PIN(33, "GP33_DEVSLP0"), + PINCTRL_PIN(34, "GP34_SATA0XPCIE6L3B_SATA0GP"), + PINCTRL_PIN(35, "GP35_SATA1XPCIE6L2B_SATA1GP"), + PINCTRL_PIN(36, "GP36_SATA2XPCIE6L1B_SATA2GP"), + PINCTRL_PIN(37, "GP37_SATA3XPCIE6L0B_SATA3GP"), + PINCTRL_PIN(38, "GP38_DEVSLP1"), + PINCTRL_PIN(39, "GP39_DEVSLP2"), + PINCTRL_PIN(40, "GP40_OC0B"), + PINCTRL_PIN(41, "GP41_OC1B"), + PINCTRL_PIN(42, "GP42_OC2B"), + PINCTRL_PIN(43, "GP43_OC3B"), + PINCTRL_PIN(44, "GP44"), + PINCTRL_PIN(45, "GP45_TMS2"), + PINCTRL_PIN(46, "GP46_TDO2"), + PINCTRL_PIN(47, "GP47"), + PINCTRL_PIN(48, "GP48"), + PINCTRL_PIN(49, "GP49"), + PINCTRL_PIN(50, "GP50"), + PINCTRL_PIN(51, "GP51_GSXDOUT"), + PINCTRL_PIN(52, "GP52_GSXSLOAD"), + PINCTRL_PIN(53, "GP53_GSXDIN"), + PINCTRL_PIN(54, "GP54_GSXSRESETB"), + PINCTRL_PIN(55, "GP55_GSXCLK"), + PINCTRL_PIN(56, "GP56"), + PINCTRL_PIN(57, "GP57"), + PINCTRL_PIN(58, "GP58"), + PINCTRL_PIN(59, "GP59"), + PINCTRL_PIN(60, "GP60_SML0ALERTB_MGPIO4"), + PINCTRL_PIN(61, "GP61_SUS_STATB"), + PINCTRL_PIN(62, "GP62_SUSCLK"), + PINCTRL_PIN(63, "GP63_SLP_S5B"), + PINCTRL_PIN(64, "GP64_SDIO_CLK"), + PINCTRL_PIN(65, "GP65_SDIO_CMD"), + PINCTRL_PIN(66, "GP66_SDIO_D0"), + PINCTRL_PIN(67, "GP67_SDIO_D1"), + PINCTRL_PIN(68, "GP68_SDIO_D2"), + PINCTRL_PIN(69, "GP69_SDIO_D3"), + PINCTRL_PIN(70, "GP70_SDIO_POWER_EN"), + PINCTRL_PIN(71, "GP71_MPHYPC"), + PINCTRL_PIN(72, "GP72_BATLOWB"), + PINCTRL_PIN(73, "GP73_SML1ALERTB_PCHHOTB_MGPIO8"), + PINCTRL_PIN(74, "GP74_SML1DATA_MGPIO12"), + PINCTRL_PIN(75, "GP75_SML1CLK_MGPIO11"), + PINCTRL_PIN(76, "GP76_BMBUSYB"), + PINCTRL_PIN(77, "GP77_PIRQAB"), + PINCTRL_PIN(78, "GP78_PIRQBB"), + PINCTRL_PIN(79, "GP79_PIRQCB"), + PINCTRL_PIN(80, "GP80_PIRQDB"), + PINCTRL_PIN(81, "GP81_SPKR"), + PINCTRL_PIN(82, "GP82_RCINB"), + PINCTRL_PIN(83, "GP83_GSPI0_CSB"), + PINCTRL_PIN(84, "GP84_GSPI0_CLK"), + PINCTRL_PIN(85, "GP85_GSPI0_MISO"), + PINCTRL_PIN(86, "GP86_GSPI0_MOSI"), + PINCTRL_PIN(87, "GP87_GSPI1_CSB"), + PINCTRL_PIN(88, "GP88_GSPI1_CLK"), + PINCTRL_PIN(89, "GP89_GSPI1_MISO"), + PINCTRL_PIN(90, "GP90_GSPI1_MOSI"), + PINCTRL_PIN(91, "GP91_UART0_RXD"), + PINCTRL_PIN(92, "GP92_UART0_TXD"), + PINCTRL_PIN(93, "GP93_UART0_RTSB"), + PINCTRL_PIN(94, "GP94_UART0_CTSB"), +}; + +static const struct intel_community lptlp_communities[] = { + COMMUNITY(0, 95), +}; + +static const struct intel_pinctrl_soc_data lptlp_soc_data = { + .pins = lptlp_pins, + .npins = ARRAY_SIZE(lptlp_pins), + .communities = lptlp_communities, + .ncommunities = ARRAY_SIZE(lptlp_communities), +}; + /* LynxPoint chipset has support for 95 GPIO pins */ #define LP_NUM_GPIO 95 @@ -477,8 +599,8 @@ static const struct dev_pm_ops lp_gpio_pm_ops = { }; static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = { - { "INT33C7", 0 }, - { "INT3437", 0 }, + { "INT33C7", (kernel_ulong_t)&lptlp_soc_data }, + { "INT3437", (kernel_ulong_t)&lptlp_soc_data }, { } }; MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match); From 18213ad4187d44f2b58e96529f169c3ae4898b51 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 20:49:44 +0200 Subject: [PATCH 29/41] pinctrl: lynxpoint: Reuse struct intel_pinctrl in the driver We may use now available struct intel_pinctrl in the driver. No functional change implied. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 84 ++++++++++++++++------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index ea46bd64226d..5a8c77c8306b 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -168,13 +168,6 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = { #define GPINDIS_BIT BIT(2) /* disable input sensing */ #define GPIWP_BIT (BIT(0) | BIT(1)) /* weak pull options */ -struct lp_gpio { - struct gpio_chip chip; - struct device *dev; - raw_spinlock_t lock; - void __iomem *regs; -}; - /* * Lynxpoint gpios are controlled through both bitmapped registers and * per gpio specific registers. The bitmapped registers are in chunks of @@ -204,12 +197,34 @@ struct lp_gpio { * LP94_CONFIG2 (gpio 94) ... */ +static struct intel_community *lp_get_community(struct intel_pinctrl *lg, + unsigned int pin) +{ + struct intel_community *comm; + int i; + + for (i = 0; i < lg->ncommunities; i++) { + comm = &lg->communities[i]; + if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) + return comm; + } + + return NULL; +} + static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset, int reg) { - struct lp_gpio *lg = gpiochip_get_data(chip); + struct intel_pinctrl *lg = gpiochip_get_data(chip); + struct intel_community *comm; int reg_offset; + comm = lp_get_community(lg, offset); + if (!comm) + return NULL; + + offset -= comm->pin_base; + if (reg == LP_CONFIG1 || reg == LP_CONFIG2) /* per gpio specific config registers */ reg_offset = offset * 8; @@ -217,10 +232,10 @@ static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset, /* bitmapped registers */ reg_offset = (offset / 32) * 4; - return lg->regs + reg + reg_offset; + return comm->regs + reg_offset + reg; } -static bool lp_gpio_acpi_use(struct lp_gpio *lg, unsigned int pin) +static bool lp_gpio_acpi_use(struct intel_pinctrl *lg, unsigned int pin) { void __iomem *acpi_use; @@ -233,7 +248,7 @@ static bool lp_gpio_acpi_use(struct lp_gpio *lg, unsigned int pin) static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset) { - struct lp_gpio *lg = gpiochip_get_data(chip); + struct intel_pinctrl *lg = gpiochip_get_data(chip); void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); u32 value; @@ -259,7 +274,7 @@ static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset) static void lp_gpio_free(struct gpio_chip *chip, unsigned int offset) { - struct lp_gpio *lg = gpiochip_get_data(chip); + struct intel_pinctrl *lg = gpiochip_get_data(chip); void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); /* disable input sensing */ @@ -276,7 +291,7 @@ static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset) static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { - struct lp_gpio *lg = gpiochip_get_data(chip); + struct intel_pinctrl *lg = gpiochip_get_data(chip); void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); unsigned long flags; @@ -292,7 +307,7 @@ static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { - struct lp_gpio *lg = gpiochip_get_data(chip); + struct intel_pinctrl *lg = gpiochip_get_data(chip); void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); unsigned long flags; @@ -306,7 +321,7 @@ static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { - struct lp_gpio *lg = gpiochip_get_data(chip); + struct intel_pinctrl *lg = gpiochip_get_data(chip); void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); unsigned long flags; @@ -333,7 +348,7 @@ static void lp_gpio_irq_handler(struct irq_desc *desc) { struct irq_data *data = irq_desc_get_irq_data(desc); struct gpio_chip *gc = irq_desc_get_handler_data(desc); - struct lp_gpio *lg = gpiochip_get_data(gc); + struct intel_pinctrl *lg = gpiochip_get_data(gc); struct irq_chip *chip = irq_data_get_irq_chip(data); void __iomem *reg, *ena; unsigned long pending; @@ -360,7 +375,7 @@ static void lp_gpio_irq_handler(struct irq_desc *desc) static void lp_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct lp_gpio *lg = gpiochip_get_data(gc); + struct intel_pinctrl *lg = gpiochip_get_data(gc); u32 hwirq = irqd_to_hwirq(d); void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_STAT); unsigned long flags; @@ -381,7 +396,7 @@ static void lp_irq_mask(struct irq_data *d) static void lp_irq_enable(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct lp_gpio *lg = gpiochip_get_data(gc); + struct intel_pinctrl *lg = gpiochip_get_data(gc); u32 hwirq = irqd_to_hwirq(d); void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); unsigned long flags; @@ -394,7 +409,7 @@ static void lp_irq_enable(struct irq_data *d) static void lp_irq_disable(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct lp_gpio *lg = gpiochip_get_data(gc); + struct intel_pinctrl *lg = gpiochip_get_data(gc); u32 hwirq = irqd_to_hwirq(d); void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); unsigned long flags; @@ -407,7 +422,7 @@ static void lp_irq_disable(struct irq_data *d) static int lp_irq_set_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct lp_gpio *lg = gpiochip_get_data(gc); + struct intel_pinctrl *lg = gpiochip_get_data(gc); u32 hwirq = irqd_to_hwirq(d); void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1); unsigned long flags; @@ -466,7 +481,7 @@ static struct irq_chip lp_irqchip = { static int lp_gpio_irq_init_hw(struct gpio_chip *chip) { - struct lp_gpio *lg = gpiochip_get_data(chip); + struct intel_pinctrl *lg = gpiochip_get_data(chip); void __iomem *reg; unsigned int base; @@ -484,18 +499,32 @@ static int lp_gpio_irq_init_hw(struct gpio_chip *chip) static int lp_gpio_probe(struct platform_device *pdev) { - struct lp_gpio *lg; + const struct intel_pinctrl_soc_data *soc; + struct intel_pinctrl *lg; struct gpio_chip *gc; struct resource *io_rc, *irq_rc; struct device *dev = &pdev->dev; void __iomem *regs; + unsigned int i; int ret; + soc = (const struct intel_pinctrl_soc_data *)device_get_match_data(dev); + if (!soc) + return -ENODEV; + lg = devm_kzalloc(dev, sizeof(*lg), GFP_KERNEL); if (!lg) return -ENOMEM; lg->dev = dev; + lg->soc = soc; + + lg->ncommunities = lg->soc->ncommunities; + lg->communities = devm_kcalloc(dev, lg->ncommunities, + sizeof(*lg->communities), GFP_KERNEL); + if (!lg->communities) + return -ENOMEM; + platform_set_drvdata(pdev, lg); io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0); @@ -510,7 +539,14 @@ static int lp_gpio_probe(struct platform_device *pdev) return -EBUSY; } - lg->regs = regs; + for (i = 0; i < lg->soc->ncommunities; i++) { + struct intel_community *comm = &lg->communities[i]; + + *comm = lg->soc->communities[i]; + + comm->regs = regs; + comm->pad_regs = regs + 0x100; + } raw_spin_lock_init(&lg->lock); @@ -578,7 +614,7 @@ static int lp_gpio_runtime_resume(struct device *dev) static int lp_gpio_resume(struct device *dev) { - struct lp_gpio *lg = dev_get_drvdata(dev); + struct intel_pinctrl *lg = dev_get_drvdata(dev); void __iomem *reg; int i; From 7f32d37009974c52323335cf8d118384fbce3572 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 20 Nov 2019 21:31:11 +0200 Subject: [PATCH 30/41] pinctrl: lynxpoint: Add pin control operations Add implementation for: - pin control, group information retrieval: count, name and pins - pin muxing: - function information (count, name and groups) - mux setting - GPIO control (enable, disable, set direction) - pin configuration: - pull disable, up and down - any other option is treated as not supported. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 315 +++++++++++++++++++++- 1 file changed, 314 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 5a8c77c8306b..c209deff9efb 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -146,6 +146,7 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = { /* Bitmapped register offsets */ #define LP_ACPI_OWNED 0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */ +#define LP_IRQ2IOXAPIC 0x10 /* Bitmap, set by bios, 1: pin routed to IOxAPIC */ #define LP_GC 0x7C /* set APIC IRQ to IRQ14 or IRQ15 for all pins */ #define LP_INT_STAT 0x80 #define LP_INT_ENABLE 0x90 @@ -166,7 +167,10 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = { /* LP_CONFIG2 reg bits */ #define GPINDIS_BIT BIT(2) /* disable input sensing */ -#define GPIWP_BIT (BIT(0) | BIT(1)) /* weak pull options */ +#define GPIWP_MASK GENMASK(1, 0) /* weak pull options */ +#define GPIWP_NONE 0 /* none */ +#define GPIWP_DOWN 1 /* weak pull down */ +#define GPIWP_UP 2 /* weak pull up */ /* * Lynxpoint gpios are controlled through both bitmapped registers and @@ -195,6 +199,8 @@ static const struct intel_pinctrl_soc_data lptlp_soc_data = { * ... * LP94_CONFIG1 (gpio 94) ... * LP94_CONFIG2 (gpio 94) ... + * + * IOxAPIC redirection map applies only for gpio 8-10, 13-14, 45-55. */ static struct intel_community *lp_get_community(struct intel_pinctrl *lg, @@ -246,6 +252,308 @@ static bool lp_gpio_acpi_use(struct intel_pinctrl *lg, unsigned int pin) return !(ioread32(acpi_use) & BIT(pin % 32)); } +static bool lp_gpio_ioxapic_use(struct gpio_chip *chip, unsigned int offset) +{ + void __iomem *ioxapic_use = lp_gpio_reg(chip, offset, LP_IRQ2IOXAPIC); + u32 value; + + value = ioread32(ioxapic_use); + + if (offset >= 8 && offset <= 10) + return !!(value & BIT(offset - 8 + 0)); + if (offset >= 13 && offset <= 14) + return !!(value & BIT(offset - 13 + 3)); + if (offset >= 45 && offset <= 55) + return !!(value & BIT(offset - 45 + 5)); + + return false; +} + +static int lp_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + return lg->soc->ngroups; +} + +static const char *lp_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + return lg->soc->groups[selector].name; +} + +static int lp_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + *pins = lg->soc->groups[selector].pins; + *num_pins = lg->soc->groups[selector].npins; + + return 0; +} + +static const struct pinctrl_ops lptlp_pinctrl_ops = { + .get_groups_count = lp_get_groups_count, + .get_group_name = lp_get_group_name, + .get_group_pins = lp_get_group_pins, +}; + +static int lp_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + return lg->soc->nfunctions; +} + +static const char *lp_get_function_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + return lg->soc->functions[selector].name; +} + +static int lp_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned int *num_groups) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + *groups = lg->soc->functions[selector].groups; + *num_groups = lg->soc->functions[selector].ngroups; + + return 0; +} + +static int lp_pinmux_set_mux(struct pinctrl_dev *pctldev, + unsigned int function, unsigned int group) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pingroup *grp = &lg->soc->groups[group]; + unsigned long flags; + int i; + + raw_spin_lock_irqsave(&lg->lock, flags); + + /* Now enable the mux setting for each pin in the group */ + for (i = 0; i < grp->npins; i++) { + void __iomem *reg = lp_gpio_reg(&lg->chip, grp->pins[i], LP_CONFIG1); + u32 value; + + value = ioread32(reg); + + value &= ~USE_SEL_MASK; + if (grp->modes) + value |= grp->modes[i]; + else + value |= grp->mode; + + iowrite32(value, reg); + } + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + return 0; +} + +static int lp_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1); + void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2); + unsigned long flags; + u32 value; + + pm_runtime_get(lg->dev); + + raw_spin_lock_irqsave(&lg->lock, flags); + + /* + * Reconfigure pin to GPIO mode if needed and issue a warning, + * since we expect firmware to configure it properly. + */ + value = ioread32(reg); + if ((value & USE_SEL_MASK) != USE_SEL_GPIO) { + iowrite32((value & USE_SEL_MASK) | USE_SEL_GPIO, reg); + dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", pin); + } + + /* Enable input sensing */ + iowrite32(ioread32(conf2) & ~GPINDIS_BIT, conf2); + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + return 0; +} + +static void lp_gpio_disable_free(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2); + unsigned long flags; + + raw_spin_lock_irqsave(&lg->lock, flags); + + /* Disable input sensing */ + iowrite32(ioread32(conf2) | GPINDIS_BIT, conf2); + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + pm_runtime_put(lg->dev); +} + +static int lp_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin, bool input) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1); + unsigned long flags; + u32 value; + + raw_spin_lock_irqsave(&lg->lock, flags); + + value = ioread32(reg); + value &= ~DIR_BIT; + if (input) { + value |= DIR_BIT; + } else { + /* + * Before making any direction modifications, do a check if GPIO + * is set for direct IRQ. On Lynxpoint, setting GPIO to output + * does not make sense, so let's at least warn the caller before + * they shoot themselves in the foot. + */ + WARN(lp_gpio_ioxapic_use(&lg->chip, pin), + "Potential Error: Setting GPIO to output with IOxAPIC redirection"); + } + iowrite32(value, reg); + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + return 0; +} + +static const struct pinmux_ops lptlp_pinmux_ops = { + .get_functions_count = lp_get_functions_count, + .get_function_name = lp_get_function_name, + .get_function_groups = lp_get_function_groups, + .set_mux = lp_pinmux_set_mux, + .gpio_request_enable = lp_gpio_request_enable, + .gpio_disable_free = lp_gpio_disable_free, + .gpio_set_direction = lp_gpio_set_direction, +}; + +static int lp_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2); + enum pin_config_param param = pinconf_to_config_param(*config); + unsigned long flags; + u32 value, pull; + u16 arg = 0; + + raw_spin_lock_irqsave(&lg->lock, flags); + value = ioread32(conf2); + raw_spin_unlock_irqrestore(&lg->lock, flags); + + pull = value & GPIWP_MASK; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (pull) + return -EINVAL; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + if (pull != GPIWP_DOWN) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_BIAS_PULL_UP: + if (pull != GPIWP_UP) + return -EINVAL; + + arg = 1; + break; + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + +static int lp_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2); + enum pin_config_param param; + unsigned long flags; + int i, ret = 0; + u32 value; + + raw_spin_lock_irqsave(&lg->lock, flags); + + value = ioread32(conf2); + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + value &= ~GPIWP_MASK; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + value &= ~GPIWP_MASK; + value |= GPIWP_DOWN; + break; + case PIN_CONFIG_BIAS_PULL_UP: + value &= ~GPIWP_MASK; + value |= GPIWP_UP; + break; + default: + ret = -ENOTSUPP; + } + + if (ret) + break; + } + + if (!ret) + iowrite32(value, conf2); + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + return ret; +} + +static const struct pinconf_ops lptlp_pinconf_ops = { + .is_generic = true, + .pin_config_get = lp_pin_config_get, + .pin_config_set = lp_pin_config_set, +}; + +static const struct pinctrl_desc lptlp_pinctrl_desc = { + .pctlops = &lptlp_pinctrl_ops, + .pmxops = &lptlp_pinmux_ops, + .confops = &lptlp_pinconf_ops, + .owner = THIS_MODULE, +}; + static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset) { struct intel_pinctrl *lg = gpiochip_get_data(chip); @@ -525,6 +833,11 @@ static int lp_gpio_probe(struct platform_device *pdev) if (!lg->communities) return -ENOMEM; + lg->pctldesc = lptlp_pinctrl_desc; + lg->pctldesc.name = dev_name(dev); + lg->pctldesc.pins = lg->soc->pins; + lg->pctldesc.npins = lg->soc->npins; + platform_set_drvdata(pdev, lg); io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0); From 03d9eca7d40608197bb20c584a6da97b3399559b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 20:14:03 +0200 Subject: [PATCH 31/41] pinctrl: lynxpoint: Implement ->pin_dbg_show() The introduced callback ->pin_dbg_show() is useful for debugging. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index c209deff9efb..bfdd283d2c20 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -297,10 +297,33 @@ static int lp_get_group_pins(struct pinctrl_dev *pctldev, return 0; } +static void lp_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned int pin) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1); + void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2); + u32 value, mode; + + value = ioread32(reg); + + mode = value & USE_SEL_MASK; + if (mode == USE_SEL_GPIO) + seq_puts(s, "GPIO "); + else + seq_printf(s, "mode %d ", mode); + + seq_printf(s, "0x%08x 0x%08x", value, ioread32(conf2)); + + if (lp_gpio_acpi_use(lg, pin)) + seq_puts(s, " [ACPI]"); +} + static const struct pinctrl_ops lptlp_pinctrl_ops = { .get_groups_count = lp_get_groups_count, .get_group_name = lp_get_group_name, .get_group_pins = lp_get_group_pins, + .pin_dbg_show = lp_pin_dbg_show, }; static int lp_get_functions_count(struct pinctrl_dev *pctldev) From 3683509c3910cb377913dcd430447ad48f676b31 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 4 Nov 2019 19:07:30 +0200 Subject: [PATCH 32/41] pinctrl: lynxpoint: Add GPIO <-> pin mapping ranges via callback When IRQ chip is instantiated via GPIO library flow, the few functions, in particular the ACPI event registration mechanism, on some of ACPI based platforms expect that the pin ranges are initialized to that point. Add GPIO <-> pin mapping ranges via callback in the GPIO library flow. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index bfdd283d2c20..795a9c7054ca 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -828,6 +828,19 @@ static int lp_gpio_irq_init_hw(struct gpio_chip *chip) return 0; } +static int lp_gpio_add_pin_ranges(struct gpio_chip *chip) +{ + struct intel_pinctrl *lg = gpiochip_get_data(chip); + struct device *dev = lg->dev; + int ret; + + ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, lg->soc->npins); + if (ret) + dev_err(dev, "failed to add GPIO pin range\n"); + + return ret; +} + static int lp_gpio_probe(struct platform_device *pdev) { const struct intel_pinctrl_soc_data *soc; @@ -899,6 +912,7 @@ static int lp_gpio_probe(struct platform_device *pdev) gc->base = -1; gc->ngpio = LP_NUM_GPIO; gc->can_sleep = false; + gc->add_pin_ranges = lp_gpio_add_pin_ranges; gc->parent = dev; /* set up interrupts */ From 64e14e90646cafa9940cead9f7ba336c55671bf9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 19:30:57 +0200 Subject: [PATCH 33/41] pinctrl: lynxpoint: Switch to pin control API When all preparations are done, we may switch to pin control API. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/Kconfig | 3 + drivers/pinctrl/intel/pinctrl-lynxpoint.c | 67 ++++------------------- 2 files changed, 13 insertions(+), 57 deletions(-) diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index c2e6bc9e3e04..ee440ec4c94c 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig @@ -34,6 +34,9 @@ config PINCTRL_CHERRYVIEW config PINCTRL_LYNXPOINT tristate "Intel Lynxpoint pinctrl and GPIO driver" depends on ACPI + select PINMUX + select PINCONF + select GENERIC_PINCONF select GPIOLIB select GPIOLIB_IRQCHIP help diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 795a9c7054ca..774b226f3a4d 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -577,43 +577,6 @@ static const struct pinctrl_desc lptlp_pinctrl_desc = { .owner = THIS_MODULE, }; -static int lp_gpio_request(struct gpio_chip *chip, unsigned int offset) -{ - struct intel_pinctrl *lg = gpiochip_get_data(chip); - void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); - void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); - u32 value; - - pm_runtime_get(lg->dev); /* should we put if failed */ - - /* - * Reconfigure pin to GPIO mode if needed and issue a warning, - * since we expect firmware to configure it properly. - */ - value = ioread32(reg); - if ((value & USE_SEL_MASK) != USE_SEL_GPIO) { - iowrite32((value & USE_SEL_MASK) | USE_SEL_GPIO, reg); - dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", offset); - } - - /* enable input sensing */ - iowrite32(ioread32(conf2) & ~GPINDIS_BIT, conf2); - - - return 0; -} - -static void lp_gpio_free(struct gpio_chip *chip, unsigned int offset) -{ - struct intel_pinctrl *lg = gpiochip_get_data(chip); - void __iomem *conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2); - - /* disable input sensing */ - iowrite32(ioread32(conf2) | GPINDIS_BIT, conf2); - - pm_runtime_put(lg->dev); -} - static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset) { void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); @@ -638,31 +601,15 @@ static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { - struct intel_pinctrl *lg = gpiochip_get_data(chip); - void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); - unsigned long flags; - - raw_spin_lock_irqsave(&lg->lock, flags); - iowrite32(ioread32(reg) | DIR_BIT, reg); - raw_spin_unlock_irqrestore(&lg->lock, flags); - - return 0; + return pinctrl_gpio_direction_input(chip->base + offset); } static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { - struct intel_pinctrl *lg = gpiochip_get_data(chip); - void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); - unsigned long flags; - lp_gpio_set(chip, offset, value); - raw_spin_lock_irqsave(&lg->lock, flags); - iowrite32(ioread32(reg) & ~DIR_BIT, reg); - raw_spin_unlock_irqrestore(&lg->lock, flags); - - return 0; + return pinctrl_gpio_direction_output(chip->base + offset); } static int lp_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) @@ -874,6 +821,12 @@ static int lp_gpio_probe(struct platform_device *pdev) lg->pctldesc.pins = lg->soc->pins; lg->pctldesc.npins = lg->soc->npins; + lg->pctldev = devm_pinctrl_register(dev, &lg->pctldesc, lg); + if (IS_ERR(lg->pctldev)) { + dev_err(dev, "failed to register pinctrl driver\n"); + return PTR_ERR(lg->pctldev); + } + platform_set_drvdata(pdev, lg); io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0); @@ -902,8 +855,8 @@ static int lp_gpio_probe(struct platform_device *pdev) gc = &lg->chip; gc->label = dev_name(dev); gc->owner = THIS_MODULE; - gc->request = lp_gpio_request; - gc->free = lp_gpio_free; + gc->request = gpiochip_generic_request; + gc->free = gpiochip_generic_free; gc->direction_input = lp_gpio_direction_input; gc->direction_output = lp_gpio_direction_output; gc->get = lp_gpio_get; From 3a67fe38e76a590d2c8ce4731cd64fbd477e5f79 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Nov 2019 17:45:45 +0200 Subject: [PATCH 34/41] pinctrl: lynxpoint: Update summary in the driver Reflect in the driver that it is now a pin control one. While here, update copyright years and authors. Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 774b226f3a4d..e928742c7181 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -1,9 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 /* - * GPIO controller driver for Intel Lynxpoint PCH chipset> - * Copyright (c) 2012, Intel Corporation. + * Intel Lynxpoint PCH pinctrl/GPIO driver * - * Author: Mathias Nyman + * Copyright (c) 2012, 2019, Intel Corporation + * Authors: Mathias Nyman + * Andy Shevchenko */ #include @@ -968,6 +969,7 @@ subsys_initcall(lp_gpio_init); module_exit(lp_gpio_exit); MODULE_AUTHOR("Mathias Nyman (Intel)"); -MODULE_DESCRIPTION("GPIO interface for Intel Lynxpoint"); +MODULE_AUTHOR("Andy Shevchenko (Intel)"); +MODULE_DESCRIPTION("Intel Lynxpoint pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:lp_gpio"); From f0682757230bdfc58118125dc81d805a427766b8 Mon Sep 17 00:00:00 2001 From: Boyan Ding Date: Wed, 1 Jan 2020 12:41:20 -0800 Subject: [PATCH 35/41] pinctrl: sunrisepoint: Add missing Interrupt Status register offset Commit 179e5a6114cc ("pinctrl: intel: Remove default Interrupt Status offset") removes default interrupt status offset of GPIO controllers, with previous commits explicitly providing the previously default offsets. However, the is_offset value in SPTH_COMMUNITY is missing, preventing related irq from being properly detected and handled. Fixes: f702e0b93cdb ("pinctrl: sunrisepoint: Provide Interrupt Status register offset") Link: https://bugzilla.kernel.org/show_bug.cgi?id=205745 Cc: stable@vger.kernel.org Signed-off-by: Boyan Ding Acked-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-sunrisepoint.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c index 44d7f50bbc82..d936e7aa74c4 100644 --- a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c +++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c @@ -49,6 +49,7 @@ .padown_offset = SPT_PAD_OWN, \ .padcfglock_offset = SPT_PADCFGLOCK, \ .hostown_offset = SPT_HOSTSW_OWN, \ + .is_offset = SPT_GPI_IS, \ .ie_offset = SPT_GPI_IE, \ .pin_base = (s), \ .npins = ((e) - (s) + 1), \ From a23680594da7a9e2696dbcf4f023e9273e2fa40b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 28 Dec 2019 00:04:47 +0100 Subject: [PATCH 36/41] pinctrl: baytrail: Do not clear IRQ flags on direct-irq enabled pins Suspending Goodix touchscreens requires changing the interrupt pin to output before sending them a power-down command. Followed by wiggling the interrupt pin to wake the device up, after which it is put back in input mode. On Bay Trail devices with a Goodix touchscreen direct-irq mode is used in combination with listing the pin as a normal GpioIo resource. This works fine, until the goodix driver gets rmmod-ed and then insmod-ed again. In this case byt_gpio_disable_free() calls byt_gpio_clear_triggering() which clears the IRQ flags and after that the (direct) IRQ no longer triggers. This commit fixes this by adding a check for the BYT_DIRECT_IRQ_EN flag to byt_gpio_clear_triggering(). Note that byt_gpio_clear_triggering() only gets called from byt_gpio_disable_free() for direct-irq enabled pins, as these are excluded from the irq_valid mask by byt_init_irq_valid_mask(). Signed-off-by: Hans de Goede Acked-by: Mika Westerberg Reviewed-by: Linus Walleij Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-baytrail.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index cb0c04c5269c..394d9cc38cc2 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -742,7 +742,13 @@ static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int off raw_spin_lock_irqsave(&byt_lock, flags); value = readl(reg); - value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + + /* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */ + if (value & BYT_DIRECT_IRQ_EN) + /* nothing to do */ ; + else + value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + writel(value, reg); raw_spin_unlock_irqrestore(&byt_lock, flags); } From e2b74419e5cc7cfc58f3e785849f73f8fa0af5b3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 1 Jan 2020 15:52:43 +0100 Subject: [PATCH 37/41] pinctrl: baytrail: Replace WARN with dev_info_once when setting direct-irq pin to output Suspending Goodix touchscreens requires changing the interrupt pin to output before sending them a power-down command. Followed by wiggling the interrupt pin to wake the device up, after which it is put back in input mode. On Cherry Trail device the interrupt pin is listed as a GpioInt ACPI resource so we can do this without problems as long as we release the IRQ before changing the pin to output mode. On Bay Trail devices with a Goodix touchscreen direct-irq mode is used in combination with listing the pin as a normal GpioIo resource. This works fine, but this triggers the WARN in byt_gpio_set_direction-s output path because direct-irq support is enabled on the pin. This commit replaces the WARN call with a dev_info_once call, fixing a bunch of WARN splats in dmesg on each suspend/resume cycle. Signed-off-by: Hans de Goede Acked-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-baytrail.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 394d9cc38cc2..b409642f168d 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -817,15 +817,15 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, value &= ~BYT_DIR_MASK; if (input) value |= BYT_OUTPUT_EN; - else + 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 warn the caller before + * does not make sense, so let's at least inform the caller before * they shoot themselves in the foot. */ - WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, - "Potential Error: Setting GPIO with direct_irq_en to output"); + dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); + writel(value, val_reg); raw_spin_unlock_irqrestore(&byt_lock, flags); From 6d416b9bb577cc3013301cfccb0d938567af489d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Jan 2020 08:53:28 +0100 Subject: [PATCH 38/41] pinctrl: intel: Add GPIO <-> pin mapping ranges via callback When IRQ chip is instantiated via GPIO library flow, the few functions, in particular the ACPI event registration mechanism, on some of ACPI based platforms expect that the pin ranges are initialized to that point. Add GPIO <-> pin mapping ranges via callback in the GPIO library flow. Cc: Hans de Goede Signed-off-by: Linus Walleij Acked-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-intel.c | 35 +++++++++++++++++---------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 06be75a636ba..2f4629bbb313 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -1130,8 +1130,8 @@ static irqreturn_t intel_gpio_irq(int irq, void *data) return ret; } -static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl, - const struct intel_community *community) +static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl, + const struct intel_community *community) { int ret = 0, i; @@ -1151,6 +1151,24 @@ static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl, return ret; } +static int intel_gpio_add_pin_ranges(struct gpio_chip *gc) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + int ret, i; + + for (i = 0; i < pctrl->ncommunities; i++) { + struct intel_community *community = &pctrl->communities[i]; + + ret = intel_gpio_add_community_ranges(pctrl, community); + if (ret) { + dev_err(pctrl->dev, "failed to add GPIO pin range\n"); + return ret; + } + } + + return 0; +} + static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl) { const struct intel_community *community; @@ -1175,7 +1193,7 @@ static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl) static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) { - int ret, i; + int ret; pctrl->chip = intel_gpio_chip; @@ -1184,6 +1202,7 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) pctrl->chip.label = dev_name(pctrl->dev); pctrl->chip.parent = pctrl->dev; pctrl->chip.base = -1; + pctrl->chip.add_pin_ranges = intel_gpio_add_pin_ranges; pctrl->irq = irq; /* Setup IRQ chip */ @@ -1201,16 +1220,6 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) return ret; } - for (i = 0; i < pctrl->ncommunities; i++) { - struct intel_community *community = &pctrl->communities[i]; - - ret = intel_gpio_add_pin_ranges(pctrl, community); - if (ret) { - dev_err(pctrl->dev, "failed to add GPIO pin range\n"); - return ret; - } - } - /* * We need to request the interrupt here (instead of providing chip * to the irq directly) because on some platforms several GPIO From af0c5330916a1ffd6cc0ffd6bea50688d99bf444 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Jan 2020 08:53:29 +0100 Subject: [PATCH 39/41] pinctrl: intel: Pass irqchip when adding gpiochip We need to convert all old gpio irqchips to pass the irqchip setup along when adding the gpio_chip. For more info see drivers/gpio/TODO. For chained irqchips this is a pretty straight-forward conversion. Cc: Hans de Goede Signed-off-by: Linus Walleij Acked-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-intel.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 2f4629bbb313..74fdfd2b9ff5 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -1194,6 +1194,7 @@ static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl) static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) { int ret; + struct gpio_irq_chip *girq; pctrl->chip = intel_gpio_chip; @@ -1214,16 +1215,9 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) pctrl->irqchip.irq_set_wake = intel_gpio_irq_wake; pctrl->irqchip.flags = IRQCHIP_MASK_ON_SUSPEND; - ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl); - if (ret) { - dev_err(pctrl->dev, "failed to register gpiochip\n"); - return ret; - } - /* - * We need to request the interrupt here (instead of providing chip - * to the irq directly) because on some platforms several GPIO - * controllers share the same interrupt line. + * On some platforms several GPIO controllers share the same interrupt + * line. */ ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq, IRQF_SHARED | IRQF_NO_THREAD, @@ -1233,14 +1227,20 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) return ret; } - ret = gpiochip_irqchip_add(&pctrl->chip, &pctrl->irqchip, 0, - handle_bad_irq, IRQ_TYPE_NONE); + girq = &pctrl->chip.irq; + girq->chip = &pctrl->irqchip; + /* This will let us handle the IRQ in the driver */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_bad_irq; + + ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl); if (ret) { - dev_err(pctrl->dev, "failed to add irqchip\n"); + dev_err(pctrl->dev, "failed to register gpiochip\n"); return ret; } - gpiochip_set_chained_irqchip(&pctrl->chip, &pctrl->irqchip, irq, NULL); return 0; } From 899b7e3374b253888b048dd06338e043e4b7637c Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 16 Jan 2020 13:09:51 +0200 Subject: [PATCH 40/41] pinctrl: sunrisepoint: Add Coffee Lake-S ACPI ID Intel Coffee Lake-S PCH has the same GPIO hardware than Sunrisepoint-H PCH but the ACPI ID is different. Add this new ACPI ID to the list of supported devices. Signed-off-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-sunrisepoint.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c index d936e7aa74c4..330c8f077b73 100644 --- a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c +++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c @@ -589,6 +589,7 @@ static const struct intel_pinctrl_soc_data spth_soc_data = { static const struct acpi_device_id spt_pinctrl_acpi_match[] = { { "INT344B", (kernel_ulong_t)&sptlp_soc_data }, + { "INT3451", (kernel_ulong_t)&spth_soc_data }, { "INT345D", (kernel_ulong_t)&spth_soc_data }, { } }; From cd0a32371db73d0b50536a7ca4f036abddff0d1d Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 16 Jan 2020 14:09:02 +0300 Subject: [PATCH 41/41] pinctrl: tigerlake: Tiger Lake uses _HID enumeration Turns out that Tiger Lake GPIO will be enumerated using _HID method where there is only a single ACPI device and multiple BARs so rework the driver to support that scheme instead. Fixes: c9ccf71fc807 ("pinctrl: intel: Add Intel Tiger Lake pin controller support") Signed-off-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-tigerlake.c | 561 ++++++++++------------ 1 file changed, 257 insertions(+), 304 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-tigerlake.c b/drivers/pinctrl/intel/pinctrl-tigerlake.c index 58572b15b3ce..08a86f6fdea6 100644 --- a/drivers/pinctrl/intel/pinctrl-tigerlake.c +++ b/drivers/pinctrl/intel/pinctrl-tigerlake.c @@ -2,7 +2,7 @@ /* * Intel Tiger Lake PCH pinctrl/GPIO driver * - * Copyright (C) 2019, Intel Corporation + * Copyright (C) 2019 - 2020, Intel Corporation * Authors: Andy Shevchenko * Mika Westerberg */ @@ -21,15 +21,19 @@ #define TGL_GPI_IS 0x100 #define TGL_GPI_IE 0x120 -#define TGL_GPP(r, s, e) \ +#define TGL_NO_GPIO -1 + +#define TGL_GPP(r, s, e, g) \ { \ .reg_num = (r), \ .base = (s), \ .size = ((e) - (s) + 1), \ + .gpio_base = (g), \ } -#define TGL_COMMUNITY(s, e, g) \ +#define TGL_COMMUNITY(b, s, e, g) \ { \ + .barno = (b), \ .padown_offset = TGL_PAD_OWN, \ .padcfglock_offset = TGL_PADCFGLOCK, \ .hostown_offset = TGL_HOSTSW_OWN, \ @@ -42,7 +46,7 @@ } /* Tiger Lake-LP */ -static const struct pinctrl_pin_desc tgllp_community0_pins[] = { +static const struct pinctrl_pin_desc tgllp_pins[] = { /* GPP_B */ PINCTRL_PIN(0, "CORE_VID_0"), PINCTRL_PIN(1, "CORE_VID_1"), @@ -113,324 +117,273 @@ static const struct pinctrl_pin_desc tgllp_community0_pins[] = { PINCTRL_PIN(64, "GPPC_A_22"), PINCTRL_PIN(65, "I2S1_SCLK"), PINCTRL_PIN(66, "ESPI_CLK_LOOPBK"), + /* GPP_S */ + PINCTRL_PIN(67, "SNDW0_CLK"), + PINCTRL_PIN(68, "SNDW0_DATA"), + PINCTRL_PIN(69, "SNDW1_CLK"), + PINCTRL_PIN(70, "SNDW1_DATA"), + PINCTRL_PIN(71, "SNDW2_CLK"), + PINCTRL_PIN(72, "SNDW2_DATA"), + PINCTRL_PIN(73, "SNDW3_CLK"), + PINCTRL_PIN(74, "SNDW3_DATA"), + /* GPP_H */ + PINCTRL_PIN(75, "GPPC_H_0"), + PINCTRL_PIN(76, "GPPC_H_1"), + PINCTRL_PIN(77, "GPPC_H_2"), + PINCTRL_PIN(78, "SX_EXIT_HOLDOFFB"), + PINCTRL_PIN(79, "I2C2_SDA"), + PINCTRL_PIN(80, "I2C2_SCL"), + PINCTRL_PIN(81, "I2C3_SDA"), + PINCTRL_PIN(82, "I2C3_SCL"), + PINCTRL_PIN(83, "I2C4_SDA"), + PINCTRL_PIN(84, "I2C4_SCL"), + PINCTRL_PIN(85, "SRCCLKREQB_4"), + PINCTRL_PIN(86, "SRCCLKREQB_5"), + PINCTRL_PIN(87, "M2_SKT2_CFG_0"), + PINCTRL_PIN(88, "M2_SKT2_CFG_1"), + PINCTRL_PIN(89, "M2_SKT2_CFG_2"), + PINCTRL_PIN(90, "M2_SKT2_CFG_3"), + PINCTRL_PIN(91, "DDPB_CTRLCLK"), + PINCTRL_PIN(92, "DDPB_CTRLDATA"), + PINCTRL_PIN(93, "CPU_C10_GATEB"), + PINCTRL_PIN(94, "TIME_SYNC_0"), + PINCTRL_PIN(95, "IMGCLKOUT_1"), + PINCTRL_PIN(96, "IMGCLKOUT_2"), + PINCTRL_PIN(97, "IMGCLKOUT_3"), + PINCTRL_PIN(98, "IMGCLKOUT_4"), + /* GPP_D */ + PINCTRL_PIN(99, "ISH_GP_0"), + PINCTRL_PIN(100, "ISH_GP_1"), + PINCTRL_PIN(101, "ISH_GP_2"), + PINCTRL_PIN(102, "ISH_GP_3"), + PINCTRL_PIN(103, "IMGCLKOUT_0"), + PINCTRL_PIN(104, "SRCCLKREQB_0"), + PINCTRL_PIN(105, "SRCCLKREQB_1"), + PINCTRL_PIN(106, "SRCCLKREQB_2"), + PINCTRL_PIN(107, "SRCCLKREQB_3"), + PINCTRL_PIN(108, "ISH_SPI_CSB"), + PINCTRL_PIN(109, "ISH_SPI_CLK"), + PINCTRL_PIN(110, "ISH_SPI_MISO"), + PINCTRL_PIN(111, "ISH_SPI_MOSI"), + PINCTRL_PIN(112, "ISH_UART0_RXD"), + PINCTRL_PIN(113, "ISH_UART0_TXD"), + PINCTRL_PIN(114, "ISH_UART0_RTSB"), + PINCTRL_PIN(115, "ISH_UART0_CTSB"), + PINCTRL_PIN(116, "ISH_GP_4"), + PINCTRL_PIN(117, "ISH_GP_5"), + PINCTRL_PIN(118, "I2S_MCLK1_OUT"), + PINCTRL_PIN(119, "GSPI2_CLK_LOOPBK"), + /* GPP_U */ + PINCTRL_PIN(120, "UART3_RXD"), + PINCTRL_PIN(121, "UART3_TXD"), + PINCTRL_PIN(122, "UART3_RTSB"), + PINCTRL_PIN(123, "UART3_CTSB"), + PINCTRL_PIN(124, "GSPI3_CS0B"), + PINCTRL_PIN(125, "GSPI3_CLK"), + PINCTRL_PIN(126, "GSPI3_MISO"), + PINCTRL_PIN(127, "GSPI3_MOSI"), + PINCTRL_PIN(128, "GSPI4_CS0B"), + PINCTRL_PIN(129, "GSPI4_CLK"), + PINCTRL_PIN(130, "GSPI4_MISO"), + PINCTRL_PIN(131, "GSPI4_MOSI"), + PINCTRL_PIN(132, "GSPI5_CS0B"), + PINCTRL_PIN(133, "GSPI5_CLK"), + PINCTRL_PIN(134, "GSPI5_MISO"), + PINCTRL_PIN(135, "GSPI5_MOSI"), + PINCTRL_PIN(136, "GSPI6_CS0B"), + PINCTRL_PIN(137, "GSPI6_CLK"), + PINCTRL_PIN(138, "GSPI6_MISO"), + PINCTRL_PIN(139, "GSPI6_MOSI"), + PINCTRL_PIN(140, "GSPI3_CLK_LOOPBK"), + PINCTRL_PIN(141, "GSPI4_CLK_LOOPBK"), + PINCTRL_PIN(142, "GSPI5_CLK_LOOPBK"), + PINCTRL_PIN(143, "GSPI6_CLK_LOOPBK"), + /* vGPIO */ + PINCTRL_PIN(144, "CNV_BTEN"), + PINCTRL_PIN(145, "CNV_BT_HOST_WAKEB"), + PINCTRL_PIN(146, "CNV_BT_IF_SELECT"), + PINCTRL_PIN(147, "vCNV_BT_UART_TXD"), + PINCTRL_PIN(148, "vCNV_BT_UART_RXD"), + PINCTRL_PIN(149, "vCNV_BT_UART_CTS_B"), + PINCTRL_PIN(150, "vCNV_BT_UART_RTS_B"), + PINCTRL_PIN(151, "vCNV_MFUART1_TXD"), + PINCTRL_PIN(152, "vCNV_MFUART1_RXD"), + PINCTRL_PIN(153, "vCNV_MFUART1_CTS_B"), + PINCTRL_PIN(154, "vCNV_MFUART1_RTS_B"), + PINCTRL_PIN(155, "vUART0_TXD"), + PINCTRL_PIN(156, "vUART0_RXD"), + PINCTRL_PIN(157, "vUART0_CTS_B"), + PINCTRL_PIN(158, "vUART0_RTS_B"), + PINCTRL_PIN(159, "vISH_UART0_TXD"), + PINCTRL_PIN(160, "vISH_UART0_RXD"), + PINCTRL_PIN(161, "vISH_UART0_CTS_B"), + PINCTRL_PIN(162, "vISH_UART0_RTS_B"), + PINCTRL_PIN(163, "vCNV_BT_I2S_BCLK"), + PINCTRL_PIN(164, "vCNV_BT_I2S_WS_SYNC"), + PINCTRL_PIN(165, "vCNV_BT_I2S_SDO"), + PINCTRL_PIN(166, "vCNV_BT_I2S_SDI"), + PINCTRL_PIN(167, "vI2S2_SCLK"), + PINCTRL_PIN(168, "vI2S2_SFRM"), + PINCTRL_PIN(169, "vI2S2_TXD"), + PINCTRL_PIN(170, "vI2S2_RXD"), + /* GPP_C */ + PINCTRL_PIN(171, "SMBCLK"), + PINCTRL_PIN(172, "SMBDATA"), + PINCTRL_PIN(173, "SMBALERTB"), + PINCTRL_PIN(174, "SML0CLK"), + PINCTRL_PIN(175, "SML0DATA"), + PINCTRL_PIN(176, "SML0ALERTB"), + PINCTRL_PIN(177, "SML1CLK"), + PINCTRL_PIN(178, "SML1DATA"), + PINCTRL_PIN(179, "UART0_RXD"), + PINCTRL_PIN(180, "UART0_TXD"), + PINCTRL_PIN(181, "UART0_RTSB"), + PINCTRL_PIN(182, "UART0_CTSB"), + PINCTRL_PIN(183, "UART1_RXD"), + PINCTRL_PIN(184, "UART1_TXD"), + PINCTRL_PIN(185, "UART1_RTSB"), + PINCTRL_PIN(186, "UART1_CTSB"), + PINCTRL_PIN(187, "I2C0_SDA"), + PINCTRL_PIN(188, "I2C0_SCL"), + PINCTRL_PIN(189, "I2C1_SDA"), + PINCTRL_PIN(190, "I2C1_SCL"), + PINCTRL_PIN(191, "UART2_RXD"), + PINCTRL_PIN(192, "UART2_TXD"), + PINCTRL_PIN(193, "UART2_RTSB"), + PINCTRL_PIN(194, "UART2_CTSB"), + /* GPP_F */ + PINCTRL_PIN(195, "CNV_BRI_DT"), + PINCTRL_PIN(196, "CNV_BRI_RSP"), + PINCTRL_PIN(197, "CNV_RGI_DT"), + PINCTRL_PIN(198, "CNV_RGI_RSP"), + PINCTRL_PIN(199, "CNV_RF_RESET_B"), + PINCTRL_PIN(200, "GPPC_F_5"), + PINCTRL_PIN(201, "CNV_PA_BLANKING"), + PINCTRL_PIN(202, "GPPC_F_7"), + PINCTRL_PIN(203, "I2S_MCLK2_INOUT"), + PINCTRL_PIN(204, "BOOTMPC"), + PINCTRL_PIN(205, "GPPC_F_10"), + PINCTRL_PIN(206, "GPPC_F_11"), + PINCTRL_PIN(207, "GSXDOUT"), + PINCTRL_PIN(208, "GSXSLOAD"), + PINCTRL_PIN(209, "GSXDIN"), + PINCTRL_PIN(210, "GSXSRESETB"), + PINCTRL_PIN(211, "GSXCLK"), + PINCTRL_PIN(212, "GMII_MDC"), + PINCTRL_PIN(213, "GMII_MDIO"), + PINCTRL_PIN(214, "SRCCLKREQB_6"), + PINCTRL_PIN(215, "EXT_PWR_GATEB"), + PINCTRL_PIN(216, "EXT_PWR_GATE2B"), + PINCTRL_PIN(217, "VNN_CTRL"), + PINCTRL_PIN(218, "V1P05_CTRL"), + PINCTRL_PIN(219, "GPPF_CLK_LOOPBACK"), + /* HVCMOS */ + PINCTRL_PIN(220, "L_BKLTEN"), + PINCTRL_PIN(221, "L_BKLTCTL"), + PINCTRL_PIN(222, "L_VDDEN"), + PINCTRL_PIN(223, "SYS_PWROK"), + PINCTRL_PIN(224, "SYS_RESETB"), + PINCTRL_PIN(225, "MLK_RSTB"), + /* GPP_E */ + PINCTRL_PIN(226, "SATAXPCIE_0"), + PINCTRL_PIN(227, "SPI1_IO_2"), + PINCTRL_PIN(228, "SPI1_IO_3"), + PINCTRL_PIN(229, "CPU_GP_0"), + PINCTRL_PIN(230, "SATA_DEVSLP_0"), + PINCTRL_PIN(231, "SATA_DEVSLP_1"), + PINCTRL_PIN(232, "GPPC_E_6"), + PINCTRL_PIN(233, "CPU_GP_1"), + PINCTRL_PIN(234, "SPI1_CS1B"), + PINCTRL_PIN(235, "USB2_OCB_0"), + PINCTRL_PIN(236, "SPI1_CSB"), + PINCTRL_PIN(237, "SPI1_CLK"), + PINCTRL_PIN(238, "SPI1_MISO_IO_1"), + PINCTRL_PIN(239, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(240, "DDSP_HPD_A"), + PINCTRL_PIN(241, "ISH_GP_6"), + PINCTRL_PIN(242, "ISH_GP_7"), + PINCTRL_PIN(243, "GPPC_E_17"), + PINCTRL_PIN(244, "DDP1_CTRLCLK"), + PINCTRL_PIN(245, "DDP1_CTRLDATA"), + PINCTRL_PIN(246, "DDP2_CTRLCLK"), + PINCTRL_PIN(247, "DDP2_CTRLDATA"), + PINCTRL_PIN(248, "DDPA_CTRLCLK"), + PINCTRL_PIN(249, "DDPA_CTRLDATA"), + PINCTRL_PIN(250, "SPI1_CLK_LOOPBK"), + /* JTAG */ + PINCTRL_PIN(251, "JTAG_TDO"), + PINCTRL_PIN(252, "JTAGX"), + PINCTRL_PIN(253, "PRDYB"), + PINCTRL_PIN(254, "PREQB"), + PINCTRL_PIN(255, "CPU_TRSTB"), + PINCTRL_PIN(256, "JTAG_TDI"), + PINCTRL_PIN(257, "JTAG_TMS"), + PINCTRL_PIN(258, "JTAG_TCK"), + PINCTRL_PIN(259, "DBG_PMODE"), + /* GPP_R */ + PINCTRL_PIN(260, "HDA_BCLK"), + PINCTRL_PIN(261, "HDA_SYNC"), + PINCTRL_PIN(262, "HDA_SDO"), + PINCTRL_PIN(263, "HDA_SDI_0"), + PINCTRL_PIN(264, "HDA_RSTB"), + PINCTRL_PIN(265, "HDA_SDI_1"), + PINCTRL_PIN(266, "GPP_R_6"), + PINCTRL_PIN(267, "GPP_R_7"), + /* SPI */ + PINCTRL_PIN(268, "SPI0_IO_2"), + PINCTRL_PIN(269, "SPI0_IO_3"), + PINCTRL_PIN(270, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(271, "SPI0_MISO_IO_1"), + PINCTRL_PIN(272, "SPI0_TPM_CSB"), + PINCTRL_PIN(273, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(274, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(275, "SPI0_CLK"), + PINCTRL_PIN(276, "SPI0_CLK_LOOPBK"), }; static const struct intel_padgroup tgllp_community0_gpps[] = { - TGL_GPP(0, 0, 25), /* GPP_B */ - TGL_GPP(1, 26, 41), /* GPP_T */ - TGL_GPP(2, 42, 66), /* GPP_A */ -}; - -static const struct intel_community tgllp_community0[] = { - TGL_COMMUNITY(0, 66, tgllp_community0_gpps), -}; - -static const struct intel_pinctrl_soc_data tgllp_community0_soc_data = { - .uid = "0", - .pins = tgllp_community0_pins, - .npins = ARRAY_SIZE(tgllp_community0_pins), - .communities = tgllp_community0, - .ncommunities = ARRAY_SIZE(tgllp_community0), -}; - -static const struct pinctrl_pin_desc tgllp_community1_pins[] = { - /* GPP_S */ - PINCTRL_PIN(0, "SNDW0_CLK"), - PINCTRL_PIN(1, "SNDW0_DATA"), - PINCTRL_PIN(2, "SNDW1_CLK"), - PINCTRL_PIN(3, "SNDW1_DATA"), - PINCTRL_PIN(4, "SNDW2_CLK"), - PINCTRL_PIN(5, "SNDW2_DATA"), - PINCTRL_PIN(6, "SNDW3_CLK"), - PINCTRL_PIN(7, "SNDW3_DATA"), - /* GPP_H */ - PINCTRL_PIN(8, "GPPC_H_0"), - PINCTRL_PIN(9, "GPPC_H_1"), - PINCTRL_PIN(10, "GPPC_H_2"), - PINCTRL_PIN(11, "SX_EXIT_HOLDOFFB"), - PINCTRL_PIN(12, "I2C2_SDA"), - PINCTRL_PIN(13, "I2C2_SCL"), - PINCTRL_PIN(14, "I2C3_SDA"), - PINCTRL_PIN(15, "I2C3_SCL"), - PINCTRL_PIN(16, "I2C4_SDA"), - PINCTRL_PIN(17, "I2C4_SCL"), - PINCTRL_PIN(18, "SRCCLKREQB_4"), - PINCTRL_PIN(19, "SRCCLKREQB_5"), - PINCTRL_PIN(20, "M2_SKT2_CFG_0"), - PINCTRL_PIN(21, "M2_SKT2_CFG_1"), - PINCTRL_PIN(22, "M2_SKT2_CFG_2"), - PINCTRL_PIN(23, "M2_SKT2_CFG_3"), - PINCTRL_PIN(24, "DDPB_CTRLCLK"), - PINCTRL_PIN(25, "DDPB_CTRLDATA"), - PINCTRL_PIN(26, "CPU_C10_GATEB"), - PINCTRL_PIN(27, "TIME_SYNC_0"), - PINCTRL_PIN(28, "IMGCLKOUT_1"), - PINCTRL_PIN(29, "IMGCLKOUT_2"), - PINCTRL_PIN(30, "IMGCLKOUT_3"), - PINCTRL_PIN(31, "IMGCLKOUT_4"), - /* GPP_D */ - PINCTRL_PIN(32, "ISH_GP_0"), - PINCTRL_PIN(33, "ISH_GP_1"), - PINCTRL_PIN(34, "ISH_GP_2"), - PINCTRL_PIN(35, "ISH_GP_3"), - PINCTRL_PIN(36, "IMGCLKOUT_0"), - PINCTRL_PIN(37, "SRCCLKREQB_0"), - PINCTRL_PIN(38, "SRCCLKREQB_1"), - PINCTRL_PIN(39, "SRCCLKREQB_2"), - PINCTRL_PIN(40, "SRCCLKREQB_3"), - PINCTRL_PIN(41, "ISH_SPI_CSB"), - PINCTRL_PIN(42, "ISH_SPI_CLK"), - PINCTRL_PIN(43, "ISH_SPI_MISO"), - PINCTRL_PIN(44, "ISH_SPI_MOSI"), - PINCTRL_PIN(45, "ISH_UART0_RXD"), - PINCTRL_PIN(46, "ISH_UART0_TXD"), - PINCTRL_PIN(47, "ISH_UART0_RTSB"), - PINCTRL_PIN(48, "ISH_UART0_CTSB"), - PINCTRL_PIN(49, "ISH_GP_4"), - PINCTRL_PIN(50, "ISH_GP_5"), - PINCTRL_PIN(51, "I2S_MCLK1_OUT"), - PINCTRL_PIN(52, "GSPI2_CLK_LOOPBK"), - /* GPP_U */ - PINCTRL_PIN(53, "UART3_RXD"), - PINCTRL_PIN(54, "UART3_TXD"), - PINCTRL_PIN(55, "UART3_RTSB"), - PINCTRL_PIN(56, "UART3_CTSB"), - PINCTRL_PIN(57, "GSPI3_CS0B"), - PINCTRL_PIN(58, "GSPI3_CLK"), - PINCTRL_PIN(59, "GSPI3_MISO"), - PINCTRL_PIN(60, "GSPI3_MOSI"), - PINCTRL_PIN(61, "GSPI4_CS0B"), - PINCTRL_PIN(62, "GSPI4_CLK"), - PINCTRL_PIN(63, "GSPI4_MISO"), - PINCTRL_PIN(64, "GSPI4_MOSI"), - PINCTRL_PIN(65, "GSPI5_CS0B"), - PINCTRL_PIN(66, "GSPI5_CLK"), - PINCTRL_PIN(67, "GSPI5_MISO"), - PINCTRL_PIN(68, "GSPI5_MOSI"), - PINCTRL_PIN(69, "GSPI6_CS0B"), - PINCTRL_PIN(70, "GSPI6_CLK"), - PINCTRL_PIN(71, "GSPI6_MISO"), - PINCTRL_PIN(72, "GSPI6_MOSI"), - PINCTRL_PIN(73, "GSPI3_CLK_LOOPBK"), - PINCTRL_PIN(74, "GSPI4_CLK_LOOPBK"), - PINCTRL_PIN(75, "GSPI5_CLK_LOOPBK"), - PINCTRL_PIN(76, "GSPI6_CLK_LOOPBK"), - /* vGPIO */ - PINCTRL_PIN(77, "CNV_BTEN"), - PINCTRL_PIN(78, "CNV_BT_HOST_WAKEB"), - PINCTRL_PIN(79, "CNV_BT_IF_SELECT"), - PINCTRL_PIN(80, "vCNV_BT_UART_TXD"), - PINCTRL_PIN(81, "vCNV_BT_UART_RXD"), - PINCTRL_PIN(82, "vCNV_BT_UART_CTS_B"), - PINCTRL_PIN(83, "vCNV_BT_UART_RTS_B"), - PINCTRL_PIN(84, "vCNV_MFUART1_TXD"), - PINCTRL_PIN(85, "vCNV_MFUART1_RXD"), - PINCTRL_PIN(86, "vCNV_MFUART1_CTS_B"), - PINCTRL_PIN(87, "vCNV_MFUART1_RTS_B"), - PINCTRL_PIN(88, "vUART0_TXD"), - PINCTRL_PIN(89, "vUART0_RXD"), - PINCTRL_PIN(90, "vUART0_CTS_B"), - PINCTRL_PIN(91, "vUART0_RTS_B"), - PINCTRL_PIN(92, "vISH_UART0_TXD"), - PINCTRL_PIN(93, "vISH_UART0_RXD"), - PINCTRL_PIN(94, "vISH_UART0_CTS_B"), - PINCTRL_PIN(95, "vISH_UART0_RTS_B"), - PINCTRL_PIN(96, "vCNV_BT_I2S_BCLK"), - PINCTRL_PIN(97, "vCNV_BT_I2S_WS_SYNC"), - PINCTRL_PIN(98, "vCNV_BT_I2S_SDO"), - PINCTRL_PIN(99, "vCNV_BT_I2S_SDI"), - PINCTRL_PIN(100, "vI2S2_SCLK"), - PINCTRL_PIN(101, "vI2S2_SFRM"), - PINCTRL_PIN(102, "vI2S2_TXD"), - PINCTRL_PIN(103, "vI2S2_RXD"), + TGL_GPP(0, 0, 25, 0), /* GPP_B */ + TGL_GPP(1, 26, 41, 32), /* GPP_T */ + TGL_GPP(2, 42, 66, 64), /* GPP_A */ }; static const struct intel_padgroup tgllp_community1_gpps[] = { - TGL_GPP(0, 0, 7), /* GPP_S */ - TGL_GPP(1, 8, 31), /* GPP_H */ - TGL_GPP(2, 32, 52), /* GPP_D */ - TGL_GPP(3, 53, 76), /* GPP_U */ - TGL_GPP(4, 77, 103), /* vGPIO */ -}; - -static const struct intel_community tgllp_community1[] = { - TGL_COMMUNITY(0, 103, tgllp_community1_gpps), -}; - -static const struct intel_pinctrl_soc_data tgllp_community1_soc_data = { - .uid = "1", - .pins = tgllp_community1_pins, - .npins = ARRAY_SIZE(tgllp_community1_pins), - .communities = tgllp_community1, - .ncommunities = ARRAY_SIZE(tgllp_community1), -}; - -static const struct pinctrl_pin_desc tgllp_community4_pins[] = { - /* GPP_C */ - PINCTRL_PIN(0, "SMBCLK"), - PINCTRL_PIN(1, "SMBDATA"), - PINCTRL_PIN(2, "SMBALERTB"), - PINCTRL_PIN(3, "SML0CLK"), - PINCTRL_PIN(4, "SML0DATA"), - PINCTRL_PIN(5, "SML0ALERTB"), - PINCTRL_PIN(6, "SML1CLK"), - PINCTRL_PIN(7, "SML1DATA"), - PINCTRL_PIN(8, "UART0_RXD"), - PINCTRL_PIN(9, "UART0_TXD"), - PINCTRL_PIN(10, "UART0_RTSB"), - PINCTRL_PIN(11, "UART0_CTSB"), - PINCTRL_PIN(12, "UART1_RXD"), - PINCTRL_PIN(13, "UART1_TXD"), - PINCTRL_PIN(14, "UART1_RTSB"), - PINCTRL_PIN(15, "UART1_CTSB"), - PINCTRL_PIN(16, "I2C0_SDA"), - PINCTRL_PIN(17, "I2C0_SCL"), - PINCTRL_PIN(18, "I2C1_SDA"), - PINCTRL_PIN(19, "I2C1_SCL"), - PINCTRL_PIN(20, "UART2_RXD"), - PINCTRL_PIN(21, "UART2_TXD"), - PINCTRL_PIN(22, "UART2_RTSB"), - PINCTRL_PIN(23, "UART2_CTSB"), - /* GPP_F */ - PINCTRL_PIN(24, "CNV_BRI_DT"), - PINCTRL_PIN(25, "CNV_BRI_RSP"), - PINCTRL_PIN(26, "CNV_RGI_DT"), - PINCTRL_PIN(27, "CNV_RGI_RSP"), - PINCTRL_PIN(28, "CNV_RF_RESET_B"), - PINCTRL_PIN(29, "GPPC_F_5"), - PINCTRL_PIN(30, "CNV_PA_BLANKING"), - PINCTRL_PIN(31, "GPPC_F_7"), - PINCTRL_PIN(32, "I2S_MCLK2_INOUT"), - PINCTRL_PIN(33, "BOOTMPC"), - PINCTRL_PIN(34, "GPPC_F_10"), - PINCTRL_PIN(35, "GPPC_F_11"), - PINCTRL_PIN(36, "GSXDOUT"), - PINCTRL_PIN(37, "GSXSLOAD"), - PINCTRL_PIN(38, "GSXDIN"), - PINCTRL_PIN(39, "GSXSRESETB"), - PINCTRL_PIN(40, "GSXCLK"), - PINCTRL_PIN(41, "GMII_MDC"), - PINCTRL_PIN(42, "GMII_MDIO"), - PINCTRL_PIN(43, "SRCCLKREQB_6"), - PINCTRL_PIN(44, "EXT_PWR_GATEB"), - PINCTRL_PIN(45, "EXT_PWR_GATE2B"), - PINCTRL_PIN(46, "VNN_CTRL"), - PINCTRL_PIN(47, "V1P05_CTRL"), - PINCTRL_PIN(48, "GPPF_CLK_LOOPBACK"), - /* HVCMOS */ - PINCTRL_PIN(49, "L_BKLTEN"), - PINCTRL_PIN(50, "L_BKLTCTL"), - PINCTRL_PIN(51, "L_VDDEN"), - PINCTRL_PIN(52, "SYS_PWROK"), - PINCTRL_PIN(53, "SYS_RESETB"), - PINCTRL_PIN(54, "MLK_RSTB"), - /* GPP_E */ - PINCTRL_PIN(55, "SATAXPCIE_0"), - PINCTRL_PIN(56, "SPI1_IO_2"), - PINCTRL_PIN(57, "SPI1_IO_3"), - PINCTRL_PIN(58, "CPU_GP_0"), - PINCTRL_PIN(59, "SATA_DEVSLP_0"), - PINCTRL_PIN(60, "SATA_DEVSLP_1"), - PINCTRL_PIN(61, "GPPC_E_6"), - PINCTRL_PIN(62, "CPU_GP_1"), - PINCTRL_PIN(63, "SPI1_CS1B"), - PINCTRL_PIN(64, "USB2_OCB_0"), - PINCTRL_PIN(65, "SPI1_CSB"), - PINCTRL_PIN(66, "SPI1_CLK"), - PINCTRL_PIN(67, "SPI1_MISO_IO_1"), - PINCTRL_PIN(68, "SPI1_MOSI_IO_0"), - PINCTRL_PIN(69, "DDSP_HPD_A"), - PINCTRL_PIN(70, "ISH_GP_6"), - PINCTRL_PIN(71, "ISH_GP_7"), - PINCTRL_PIN(72, "GPPC_E_17"), - PINCTRL_PIN(73, "DDP1_CTRLCLK"), - PINCTRL_PIN(74, "DDP1_CTRLDATA"), - PINCTRL_PIN(75, "DDP2_CTRLCLK"), - PINCTRL_PIN(76, "DDP2_CTRLDATA"), - PINCTRL_PIN(77, "DDPA_CTRLCLK"), - PINCTRL_PIN(78, "DDPA_CTRLDATA"), - PINCTRL_PIN(79, "SPI1_CLK_LOOPBK"), - /* JTAG */ - PINCTRL_PIN(80, "JTAG_TDO"), - PINCTRL_PIN(81, "JTAGX"), - PINCTRL_PIN(82, "PRDYB"), - PINCTRL_PIN(83, "PREQB"), - PINCTRL_PIN(84, "CPU_TRSTB"), - PINCTRL_PIN(85, "JTAG_TDI"), - PINCTRL_PIN(86, "JTAG_TMS"), - PINCTRL_PIN(87, "JTAG_TCK"), - PINCTRL_PIN(88, "DBG_PMODE"), + TGL_GPP(0, 67, 74, 96), /* GPP_S */ + TGL_GPP(1, 75, 98, 128), /* GPP_H */ + TGL_GPP(2, 99, 119, 160), /* GPP_D */ + TGL_GPP(3, 120, 143, 192), /* GPP_U */ + TGL_GPP(4, 144, 170, 224), /* vGPIO */ }; static const struct intel_padgroup tgllp_community4_gpps[] = { - TGL_GPP(0, 0, 23), /* GPP_C */ - TGL_GPP(1, 24, 48), /* GPP_F */ - TGL_GPP(2, 49, 54), /* HVCMOS */ - TGL_GPP(3, 55, 79), /* GPP_E */ - TGL_GPP(4, 80, 88), /* JTAG */ -}; - -static const struct intel_community tgllp_community4[] = { - TGL_COMMUNITY(0, 88, tgllp_community4_gpps), -}; - -static const struct intel_pinctrl_soc_data tgllp_community4_soc_data = { - .uid = "4", - .pins = tgllp_community4_pins, - .npins = ARRAY_SIZE(tgllp_community4_pins), - .communities = tgllp_community4, - .ncommunities = ARRAY_SIZE(tgllp_community4), -}; - -static const struct pinctrl_pin_desc tgllp_community5_pins[] = { - /* GPP_R */ - PINCTRL_PIN(0, "HDA_BCLK"), - PINCTRL_PIN(1, "HDA_SYNC"), - PINCTRL_PIN(2, "HDA_SDO"), - PINCTRL_PIN(3, "HDA_SDI_0"), - PINCTRL_PIN(4, "HDA_RSTB"), - PINCTRL_PIN(5, "HDA_SDI_1"), - PINCTRL_PIN(6, "GPP_R_6"), - PINCTRL_PIN(7, "GPP_R_7"), - /* SPI */ - PINCTRL_PIN(8, "SPI0_IO_2"), - PINCTRL_PIN(9, "SPI0_IO_3"), - PINCTRL_PIN(10, "SPI0_MOSI_IO_0"), - PINCTRL_PIN(11, "SPI0_MISO_IO_1"), - PINCTRL_PIN(12, "SPI0_TPM_CSB"), - PINCTRL_PIN(13, "SPI0_FLASH_0_CSB"), - PINCTRL_PIN(14, "SPI0_FLASH_1_CSB"), - PINCTRL_PIN(15, "SPI0_CLK"), - PINCTRL_PIN(16, "SPI0_CLK_LOOPBK"), + TGL_GPP(0, 171, 194, 256), /* GPP_C */ + TGL_GPP(1, 195, 219, 288), /* GPP_F */ + TGL_GPP(2, 220, 225, TGL_NO_GPIO), /* HVCMOS */ + TGL_GPP(3, 226, 250, 320), /* GPP_E */ + TGL_GPP(4, 251, 259, TGL_NO_GPIO), /* JTAG */ }; static const struct intel_padgroup tgllp_community5_gpps[] = { - TGL_GPP(0, 0, 7), /* GPP_R */ - TGL_GPP(1, 8, 16), /* SPI */ + TGL_GPP(0, 260, 267, 352), /* GPP_R */ + TGL_GPP(1, 268, 276, TGL_NO_GPIO), /* SPI */ }; -static const struct intel_community tgllp_community5[] = { - TGL_COMMUNITY(0, 16, tgllp_community5_gpps), +static const struct intel_community tgllp_communities[] = { + TGL_COMMUNITY(0, 0, 66, tgllp_community0_gpps), + TGL_COMMUNITY(1, 67, 170, tgllp_community1_gpps), + TGL_COMMUNITY(2, 171, 259, tgllp_community4_gpps), + TGL_COMMUNITY(3, 260, 276, tgllp_community5_gpps), }; -static const struct intel_pinctrl_soc_data tgllp_community5_soc_data = { - .uid = "5", - .pins = tgllp_community5_pins, - .npins = ARRAY_SIZE(tgllp_community5_pins), - .communities = tgllp_community5, - .ncommunities = ARRAY_SIZE(tgllp_community5), -}; - -static const struct intel_pinctrl_soc_data *tgllp_soc_data_array[] = { - &tgllp_community0_soc_data, - &tgllp_community1_soc_data, - &tgllp_community4_soc_data, - &tgllp_community5_soc_data, - NULL +static const struct intel_pinctrl_soc_data tgllp_soc_data = { + .pins = tgllp_pins, + .npins = ARRAY_SIZE(tgllp_pins), + .communities = tgllp_communities, + .ncommunities = ARRAY_SIZE(tgllp_communities), }; static const struct acpi_device_id tgl_pinctrl_acpi_match[] = { - { "INT34C5", (kernel_ulong_t)tgllp_soc_data_array }, + { "INT34C5", (kernel_ulong_t)&tgllp_soc_data }, { } }; MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match); @@ -438,7 +391,7 @@ MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match); static INTEL_PINCTRL_PM_OPS(tgl_pinctrl_pm_ops); static struct platform_driver tgl_pinctrl_driver = { - .probe = intel_pinctrl_probe_by_uid, + .probe = intel_pinctrl_probe_by_hid, .driver = { .name = "tigerlake-pinctrl", .acpi_match_table = tgl_pinctrl_acpi_match,