* [PATCHv2] pinctrl-bcm2835.c: fix race condition when setting gpio dir
@ 2023-04-20 12:47 Hans Verkuil
2023-04-21 9:01 ` Linus Walleij
0 siblings, 1 reply; 2+ messages in thread
From: Hans Verkuil @ 2023-04-20 12:47 UTC (permalink / raw)
To: open list:GPIO SUBSYSTEM
Cc: Linux Media Mailing List, Linus Walleij, linux-rpi-kernel,
Florian Fainelli, Stefan Wahren,
Broadcom internal kernel review list
In the past setting the pin direction called pinctrl_gpio_direction()
which uses a mutex to serialize this. That was changed to set the
direction directly in the pin controller driver, but that lost the
serialization mechanism. Since the direction of multiple pins are in
the same register you can have a race condition, something that was
in fact observed with the cec-gpio driver.
Add a new spinlock to serialize writing to the FSEL registers.
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Fixes: 1a4541b68e25 ("pinctrl-bcm2835: don't call pinctrl_gpio_direction()")
---
Changes since v1:
- use 'goto unlock' as per Stefan's suggestion
---
drivers/pinctrl/bcm/pinctrl-bcm2835.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 8e2551a08c37..7435173e10f4 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -90,6 +90,8 @@ struct bcm2835_pinctrl {
struct pinctrl_gpio_range gpio_range;
raw_spinlock_t irq_lock[BCM2835_NUM_BANKS];
+ /* Protect FSEL registers */
+ spinlock_t fsel_lock;
};
/* pins are just named GPIO0..GPIO53 */
@@ -284,14 +286,19 @@ static inline void bcm2835_pinctrl_fsel_set(
struct bcm2835_pinctrl *pc, unsigned pin,
enum bcm2835_fsel fsel)
{
- u32 val = bcm2835_gpio_rd(pc, FSEL_REG(pin));
- enum bcm2835_fsel cur = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK;
+ u32 val;
+ enum bcm2835_fsel cur;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pc->fsel_lock, flags);
+ val = bcm2835_gpio_rd(pc, FSEL_REG(pin));
+ cur = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK;
dev_dbg(pc->dev, "read %08x (%u => %s)\n", val, pin,
- bcm2835_functions[cur]);
+ bcm2835_functions[cur]);
if (cur == fsel)
- return;
+ goto unlock;
if (cur != BCM2835_FSEL_GPIO_IN && fsel != BCM2835_FSEL_GPIO_IN) {
/* always transition through GPIO_IN */
@@ -309,6 +316,9 @@ static inline void bcm2835_pinctrl_fsel_set(
dev_dbg(pc->dev, "write %08x (%u <= %s)\n", val, pin,
bcm2835_functions[fsel]);
bcm2835_gpio_wr(pc, FSEL_REG(pin), val);
+
+unlock:
+ spin_unlock_irqrestore(&pc->fsel_lock, flags);
}
static int bcm2835_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -1248,6 +1258,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
pc->gpio_chip = *pdata->gpio_chip;
pc->gpio_chip.parent = dev;
+ spin_lock_init(&pc->fsel_lock);
for (i = 0; i < BCM2835_NUM_BANKS; i++) {
unsigned long events;
unsigned offset;
--
2.39.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCHv2] pinctrl-bcm2835.c: fix race condition when setting gpio dir
2023-04-20 12:47 [PATCHv2] pinctrl-bcm2835.c: fix race condition when setting gpio dir Hans Verkuil
@ 2023-04-21 9:01 ` Linus Walleij
0 siblings, 0 replies; 2+ messages in thread
From: Linus Walleij @ 2023-04-21 9:01 UTC (permalink / raw)
To: Hans Verkuil
Cc: open list:GPIO SUBSYSTEM, Linux Media Mailing List,
linux-rpi-kernel, Florian Fainelli, Stefan Wahren,
Broadcom internal kernel review list
On Thu, Apr 20, 2023 at 2:47 PM Hans Verkuil <hverkuil-cisco@xs4all.nl> wrote:
> In the past setting the pin direction called pinctrl_gpio_direction()
> which uses a mutex to serialize this. That was changed to set the
> direction directly in the pin controller driver, but that lost the
> serialization mechanism. Since the direction of multiple pins are in
> the same register you can have a race condition, something that was
> in fact observed with the cec-gpio driver.
>
> Add a new spinlock to serialize writing to the FSEL registers.
>
> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
> Fixes: 1a4541b68e25 ("pinctrl-bcm2835: don't call pinctrl_gpio_direction()")
I just applied this patch now so it can go in with the rest of the patches
for the merge window. I don't especially fancy having to immediately
start a fixes branch before I've even sent the bulk of patches to Torvalds.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-04-21 9:02 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-20 12:47 [PATCHv2] pinctrl-bcm2835.c: fix race condition when setting gpio dir Hans Verkuil
2023-04-21 9:01 ` 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).