diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2019-12-13 11:01:10 +0100 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2019-12-13 11:01:10 +0100 |
commit | a64556654b77e109152f97d7965ef1a5b7383035 (patch) | |
tree | db98a08e99e92bf34442d5bacfe446c1cff43861 /drivers/pinctrl | |
parent | pinctrl: pinmux: fix a possible null pointer in pinmux_can_be_used_for_gpio (diff) | |
parent | pinctrl: cherryview: Pass irqchip when adding gpiochip (diff) | |
download | linux-a64556654b77e109152f97d7965ef1a5b7383035.tar.xz linux-a64556654b77e109152f97d7965ef1a5b7383035.zip |
Merge tag 'intel-pinctrl-v5.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel into fixes
intel-pinctrl for v5.5-2
* Fix Baytrail silicon issue by using a global lock
* Fix North community pin names that user will assume their functions
* Convert Cherryview and Baytrail to pass IRQ chip along with GPIO one
The following is an automated git shortlog grouped by driver:
baytrail:
- Pass irqchip when adding gpiochip
- Add GPIO <-> pin mapping ranges via callback
- Update North Community pin list
- Really serialize all register accesses
cherryview:
- Pass irqchip when adding gpiochip
- Add GPIO <-> pin mapping ranges via callback
- Split out irq hw-init into a separate helper function
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-baytrail.c | 200 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-cherryview.c | 107 |
2 files changed, 173 insertions, 134 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 9ffb22211d2b..55141d5de29e 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -110,7 +110,6 @@ struct byt_gpio { struct platform_device *pdev; struct pinctrl_dev *pctl_dev; struct pinctrl_desc pctl_desc; - raw_spinlock_t lock; const struct intel_pinctrl_soc_data *soc_data; struct intel_community *communities_copy; struct byt_gpio_pin_context *saved_context; @@ -494,34 +493,34 @@ static const struct intel_pinctrl_soc_data byt_sus_soc_data = { }; static const struct pinctrl_pin_desc byt_ncore_pins[] = { - PINCTRL_PIN(0, "GPIO_NCORE0"), - PINCTRL_PIN(1, "GPIO_NCORE1"), - PINCTRL_PIN(2, "GPIO_NCORE2"), - PINCTRL_PIN(3, "GPIO_NCORE3"), - PINCTRL_PIN(4, "GPIO_NCORE4"), - PINCTRL_PIN(5, "GPIO_NCORE5"), - PINCTRL_PIN(6, "GPIO_NCORE6"), - PINCTRL_PIN(7, "GPIO_NCORE7"), - PINCTRL_PIN(8, "GPIO_NCORE8"), - PINCTRL_PIN(9, "GPIO_NCORE9"), - PINCTRL_PIN(10, "GPIO_NCORE10"), - PINCTRL_PIN(11, "GPIO_NCORE11"), - PINCTRL_PIN(12, "GPIO_NCORE12"), - PINCTRL_PIN(13, "GPIO_NCORE13"), - PINCTRL_PIN(14, "GPIO_NCORE14"), - PINCTRL_PIN(15, "GPIO_NCORE15"), - PINCTRL_PIN(16, "GPIO_NCORE16"), - PINCTRL_PIN(17, "GPIO_NCORE17"), - PINCTRL_PIN(18, "GPIO_NCORE18"), - PINCTRL_PIN(19, "GPIO_NCORE19"), - PINCTRL_PIN(20, "GPIO_NCORE20"), - PINCTRL_PIN(21, "GPIO_NCORE21"), - PINCTRL_PIN(22, "GPIO_NCORE22"), - PINCTRL_PIN(23, "GPIO_NCORE23"), - PINCTRL_PIN(24, "GPIO_NCORE24"), - PINCTRL_PIN(25, "GPIO_NCORE25"), - PINCTRL_PIN(26, "GPIO_NCORE26"), - PINCTRL_PIN(27, "GPIO_NCORE27"), + PINCTRL_PIN(0, "HV_DDI0_HPD"), + PINCTRL_PIN(1, "HV_DDI0_DDC_SDA"), + PINCTRL_PIN(2, "HV_DDI0_DDC_SCL"), + PINCTRL_PIN(3, "PANEL0_VDDEN"), + PINCTRL_PIN(4, "PANEL0_BKLTEN"), + PINCTRL_PIN(5, "PANEL0_BKLTCTL"), + PINCTRL_PIN(6, "HV_DDI1_HPD"), + PINCTRL_PIN(7, "HV_DDI1_DDC_SDA"), + PINCTRL_PIN(8, "HV_DDI1_DDC_SCL"), + PINCTRL_PIN(9, "PANEL1_VDDEN"), + PINCTRL_PIN(10, "PANEL1_BKLTEN"), + PINCTRL_PIN(11, "PANEL1_BKLTCTL"), + PINCTRL_PIN(12, "GP_INTD_DSI_TE1"), + PINCTRL_PIN(13, "HV_DDI2_DDC_SDA"), + PINCTRL_PIN(14, "HV_DDI2_DDC_SCL"), + PINCTRL_PIN(15, "GP_CAMERASB00"), + PINCTRL_PIN(16, "GP_CAMERASB01"), + PINCTRL_PIN(17, "GP_CAMERASB02"), + PINCTRL_PIN(18, "GP_CAMERASB03"), + PINCTRL_PIN(19, "GP_CAMERASB04"), + PINCTRL_PIN(20, "GP_CAMERASB05"), + PINCTRL_PIN(21, "GP_CAMERASB06"), + PINCTRL_PIN(22, "GP_CAMERASB07"), + PINCTRL_PIN(23, "GP_CAMERASB08"), + PINCTRL_PIN(24, "GP_CAMERASB09"), + PINCTRL_PIN(25, "GP_CAMERASB10"), + PINCTRL_PIN(26, "GP_CAMERASB11"), + PINCTRL_PIN(27, "GP_INTD_DSI_TE2"), }; static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = { @@ -549,6 +548,8 @@ static const struct intel_pinctrl_soc_data *byt_soc_data[] = { NULL }; +static DEFINE_RAW_SPINLOCK(byt_lock); + static struct intel_community *byt_get_community(struct byt_gpio *vg, unsigned int pin) { @@ -658,7 +659,7 @@ static void byt_set_group_simple_mux(struct byt_gpio *vg, unsigned long flags; int i; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); for (i = 0; i < group.npins; i++) { void __iomem *padcfg0; @@ -678,7 +679,7 @@ static void byt_set_group_simple_mux(struct byt_gpio *vg, writel(value, padcfg0); } - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); } static void byt_set_group_mixed_mux(struct byt_gpio *vg, @@ -688,7 +689,7 @@ static void byt_set_group_mixed_mux(struct byt_gpio *vg, unsigned long flags; int i; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); for (i = 0; i < group.npins; i++) { void __iomem *padcfg0; @@ -708,7 +709,7 @@ static void byt_set_group_mixed_mux(struct byt_gpio *vg, writel(value, padcfg0); } - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); } static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, @@ -749,11 +750,11 @@ static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset) unsigned long flags; u32 value; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); value = readl(reg); value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); writel(value, reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); } static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, @@ -765,7 +766,7 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, u32 value, gpio_mux; unsigned long flags; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); /* * In most cases, func pin mux 000 means GPIO function. @@ -787,7 +788,7 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, "pin %u forcibly re-configured as GPIO\n", offset); } - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); pm_runtime_get(&vg->pdev->dev); @@ -815,7 +816,7 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, unsigned long flags; u32 value; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); value = readl(val_reg); value &= ~BYT_DIR_MASK; @@ -832,7 +833,7 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, "Potential Error: Setting GPIO with direct_irq_en to output"); writel(value, val_reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } @@ -901,11 +902,11 @@ static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, u32 conf, pull, val, debounce; u16 arg = 0; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); conf = readl(conf_reg); pull = conf & BYT_PULL_ASSIGN_MASK; val = readl(val_reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); switch (param) { case PIN_CONFIG_BIAS_DISABLE: @@ -932,9 +933,9 @@ static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, if (!(conf & BYT_DEBOUNCE_EN)) return -EINVAL; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); debounce = readl(db_reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { case BYT_DEBOUNCE_PULSE_375US: @@ -986,7 +987,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, u32 conf, val, debounce; int i, ret = 0; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); conf = readl(conf_reg); val = readl(val_reg); @@ -1094,7 +1095,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, if (!ret) writel(conf, conf_reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); return ret; } @@ -1119,9 +1120,9 @@ static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset) unsigned long flags; u32 val; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); val = readl(reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); return !!(val & BYT_LEVEL); } @@ -1136,13 +1137,13 @@ static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) if (!reg) return; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); old_val = readl(reg); if (value) writel(old_val | BYT_LEVEL, reg); else writel(old_val & ~BYT_LEVEL, reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); } static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) @@ -1155,9 +1156,9 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) if (!reg) return -EINVAL; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); value = readl(reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); if (!(value & BYT_OUTPUT_EN)) return 0; @@ -1200,14 +1201,14 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) const char *label; unsigned int pin; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); pin = vg->soc_data->pins[i].number; reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); if (!reg) { seq_printf(s, "Could not retrieve pin %i conf0 reg\n", pin); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); continue; } conf0 = readl(reg); @@ -1216,11 +1217,11 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) if (!reg) { seq_printf(s, "Could not retrieve pin %i val reg\n", pin); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); continue; } val = readl(reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); comm = byt_get_community(vg, pin); if (!comm) { @@ -1304,9 +1305,9 @@ static void byt_irq_ack(struct irq_data *d) if (!reg) return; - raw_spin_lock(&vg->lock); + raw_spin_lock(&byt_lock); writel(BIT(offset % 32), reg); - raw_spin_unlock(&vg->lock); + raw_spin_unlock(&byt_lock); } static void byt_irq_mask(struct irq_data *d) @@ -1330,7 +1331,7 @@ static void byt_irq_unmask(struct irq_data *d) if (!reg) return; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); value = readl(reg); switch (irqd_get_trigger_type(d)) { @@ -1353,7 +1354,7 @@ static void byt_irq_unmask(struct irq_data *d) writel(value, reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); } static int byt_irq_type(struct irq_data *d, unsigned int type) @@ -1367,7 +1368,7 @@ static int byt_irq_type(struct irq_data *d, unsigned int type) if (!reg || offset >= vg->chip.ngpio) return -EINVAL; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); value = readl(reg); WARN(value & BYT_DIRECT_IRQ_EN, @@ -1389,7 +1390,7 @@ static int byt_irq_type(struct irq_data *d, unsigned int type) else if (type & IRQ_TYPE_LEVEL_MASK) irq_set_handler_locked(d, handle_level_irq); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } @@ -1425,9 +1426,9 @@ static void byt_gpio_irq_handler(struct irq_desc *desc) continue; } - raw_spin_lock(&vg->lock); + raw_spin_lock(&byt_lock); pending = readl(reg); - raw_spin_unlock(&vg->lock); + raw_spin_unlock(&byt_lock); for_each_set_bit(pin, &pending, 32) { virq = irq_find_mapping(vg->chip.irq.domain, base + pin); generic_handle_irq(virq); @@ -1450,9 +1451,9 @@ static void byt_init_irq_valid_mask(struct gpio_chip *chip, */ } -static void byt_gpio_irq_init_hw(struct byt_gpio *vg) +static int byt_gpio_irq_init_hw(struct gpio_chip *chip) { - struct gpio_chip *gc = &vg->chip; + struct byt_gpio *vg = gpiochip_get_data(chip); struct device *dev = &vg->pdev->dev; void __iomem *reg; u32 base, value; @@ -1476,7 +1477,7 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) value = readl(reg); if (value & BYT_DIRECT_IRQ_EN) { - clear_bit(i, gc->irq.valid_mask); + clear_bit(i, chip->irq.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); @@ -1504,6 +1505,21 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) "GPIO interrupt error, pins misconfigured. INT_STAT%u: 0x%08x\n", base / 32, value); } + + return 0; +} + +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; + int ret; + + ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc_data->npins); + if (ret) + dev_err(dev, "failed to add GPIO pin range\n"); + + return ret; } static int byt_gpio_probe(struct byt_gpio *vg) @@ -1518,6 +1534,7 @@ static int byt_gpio_probe(struct byt_gpio *vg) gc->label = dev_name(&vg->pdev->dev); gc->base = -1; gc->can_sleep = false; + 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; @@ -1528,33 +1545,30 @@ static int byt_gpio_probe(struct byt_gpio *vg) if (!vg->saved_context) return -ENOMEM; #endif - ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg); - if (ret) { - dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n"); - return ret; - } - - ret = gpiochip_add_pin_range(&vg->chip, dev_name(&vg->pdev->dev), - 0, 0, vg->soc_data->npins); - if (ret) { - dev_err(&vg->pdev->dev, "failed to add GPIO pin range\n"); - return ret; - } /* set up interrupts */ irq_rc = platform_get_resource(vg->pdev, IORESOURCE_IRQ, 0); if (irq_rc && irq_rc->start) { - byt_gpio_irq_init_hw(vg); - ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0, - handle_bad_irq, IRQ_TYPE_NONE); - if (ret) { - dev_err(&vg->pdev->dev, "failed to add irqchip\n"); - return ret; - } + struct gpio_irq_chip *girq; + + girq = &gc->irq; + girq->chip = &byt_irqchip; + girq->init_hw = byt_gpio_irq_init_hw; + girq->parent_handler = byt_gpio_irq_handler; + girq->num_parents = 1; + girq->parents = devm_kcalloc(&vg->pdev->dev, girq->num_parents, + sizeof(*girq->parents), GFP_KERNEL); + if (!girq->parents) + return -ENOMEM; + girq->parents[0] = (unsigned int)irq_rc->start; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_bad_irq; + } - gpiochip_set_chained_irqchip(gc, &byt_irqchip, - (unsigned)irq_rc->start, - byt_gpio_irq_handler); + ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg); + if (ret) { + dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n"); + return ret; } return ret; @@ -1638,8 +1652,6 @@ static int byt_pinctrl_probe(struct platform_device *pdev) return PTR_ERR(vg->pctl_dev); } - raw_spin_lock_init(&vg->lock); - ret = byt_gpio_probe(vg); if (ret) return ret; @@ -1654,8 +1666,11 @@ static int byt_pinctrl_probe(struct platform_device *pdev) static int byt_gpio_suspend(struct device *dev) { struct byt_gpio *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++) { void __iomem *reg; u32 value; @@ -1676,14 +1691,18 @@ static int byt_gpio_suspend(struct device *dev) vg->saved_context[i].val = value; } + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } static int byt_gpio_resume(struct device *dev) { struct byt_gpio *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++) { void __iomem *reg; u32 value; @@ -1721,6 +1740,7 @@ static int byt_gpio_resume(struct device *dev) } } + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } #endif diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 582fa8a75559..60527b93a711 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -149,6 +149,7 @@ struct chv_pin_context { * @chip: GPIO chip in this pin controller * @irqchip: IRQ chip in this pin controller * @regs: MMIO registers + * @irq: Our parent irq * @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO * offset (in GPIO number space) * @community: Community this pinctrl instance represents @@ -165,6 +166,7 @@ struct chv_pinctrl { struct gpio_chip chip; struct irq_chip irqchip; void __iomem *regs; + unsigned int irq; unsigned int intr_lines[16]; const struct chv_community *community; u32 saved_intmask; @@ -1555,39 +1557,9 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip, } } -static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) +static int chv_gpio_irq_init_hw(struct gpio_chip *chip) { - const struct chv_gpio_pinrange *range; - struct gpio_chip *chip = &pctrl->chip; - bool need_valid_mask = !dmi_check_system(chv_no_valid_mask); - const struct chv_community *community = pctrl->community; - int ret, i, irq_base; - - *chip = chv_gpio_chip; - - chip->ngpio = community->pins[community->npins - 1].number + 1; - chip->label = dev_name(pctrl->dev); - chip->parent = pctrl->dev; - chip->base = -1; - if (need_valid_mask) - chip->irq.init_valid_mask = chv_init_irq_valid_mask; - - ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl); - if (ret) { - dev_err(pctrl->dev, "Failed to register gpiochip\n"); - return ret; - } - - for (i = 0; i < community->ngpio_ranges; i++) { - range = &community->gpio_ranges[i]; - ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev), - range->base, range->base, - range->npins); - if (ret) { - dev_err(pctrl->dev, "failed to add GPIO pin range\n"); - return ret; - } - } + struct chv_pinctrl *pctrl = gpiochip_get_data(chip); /* * The same set of machines in chv_no_valid_mask[] have incorrectly @@ -1596,7 +1568,7 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) * * See also https://bugzilla.kernel.org/show_bug.cgi?id=197953. */ - if (!need_valid_mask) { + if (!pctrl->chip.irq.init_valid_mask) { /* * Mask all interrupts the community is able to generate * but leave the ones that can only generate GPEs unmasked. @@ -1608,15 +1580,47 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) /* Clear all interrupts */ chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); - if (!need_valid_mask) { - irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, - community->npins, NUMA_NO_NODE); - if (irq_base < 0) { - dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); - return irq_base; + return 0; +} + +static int chv_gpio_add_pin_ranges(struct gpio_chip *chip) +{ + struct chv_pinctrl *pctrl = gpiochip_get_data(chip); + const struct chv_community *community = pctrl->community; + const struct chv_gpio_pinrange *range; + int ret, i; + + for (i = 0; i < community->ngpio_ranges; i++) { + range = &community->gpio_ranges[i]; + ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev), + range->base, range->base, + range->npins); + if (ret) { + dev_err(pctrl->dev, "failed to add GPIO pin range\n"); + return ret; } } + return 0; +} + +static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) +{ + const struct chv_gpio_pinrange *range; + struct gpio_chip *chip = &pctrl->chip; + bool need_valid_mask = !dmi_check_system(chv_no_valid_mask); + const struct chv_community *community = pctrl->community; + int ret, i, irq_base; + + *chip = chv_gpio_chip; + + chip->ngpio = community->pins[community->npins - 1].number + 1; + chip->label = dev_name(pctrl->dev); + chip->add_pin_ranges = chv_gpio_add_pin_ranges; + chip->parent = pctrl->dev; + 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; @@ -1625,10 +1629,27 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) pctrl->irqchip.irq_set_type = chv_gpio_irq_type; pctrl->irqchip.flags = IRQCHIP_SKIP_SET_WAKE; - ret = gpiochip_irqchip_add(chip, &pctrl->irqchip, 0, - handle_bad_irq, IRQ_TYPE_NONE); + chip->irq.chip = &pctrl->irqchip; + chip->irq.init_hw = chv_gpio_irq_init_hw; + chip->irq.parent_handler = chv_gpio_irq_handler; + chip->irq.num_parents = 1; + chip->irq.parents = &pctrl->irq; + chip->irq.default_type = IRQ_TYPE_NONE; + chip->irq.handler = handle_bad_irq; + if (need_valid_mask) { + chip->irq.init_valid_mask = chv_init_irq_valid_mask; + } else { + irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, + community->npins, NUMA_NO_NODE); + if (irq_base < 0) { + dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); + return irq_base; + } + } + + ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl); if (ret) { - dev_err(pctrl->dev, "failed to add IRQ chip\n"); + dev_err(pctrl->dev, "Failed to register gpiochip\n"); return ret; } @@ -1642,8 +1663,6 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) } } - gpiochip_set_chained_irqchip(chip, &pctrl->irqchip, irq, - chv_gpio_irq_handler); return 0; } |