Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pinctrl-v7.0-4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control fixes from Linus Walleij:
"Some late pin control fixes. I'm not happy to have bugs so late in the
kernel cycle, but they are all driver specifics so I guess it's how it
is.

- Three fixes for the Intel pin control driver fixing the feature set
for the new silicon

- One fix for an IRQ storm in the MCP23S08 pin controller/GPIO
expander"

* tag 'pinctrl-v7.0-4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
pinctrl: mcp23s08: Disable all pin interrupts during probe
pinctrl: intel: Enable 3-bit PAD_OWN feature
pinctrl: intel: Fix the revision for new features (1kOhm PD, HW debouncer)
pinctrl: intel: Improve capability support

+36 -10
+26 -10
drivers/pinctrl/intel/pinctrl-intel.c
··· 53 53 #define PADOWN_MASK(p) (GENMASK(3, 0) << PADOWN_SHIFT(p)) 54 54 #define PADOWN_GPP(p) ((p) / 8) 55 55 56 - #define PWMC 0x204 57 - 58 56 /* Offset from pad_regs */ 59 57 #define PADCFG0 0x000 60 58 #define PADCFG0_RXEVCFG_MASK GENMASK(26, 25) ··· 203 205 community = intel_get_community(pctrl, pin); 204 206 if (!community) 205 207 return false; 206 - if (!community->padown_offset) 208 + 209 + /* If padown_offset is not provided, assume host ownership */ 210 + padown = community->regs + community->padown_offset; 211 + if (padown == community->regs) 207 212 return true; 213 + 214 + /* New HW generations have extended PAD_OWN registers */ 215 + if (community->features & PINCTRL_FEATURE_3BIT_PAD_OWN) 216 + return !(readl(padown + pin_to_padno(community, pin) * 4) & 7); 208 217 209 218 padgrp = intel_community_get_padgroup(community, pin); 210 219 if (!padgrp) ··· 219 214 220 215 gpp_offset = padgroup_offset(padgrp, pin); 221 216 gpp = PADOWN_GPP(gpp_offset); 222 - offset = community->padown_offset + padgrp->padown_num * 4 + gpp * 4; 223 - padown = community->regs + offset; 217 + offset = padgrp->padown_num * 4 + gpp * 4; 224 218 225 - return !(readl(padown) & PADOWN_MASK(gpp_offset)); 219 + return !(readl(padown + offset) & PADOWN_MASK(gpp_offset)); 226 220 } 227 221 228 222 static bool intel_pad_acpi_mode(const struct intel_pinctrl *pctrl, unsigned int pin) ··· 1553 1549 } 1554 1550 1555 1551 static int intel_pinctrl_probe_pwm(struct intel_pinctrl *pctrl, 1556 - struct intel_community *community) 1552 + struct intel_community *community, 1553 + unsigned short capability_offset) 1557 1554 { 1555 + void __iomem *base = community->regs + capability_offset + 4; 1558 1556 static const struct pwm_lpss_boardinfo info = { 1559 1557 .clk_rate = 19200000, 1560 1558 .npwm = 1, ··· 1570 1564 if (!IS_REACHABLE(CONFIG_PWM_LPSS)) 1571 1565 return 0; 1572 1566 1573 - chip = devm_pwm_lpss_probe(pctrl->dev, community->regs + PWMC, &info); 1567 + chip = devm_pwm_lpss_probe(pctrl->dev, base, &info); 1574 1568 return PTR_ERR_OR_ZERO(chip); 1575 1569 } 1576 1570 ··· 1601 1595 1602 1596 for (i = 0; i < pctrl->ncommunities; i++) { 1603 1597 struct intel_community *community = &pctrl->communities[i]; 1598 + unsigned short capability_offset[6]; 1604 1599 void __iomem *regs; 1600 + u32 revision; 1605 1601 u32 offset; 1606 1602 u32 value; 1607 1603 ··· 1618 1610 value = readl(regs + REVID); 1619 1611 if (value == ~0u) 1620 1612 return -ENODEV; 1621 - if (((value & REVID_MASK) >> REVID_SHIFT) >= 0x94) { 1613 + 1614 + revision = (value & REVID_MASK) >> REVID_SHIFT; 1615 + if (revision >= 0x092) { 1622 1616 community->features |= PINCTRL_FEATURE_DEBOUNCE; 1623 1617 community->features |= PINCTRL_FEATURE_1K_PD; 1624 1618 } 1619 + if (revision >= 0x110) 1620 + community->features |= PINCTRL_FEATURE_3BIT_PAD_OWN; 1625 1621 1626 1622 /* Determine community features based on the capabilities */ 1627 1623 offset = CAPLIST; ··· 1634 1622 switch ((value & CAPLIST_ID_MASK) >> CAPLIST_ID_SHIFT) { 1635 1623 case CAPLIST_ID_GPIO_HW_INFO: 1636 1624 community->features |= PINCTRL_FEATURE_GPIO_HW_INFO; 1625 + capability_offset[CAPLIST_ID_GPIO_HW_INFO] = offset; 1637 1626 break; 1638 1627 case CAPLIST_ID_PWM: 1639 1628 community->features |= PINCTRL_FEATURE_PWM; 1629 + capability_offset[CAPLIST_ID_PWM] = offset; 1640 1630 break; 1641 1631 case CAPLIST_ID_BLINK: 1642 1632 community->features |= PINCTRL_FEATURE_BLINK; 1633 + capability_offset[CAPLIST_ID_BLINK] = offset; 1643 1634 break; 1644 1635 case CAPLIST_ID_EXP: 1645 1636 community->features |= PINCTRL_FEATURE_EXP; 1637 + capability_offset[CAPLIST_ID_EXP] = offset; 1646 1638 break; 1647 1639 default: 1648 1640 break; ··· 1669 1653 if (ret) 1670 1654 return ret; 1671 1655 1672 - ret = intel_pinctrl_probe_pwm(pctrl, community); 1656 + ret = intel_pinctrl_probe_pwm(pctrl, community, capability_offset[CAPLIST_ID_PWM]); 1673 1657 if (ret) 1674 1658 return ret; 1675 1659 }
+1
drivers/pinctrl/intel/pinctrl-intel.h
··· 150 150 #define PINCTRL_FEATURE_PWM BIT(3) 151 151 #define PINCTRL_FEATURE_BLINK BIT(4) 152 152 #define PINCTRL_FEATURE_EXP BIT(5) 153 + #define PINCTRL_FEATURE_3BIT_PAD_OWN BIT(6) 153 154 154 155 #define __INTEL_COMMUNITY(b, s, e, g, n, gs, gn, soc) \ 155 156 { \
+9
drivers/pinctrl/pinctrl-mcp23s08.c
··· 664 664 if (mcp->irq && mcp->irq_controller) { 665 665 struct gpio_irq_chip *girq = &mcp->chip.irq; 666 666 667 + /* 668 + * Disable all pin interrupts, to prevent the interrupt handler from 669 + * calling nested handlers for any currently-enabled interrupts that 670 + * do not (yet) have an actual handler. 671 + */ 672 + ret = mcp_write(mcp, MCP_GPINTEN, 0); 673 + if (ret < 0) 674 + return dev_err_probe(dev, ret, "can't disable interrupts\n"); 675 + 667 676 gpio_irq_chip_set_chip(girq, &mcp23s08_irq_chip); 668 677 /* This will let us handle the parent IRQ in the driver */ 669 678 girq->parent_handler = NULL;