LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] pinctrl: stm32: add lock mechanism for irqmux selection
@ 2019-05-10  7:43 Alexandre Torgue
  2019-05-24 11:26 ` Linus Walleij
  0 siblings, 1 reply; 4+ messages in thread
From: Alexandre Torgue @ 2019-05-10  7:43 UTC (permalink / raw)
  To: Linus Walleij, Maxime Coquelin
  Cc: linux-kernel, linux-gpio, linux-arm-kernel, linux-stm32,
	alexandre.torgue

GPIOs are split between several banks (A, B, ...) and each bank can have
up to 16 lines. Those GPIOs could be used as interrupt lines thanks to
exti lines. As there are only 16 exti lines, a mux is used to select which
gpio line is connected to which exti line. Mapping is done as follow:

-A0, B0, C0.. -->exti_line_0 (X0 selected by mux_0)
-A1, B1, C1.. -->exti_line_1 (X1 selected by mux_1)
...

This patch adds a protection to avoid overriding on mux_n for exti_line_n.

Signed-off-by: Alexandre Torgue <alexandre.torgue@st.com>

diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index 2317ccf..99e4149 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -98,6 +98,8 @@ struct stm32_pinctrl {
 	struct stm32_desc_pin *pins;
 	u32 npins;
 	u32 pkg;
+	u16 irqmux_map;
+	spinlock_t irqmux_lock;
 };
 
 static inline int stm32_gpio_pin(int gpio)
@@ -307,9 +309,53 @@ 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(pctl->hwlock, HWSPINLOCK_TIMEOUT);
+
+	if (ret) {
+		dev_err(pctl->dev, "Can't get hwspinlock\n");
+		goto unlock;
+	}
+
+	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(pctl->hwlock);
+		goto unlock;
+	} else {
+		pctl->irqmux_map |= BIT(irq_data->hwirq);
+	}
 
 	regmap_field_write(pctl->irqmux[irq_data->hwirq], bank->bank_ioport_nr);
-	return 0;
+
+	if (pctl->hwlock)
+		hwspin_unlock(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,
@@ -338,6 +384,7 @@ static const struct irq_domain_ops stm32_gpio_domain_ops = {
 	.alloc          = stm32_gpio_domain_alloc,
 	.free           = irq_domain_free_irqs_common,
 	.activate	= stm32_gpio_domain_activate,
+	.deactivate	= stm32_gpio_domain_deactivate,
 };
 
 /* Pinctrl functions */
@@ -1290,6 +1337,8 @@ int stm32_pctl_probe(struct platform_device *pdev)
 		pctl->hwlock = hwspin_lock_request_specific(hwlock_id);
 	}
 
+	spin_lock_init(&pctl->irqmux_lock);
+
 	pctl->dev = dev;
 	pctl->match_data = match->data;
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] pinctrl: stm32: add lock mechanism for irqmux selection
  2019-05-10  7:43 [PATCH] pinctrl: stm32: add lock mechanism for irqmux selection Alexandre Torgue
@ 2019-05-24 11:26 ` Linus Walleij
  2019-05-24 12:27   ` Alexandre Torgue
  0 siblings, 1 reply; 4+ messages in thread
From: Linus Walleij @ 2019-05-24 11:26 UTC (permalink / raw)
  To: Alexandre Torgue
  Cc: Maxime Coquelin, linux-kernel, open list:GPIO SUBSYSTEM,
	Linux ARM, linux-stm32

On Fri, May 10, 2019 at 9:43 AM Alexandre Torgue
<alexandre.torgue@st.com> wrote:

> GPIOs are split between several banks (A, B, ...) and each bank can have
> up to 16 lines. Those GPIOs could be used as interrupt lines thanks to
> exti lines. As there are only 16 exti lines, a mux is used to select which
> gpio line is connected to which exti line. Mapping is done as follow:
>
> -A0, B0, C0.. -->exti_line_0 (X0 selected by mux_0)
> -A1, B1, C1.. -->exti_line_1 (X1 selected by mux_1)
> ...
>
> This patch adds a protection to avoid overriding on mux_n for exti_line_n.
>
> Signed-off-by: Alexandre Torgue <alexandre.torgue@st.com>

Patch applied, can't say I fully understand it but you know what
you're doing!

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] pinctrl: stm32: add lock mechanism for irqmux selection
  2019-05-24 11:26 ` Linus Walleij
@ 2019-05-24 12:27   ` Alexandre Torgue
  2019-05-24 15:22     ` Linus Walleij
  0 siblings, 1 reply; 4+ messages in thread
From: Alexandre Torgue @ 2019-05-24 12:27 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Maxime Coquelin, linux-kernel, open list:GPIO SUBSYSTEM,
	Linux ARM, linux-stm32



On 5/24/19 1:26 PM, Linus Walleij wrote:
> On Fri, May 10, 2019 at 9:43 AM Alexandre Torgue
> <alexandre.torgue@st.com> wrote:
> 
>> GPIOs are split between several banks (A, B, ...) and each bank can have
>> up to 16 lines. Those GPIOs could be used as interrupt lines thanks to
>> exti lines. As there are only 16 exti lines, a mux is used to select which
>> gpio line is connected to which exti line. Mapping is done as follow:
>>
>> -A0, B0, C0.. -->exti_line_0 (X0 selected by mux_0)
>> -A1, B1, C1.. -->exti_line_1 (X1 selected by mux_1)
>> ...
>>
>> This patch adds a protection to avoid overriding on mux_n for exti_line_n.
>>
>> Signed-off-by: Alexandre Torgue <alexandre.torgue@st.com>
> 
> Patch applied, can't say I fully understand it but you know what
> you're doing!

Thanks :). Do you need a better explanation ?

> 
> Yours,
> Linus Walleij
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] pinctrl: stm32: add lock mechanism for irqmux selection
  2019-05-24 12:27   ` Alexandre Torgue
@ 2019-05-24 15:22     ` Linus Walleij
  0 siblings, 0 replies; 4+ messages in thread
From: Linus Walleij @ 2019-05-24 15:22 UTC (permalink / raw)
  To: Alexandre Torgue
  Cc: Maxime Coquelin, linux-kernel, open list:GPIO SUBSYSTEM,
	Linux ARM, linux-stm32, Lina Iyer

On Fri, May 24, 2019 at 2:27 PM Alexandre Torgue
<alexandre.torgue@st.com> wrote:
> On 5/24/19 1:26 PM, Linus Walleij wrote:

> > Patch applied, can't say I fully understand it but you know what
> > you're doing!
>
> Thanks :). Do you need a better explanation ?

What I need to understand for hierarchical interrupt controllers
on GPIO is what I can pull into the gpio library. I am working
to extract some code from drivers/gpio/gpio-ixp4xx.c
to make generic simple hierarchical domain support available,
and Lina is working on generalizing some stuff.

But these complex domain operations in the STM32 seem
to be some special beast.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-05-24 15:22 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-10  7:43 [PATCH] pinctrl: stm32: add lock mechanism for irqmux selection Alexandre Torgue
2019-05-24 11:26 ` Linus Walleij
2019-05-24 12:27   ` Alexandre Torgue
2019-05-24 15:22     ` Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).