diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-02 02:57:14 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-02 02:57:14 +0300 |
commit | a32b344e6f4375c5bdc3e89d0997b7eae187a3b1 (patch) | |
tree | 5ff4d4e6f79300641485f72459b5c985f822d318 /drivers/pinctrl/stm32 | |
parent | e04360a2ea01bf42aa639b65aad81f502e896c7f (diff) | |
parent | bfa50166cd9d5d190b20dc33d1ec7ae19ced7022 (diff) | |
download | linux-a32b344e6f4375c5bdc3e89d0997b7eae187a3b1.tar.xz |
Merge tag 'pinctrl-v5.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control updates from Linus Walleij:
"This is the bulk of pin control changes for the v5.14 kernel. Not so
much going on. No core changes, just drivers.
The most interesting would be that MIPS Ralink is migrating to pin
control and we have some bindings but not yet code for the Apple M1
pin controller.
New drivers:
- Last merge window we created a driver for the Ralink RT2880. We are
now moving the Ralink SoC pin control drivers out of the MIPS
architecture code and into the pin control subsystem. This concerns
RT288X, MT7620, RT305X, RT3883 and MT7621.
- Qualcomm SM6125 SoC pin control driver.
- Qualcomm spmi-gpio support for PM7325.
- Qualcomm spmi-mpp also handles PMI8994 (just a compatible string)
- Mediatek MT8365 SoC pin controller.
- New device HID for the AMD GPIO controller.
Improvements:
- Pin bias config support for a slew of Renesas pin controllers.
- Incremental improvements and non-urgent bug fixes to the Renesas
SoC drivers.
- Implement irq_set_wake on the AMD pin controller so we can wake up
from external pin events.
Misc:
- Devicetree bindings for the Apple M1 pin controller, we will
probably see a proper driver for this soon as well"
* tag 'pinctrl-v5.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (54 commits)
pinctrl: ralink: rt305x: add missing include
pinctrl: stm32: check for IRQ MUX validity during alloc()
pinctrl: zynqmp: some code cleanups
drivers: qcom: pinctrl: Add pinctrl driver for sm6125
dt-bindings: pinctrl: qcom: sm6125: Document SM6125 pinctrl driver
dt-bindings: pinctrl: mcp23s08: add documentation for reset-gpios
pinctrl: mcp23s08: Add optional reset GPIO
pinctrl: mediatek: fix mode encoding
pinctrl: mcp23s08: Fix missing unlock on error in mcp23s08_irq()
pinctrl: bcm: Constify static pinmux_ops
pinctrl: bcm: Constify static pinctrl_ops
pinctrl: ralink: move RT288X SoC pinmux config into a new 'pinctrl-rt288x.c' file
pinctrl: ralink: move MT7620 SoC pinmux config into a new 'pinctrl-mt7620.c' file
pinctrl: ralink: move RT305X SoC pinmux config into a new 'pinctrl-rt305x.c' file
pinctrl: ralink: move RT3883 SoC pinmux config into a new 'pinctrl-rt3883.c' file
pinctrl: ralink: move MT7621 SoC pinmux config into a new 'pinctrl-mt7621.c' file
pinctrl: ralink: move ralink architecture pinmux header into the driver
pinctrl: single: config: enable the pin's input
pinctrl: mtk: Fix mt8365 Kconfig dependency
pinctrl: mcp23s08: fix race condition in irq handler
...
Diffstat (limited to 'drivers/pinctrl/stm32')
-rw-r--r-- | drivers/pinctrl/stm32/pinctrl-stm32.c | 79 |
1 files changed, 40 insertions, 39 deletions
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index c14d12d54cc5..68b3886f9f0f 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -414,57 +414,25 @@ static int stm32_gpio_domain_activate(struct irq_domain *d, { struct stm32_gpio_bank *bank = d->host_data; struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent); - unsigned long flags; int ret = 0; - /* - * gpio irq mux is shared between several banks, a lock has to be done - * to avoid overriding. - */ - spin_lock_irqsave(&pctl->irqmux_lock, flags); - if (pctl->hwlock) { ret = hwspin_lock_timeout_in_atomic(pctl->hwlock, HWSPNLCK_TIMEOUT); if (ret) { dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + return ret; } } - if (pctl->irqmux_map & BIT(irq_data->hwirq)) { - dev_err(pctl->dev, "irq line %ld already requested.\n", - irq_data->hwirq); - ret = -EBUSY; - if (pctl->hwlock) - hwspin_unlock_in_atomic(pctl->hwlock); - goto unlock; - } else { - pctl->irqmux_map |= BIT(irq_data->hwirq); - } - regmap_field_write(pctl->irqmux[irq_data->hwirq], bank->bank_ioport_nr); if (pctl->hwlock) hwspin_unlock_in_atomic(pctl->hwlock); -unlock: - spin_unlock_irqrestore(&pctl->irqmux_lock, flags); return ret; } -static void stm32_gpio_domain_deactivate(struct irq_domain *d, - struct irq_data *irq_data) -{ - struct stm32_gpio_bank *bank = d->host_data; - struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent); - unsigned long flags; - - spin_lock_irqsave(&pctl->irqmux_lock, flags); - pctl->irqmux_map &= ~BIT(irq_data->hwirq); - spin_unlock_irqrestore(&pctl->irqmux_lock, flags); -} - static int stm32_gpio_domain_alloc(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs, void *data) @@ -472,9 +440,28 @@ static int stm32_gpio_domain_alloc(struct irq_domain *d, struct stm32_gpio_bank *bank = d->host_data; struct irq_fwspec *fwspec = data; struct irq_fwspec parent_fwspec; - irq_hw_number_t hwirq; + struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent); + irq_hw_number_t hwirq = fwspec->param[0]; + unsigned long flags; + int ret = 0; + + /* + * Check first that the IRQ MUX of that line is free. + * gpio irq mux is shared between several banks, protect with a lock + */ + spin_lock_irqsave(&pctl->irqmux_lock, flags); + + if (pctl->irqmux_map & BIT(hwirq)) { + dev_err(pctl->dev, "irq line %ld already requested.\n", hwirq); + ret = -EBUSY; + } else { + pctl->irqmux_map |= BIT(hwirq); + } + + spin_unlock_irqrestore(&pctl->irqmux_lock, flags); + if (ret) + return ret; - hwirq = fwspec->param[0]; parent_fwspec.fwnode = d->parent->fwnode; parent_fwspec.param_count = 2; parent_fwspec.param[0] = fwspec->param[0]; @@ -486,12 +473,26 @@ static int stm32_gpio_domain_alloc(struct irq_domain *d, return irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &parent_fwspec); } +static void stm32_gpio_domain_free(struct irq_domain *d, unsigned int virq, + unsigned int nr_irqs) +{ + struct stm32_gpio_bank *bank = d->host_data; + struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent); + struct irq_data *irq_data = irq_domain_get_irq_data(d, virq); + unsigned long flags, hwirq = irq_data->hwirq; + + irq_domain_free_irqs_common(d, virq, nr_irqs); + + spin_lock_irqsave(&pctl->irqmux_lock, flags); + pctl->irqmux_map &= ~BIT(hwirq); + spin_unlock_irqrestore(&pctl->irqmux_lock, flags); +} + static const struct irq_domain_ops stm32_gpio_domain_ops = { - .translate = stm32_gpio_domain_translate, - .alloc = stm32_gpio_domain_alloc, - .free = irq_domain_free_irqs_common, + .translate = stm32_gpio_domain_translate, + .alloc = stm32_gpio_domain_alloc, + .free = stm32_gpio_domain_free, .activate = stm32_gpio_domain_activate, - .deactivate = stm32_gpio_domain_deactivate, }; /* Pinctrl functions */ |