diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-baytrail.c | 42 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-broxton.c | 1 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-cherryview.c | 66 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.c | 45 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.h | 2 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-lynxpoint.c | 26 |
6 files changed, 110 insertions, 72 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index f89c9fcd4e1b..31f8f271628c 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1350,15 +1350,15 @@ static void byt_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *vg = gpiochip_get_data(gc); - unsigned int offset = irqd_to_hwirq(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); void __iomem *reg; - reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG); + reg = byt_gpio_reg(vg, hwirq, BYT_INT_STAT_REG); if (!reg) return; raw_spin_lock(&byt_lock); - writel(BIT(offset % 32), reg); + writel(BIT(hwirq % 32), reg); raw_spin_unlock(&byt_lock); } @@ -1366,20 +1366,24 @@ static void byt_irq_mask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *vg = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); - byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); + byt_gpio_clear_triggering(vg, hwirq); + gpiochip_disable_irq(gc, hwirq); } static void byt_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *vg = gpiochip_get_data(gc); - unsigned int offset = irqd_to_hwirq(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); unsigned long flags; void __iomem *reg; u32 value; - reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + gpiochip_enable_irq(gc, hwirq); + + reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG); if (!reg) return; @@ -1412,12 +1416,13 @@ static void byt_irq_unmask(struct irq_data *d) static int byt_irq_type(struct irq_data *d, unsigned int type) { struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); - u32 offset = irqd_to_hwirq(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); u32 value; unsigned long flags; - void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + void __iomem *reg; - if (!reg || offset >= vg->chip.ngpio) + reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG); + if (!reg) return -EINVAL; raw_spin_lock_irqsave(&byt_lock, flags); @@ -1447,6 +1452,16 @@ static int byt_irq_type(struct irq_data *d, unsigned int type) return 0; } +static const struct irq_chip byt_gpio_irq_chip = { + .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 | IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static void byt_gpio_irq_handler(struct irq_desc *desc) { struct irq_data *data = irq_desc_get_irq_data(desc); @@ -1633,15 +1648,8 @@ static int byt_gpio_probe(struct intel_pinctrl *vg) if (irq > 0) { 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 | IRQCHIP_SET_TYPE_MASKED, - girq = &gc->irq; - girq->chip = &vg->irqchip; + gpio_irq_chip_set_chip(girq, &byt_gpio_irq_chip); girq->init_hw = byt_gpio_irq_init_hw; girq->init_valid_mask = byt_init_irq_valid_mask; girq->parent_handler = byt_gpio_irq_handler; diff --git a/drivers/pinctrl/intel/pinctrl-broxton.c b/drivers/pinctrl/intel/pinctrl-broxton.c index 2be7e414f803..fb15cd10a32f 100644 --- a/drivers/pinctrl/intel/pinctrl-broxton.c +++ b/drivers/pinctrl/intel/pinctrl-broxton.c @@ -1035,4 +1035,5 @@ module_exit(bxt_pinctrl_exit); MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); MODULE_DESCRIPTION("Intel Broxton SoC pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:apollolake-pinctrl"); MODULE_ALIAS("platform:broxton-pinctrl"); diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 1d5818269076..26b2a425d201 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1242,12 +1242,12 @@ static void chv_gpio_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *pctrl = gpiochip_get_data(gc); - int pin = irqd_to_hwirq(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); u32 intr_line; raw_spin_lock(&chv_lock); - intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0); + intr_line = chv_readl(pctrl, hwirq, CHV_PADCTRL0); intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; chv_pctrl_writel(pctrl, CHV_INTSTAT, BIT(intr_line)); @@ -1255,17 +1255,15 @@ static void chv_gpio_irq_ack(struct irq_data *d) raw_spin_unlock(&chv_lock); } -static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) +static void chv_gpio_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t hwirq, bool mask) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *pctrl = gpiochip_get_data(gc); - int pin = irqd_to_hwirq(d); u32 value, intr_line; unsigned long flags; raw_spin_lock_irqsave(&chv_lock, flags); - intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0); + intr_line = chv_readl(pctrl, hwirq, CHV_PADCTRL0); intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; @@ -1281,12 +1279,20 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) static void chv_gpio_irq_mask(struct irq_data *d) { - chv_gpio_irq_mask_unmask(d, true); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + + chv_gpio_irq_mask_unmask(gc, hwirq, true); + gpiochip_disable_irq(gc, hwirq); } static void chv_gpio_irq_unmask(struct irq_data *d) { - chv_gpio_irq_mask_unmask(d, false); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + + gpiochip_enable_irq(gc, hwirq); + chv_gpio_irq_mask_unmask(gc, hwirq, false); } static unsigned chv_gpio_irq_startup(struct irq_data *d) @@ -1306,17 +1312,17 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) struct intel_pinctrl *pctrl = gpiochip_get_data(gc); struct device *dev = pctrl->dev; struct intel_community_context *cctx = &pctrl->context.communities[0]; - unsigned int pin = irqd_to_hwirq(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); irq_flow_handler_t handler; unsigned long flags; u32 intsel, value; raw_spin_lock_irqsave(&chv_lock, flags); - intsel = chv_readl(pctrl, pin, CHV_PADCTRL0); + intsel = chv_readl(pctrl, hwirq, CHV_PADCTRL0); intsel &= CHV_PADCTRL0_INTSEL_MASK; intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; - value = chv_readl(pctrl, pin, CHV_PADCTRL1); + value = chv_readl(pctrl, hwirq, CHV_PADCTRL1); if (value & CHV_PADCTRL1_INTWAKECFG_LEVEL) handler = handle_level_irq; else @@ -1324,9 +1330,9 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) if (cctx->intr_lines[intsel] == CHV_INVALID_HWIRQ) { irq_set_handler_locked(d, handler); - dev_dbg(dev, "using interrupt line %u for IRQ_TYPE_NONE on pin %u\n", - intsel, pin); - cctx->intr_lines[intsel] = pin; + dev_dbg(dev, "using interrupt line %u for IRQ_TYPE_NONE on pin %lu\n", + intsel, hwirq); + cctx->intr_lines[intsel] = hwirq; } raw_spin_unlock_irqrestore(&chv_lock, flags); } @@ -1392,14 +1398,14 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *pctrl = gpiochip_get_data(gc); - unsigned int pin = irqd_to_hwirq(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); unsigned long flags; u32 value; int ret; raw_spin_lock_irqsave(&chv_lock, flags); - ret = chv_gpio_set_intr_line(pctrl, pin); + ret = chv_gpio_set_intr_line(pctrl, hwirq); if (ret) goto out_unlock; @@ -1416,8 +1422,8 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) * 2. If the pin cfg is not locked in BIOS: * Driver programs the IntWakeCfg bits and save the mapping. */ - if (!chv_pad_locked(pctrl, pin)) { - value = chv_readl(pctrl, pin, CHV_PADCTRL1); + if (!chv_pad_locked(pctrl, hwirq)) { + value = chv_readl(pctrl, hwirq, CHV_PADCTRL1); value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; value &= ~CHV_PADCTRL1_INVRXTX_MASK; @@ -1434,7 +1440,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) value |= CHV_PADCTRL1_INVRXTX_RXDATA; } - chv_writel(pctrl, pin, CHV_PADCTRL1, value); + chv_writel(pctrl, hwirq, CHV_PADCTRL1, value); } if (type & IRQ_TYPE_EDGE_BOTH) @@ -1448,6 +1454,17 @@ out_unlock: return ret; } +static const struct irq_chip chv_gpio_irq_chip = { + .name = "chv-gpio", + .irq_startup = chv_gpio_irq_startup, + .irq_ack = chv_gpio_irq_ack, + .irq_mask = chv_gpio_irq_mask, + .irq_unmask = chv_gpio_irq_unmask, + .irq_set_type = chv_gpio_irq_type, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static void chv_gpio_irq_handler(struct irq_desc *desc) { struct gpio_chip *gc = irq_desc_get_handler_data(desc); @@ -1611,15 +1628,8 @@ static int chv_gpio_probe(struct intel_pinctrl *pctrl, int irq) chip->base = -1; pctrl->irq = irq; - pctrl->irqchip.name = "chv-gpio"; - pctrl->irqchip.irq_startup = chv_gpio_irq_startup; - pctrl->irqchip.irq_ack = chv_gpio_irq_ack; - pctrl->irqchip.irq_mask = chv_gpio_irq_mask; - pctrl->irqchip.irq_unmask = chv_gpio_irq_unmask; - pctrl->irqchip.irq_set_type = chv_gpio_irq_type; - pctrl->irqchip.flags = IRQCHIP_SKIP_SET_WAKE; - - chip->irq.chip = &pctrl->irqchip; + + gpio_irq_chip_set_chip(&chip->irq, &chv_gpio_irq_chip); chip->irq.init_hw = chv_gpio_irq_init_hw; chip->irq.parent_handler = chv_gpio_irq_handler; chip->irq.num_parents = 1; diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 826d494f3cc6..ffc045f7bf00 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -858,6 +858,9 @@ static const struct pinctrl_desc intel_pinctrl_desc = { * When coming through gpiolib irqchip, the GPIO offset is not * automatically translated to pinctrl pin number. This function can be * used to find out the corresponding pinctrl pin. + * + * Return: a pin number and pointers to the community and pad group, which + * the pin belongs to, or negative error code if translation can't be done. */ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset, const struct intel_community **community, @@ -899,6 +902,8 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset, * @pin: pin number * * Translate the pin number of pinctrl to GPIO offset + * + * Return: a GPIO offset, or negative error code if translation can't be done. */ static __maybe_unused int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin) { @@ -1039,15 +1044,14 @@ static void intel_gpio_irq_ack(struct irq_data *d) } } -static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) +static void intel_gpio_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t hwirq, bool mask) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *pctrl = gpiochip_get_data(gc); const struct intel_community *community; const struct intel_padgroup *padgrp; int pin; - pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp); + pin = intel_gpio_to_pin(pctrl, hwirq, &community, &padgrp); if (pin >= 0) { unsigned int gpp, gpp_offset; unsigned long flags; @@ -1077,12 +1081,20 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) static void intel_gpio_irq_mask(struct irq_data *d) { - intel_gpio_irq_mask_unmask(d, true); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + + intel_gpio_irq_mask_unmask(gc, hwirq, true); + gpiochip_disable_irq(gc, hwirq); } static void intel_gpio_irq_unmask(struct irq_data *d) { - intel_gpio_irq_mask_unmask(d, false); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + + gpiochip_enable_irq(gc, hwirq); + intel_gpio_irq_mask_unmask(gc, hwirq, false); } static int intel_gpio_irq_type(struct irq_data *d, unsigned int type) @@ -1157,6 +1169,17 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on) return 0; } +static const struct irq_chip intel_gpio_irq_chip = { + .name = "intel-gpio", + .irq_ack = intel_gpio_irq_ack, + .irq_mask = intel_gpio_irq_mask, + .irq_unmask = intel_gpio_irq_unmask, + .irq_set_type = intel_gpio_irq_type, + .irq_set_wake = intel_gpio_irq_wake, + .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, const struct intel_community *community) { @@ -1319,15 +1342,6 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) pctrl->chip.add_pin_ranges = intel_gpio_add_pin_ranges; pctrl->irq = irq; - /* Setup IRQ chip */ - pctrl->irqchip.name = dev_name(pctrl->dev); - pctrl->irqchip.irq_ack = intel_gpio_irq_ack; - pctrl->irqchip.irq_mask = intel_gpio_irq_mask; - pctrl->irqchip.irq_unmask = intel_gpio_irq_unmask; - pctrl->irqchip.irq_set_type = intel_gpio_irq_type; - pctrl->irqchip.irq_set_wake = intel_gpio_irq_wake; - pctrl->irqchip.flags = IRQCHIP_MASK_ON_SUSPEND; - /* * On some platforms several GPIO controllers share the same interrupt * line. @@ -1340,8 +1354,9 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) return ret; } + /* Setup IRQ chip */ girq = &pctrl->chip.irq; - girq->chip = &pctrl->irqchip; + gpio_irq_chip_set_chip(girq, &intel_gpio_irq_chip); /* This will let us handle the IRQ in the driver */ girq->parent_handler = NULL; girq->num_parents = 0; diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index c4fef03b663f..710341bb67cc 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -223,7 +223,6 @@ struct intel_pinctrl_context { * @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 @@ -236,7 +235,6 @@ struct intel_pinctrl { 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; diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 561fa322b0b4..4fb39eb30902 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -663,7 +663,7 @@ static void lp_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *lg = gpiochip_get_data(gc); - u32 hwirq = irqd_to_hwirq(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_STAT); unsigned long flags; @@ -684,10 +684,12 @@ static void lp_irq_enable(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *lg = gpiochip_get_data(gc); - u32 hwirq = irqd_to_hwirq(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); unsigned long flags; + gpiochip_enable_irq(gc, hwirq); + raw_spin_lock_irqsave(&lg->lock, flags); iowrite32(ioread32(reg) | BIT(hwirq % 32), reg); raw_spin_unlock_irqrestore(&lg->lock, flags); @@ -697,30 +699,33 @@ static void lp_irq_disable(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *lg = gpiochip_get_data(gc); - u32 hwirq = irqd_to_hwirq(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); unsigned long flags; raw_spin_lock_irqsave(&lg->lock, flags); iowrite32(ioread32(reg) & ~BIT(hwirq % 32), reg); raw_spin_unlock_irqrestore(&lg->lock, flags); + + gpiochip_disable_irq(gc, hwirq); } 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 intel_pinctrl *lg = gpiochip_get_data(gc); - u32 hwirq = irqd_to_hwirq(d); - void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1); + irq_hw_number_t hwirq = irqd_to_hwirq(d); unsigned long flags; + void __iomem *reg; u32 value; - if (hwirq >= lg->chip.ngpio) + reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1); + if (!reg) 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); + dev_err(lg->dev, "pin %lu can't be used as IRQ\n", hwirq); return -EBUSY; } @@ -755,7 +760,7 @@ static int lp_irq_set_type(struct irq_data *d, unsigned int type) return 0; } -static struct irq_chip lp_irqchip = { +static const struct irq_chip lp_irqchip = { .name = "LP-GPIO", .irq_ack = lp_irq_ack, .irq_mask = lp_irq_mask, @@ -763,7 +768,8 @@ static struct irq_chip lp_irqchip = { .irq_enable = lp_irq_enable, .irq_disable = lp_irq_disable, .irq_set_type = lp_irq_set_type, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, }; static int lp_gpio_irq_init_hw(struct gpio_chip *chip) @@ -884,7 +890,7 @@ static int lp_gpio_probe(struct platform_device *pdev) struct gpio_irq_chip *girq; girq = &gc->irq; - girq->chip = &lp_irqchip; + gpio_irq_chip_set_chip(girq, &lp_irqchip); girq->init_hw = lp_gpio_irq_init_hw; girq->parent_handler = lp_gpio_irq_handler; girq->num_parents = 1; |