[PATCH] gpio: rockchip: mark the GPIO controller as sleeping

Bartosz Golaszewski posted 1 patch 1 month ago
drivers/gpio/gpio-rockchip.c | 1 +
1 file changed, 1 insertion(+)
[PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Bartosz Golaszewski 1 month ago
The GPIO controller is configured as non-sleeping but it uses generic
pinctrl helpers which use a mutex for synchronization.

This can cause the following lockdep splat with shared GPIOs enabled on
boards which have multiple devices using the same GPIO:

BUG: sleeping function called from invalid context at
kernel/locking/mutex.c:591
in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 12, name:
kworker/u16:0
preempt_count: 1, expected: 0
RCU nest depth: 0, expected: 0
6 locks held by kworker/u16:0/12:
  #0: ffff0001f0018d48 ((wq_completion)events_unbound#2){+.+.}-{0:0},
at: process_one_work+0x18c/0x604
  #1: ffff8000842dbdf0 (deferred_probe_work){+.+.}-{0:0}, at:
process_one_work+0x1b4/0x604
  #2: ffff0001f18498f8 (&dev->mutex){....}-{4:4}, at:
__device_attach+0x38/0x1b0
  #3: ffff0001f75f1e90 (&gdev->srcu){.+.?}-{0:0}, at:
gpiod_direction_output_raw_commit+0x0/0x360
  #4: ffff0001f46e3db8 (&shared_desc->spinlock){....}-{3:3}, at:
gpio_shared_proxy_direction_output+0xd0/0x144 [gpio_shared_proxy]
  #5: ffff0001f180ee90 (&gdev->srcu){.+.?}-{0:0}, at:
gpiod_direction_output_raw_commit+0x0/0x360
irq event stamp: 81450
hardirqs last  enabled at (81449): [<ffff8000813acba4>]
_raw_spin_unlock_irqrestore+0x74/0x78
hardirqs last disabled at (81450): [<ffff8000813abfb8>]
_raw_spin_lock_irqsave+0x84/0x88
softirqs last  enabled at (79616): [<ffff8000811455fc>]
__alloc_skb+0x17c/0x1e8
softirqs last disabled at (79614): [<ffff8000811455fc>]
__alloc_skb+0x17c/0x1e8
CPU: 2 UID: 0 PID: 12 Comm: kworker/u16:0 Not tainted
6.19.0-rc4-next-20260105+ #11975 PREEMPT
Hardware name: Hardkernel ODROID-M1 (DT)
Workqueue: events_unbound deferred_probe_work_func
Call trace:
  show_stack+0x18/0x24 (C)
  dump_stack_lvl+0x90/0xd0
  dump_stack+0x18/0x24
  __might_resched+0x144/0x248
  __might_sleep+0x48/0x98
  __mutex_lock+0x5c/0x894
  mutex_lock_nested+0x24/0x30
  pinctrl_get_device_gpio_range+0x44/0x128
  pinctrl_gpio_direction+0x3c/0xe0
  pinctrl_gpio_direction_output+0x14/0x20
  rockchip_gpio_direction_output+0xb8/0x19c
  gpiochip_direction_output+0x38/0x94
  gpiod_direction_output_raw_commit+0x1d8/0x360
  gpiod_direction_output_nonotify+0x7c/0x230
  gpiod_direction_output+0x34/0xf8
  gpio_shared_proxy_direction_output+0xec/0x144 [gpio_shared_proxy]
  gpiochip_direction_output+0x38/0x94
  gpiod_direction_output_raw_commit+0x1d8/0x360
  gpiod_direction_output_nonotify+0x7c/0x230
  gpiod_configure_flags+0xbc/0x480
  gpiod_find_and_request+0x1a0/0x574
  gpiod_get_index+0x58/0x84
  devm_gpiod_get_index+0x20/0xb4
  devm_gpiod_get_optional+0x18/0x30
  rockchip_pcie_probe+0x98/0x380
  platform_probe+0x5c/0xac
  really_probe+0xbc/0x298

Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
Cc: stable@vger.kernel.org
Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
Closes: https://lore.kernel.org/all/d035fc29-3b03-4cd6-b8ec-001f93540bc6@samsung.com/
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 drivers/gpio/gpio-rockchip.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
index 47174eb3ba76..bae2061f15fc 100644
--- a/drivers/gpio/gpio-rockchip.c
+++ b/drivers/gpio/gpio-rockchip.c
@@ -593,6 +593,7 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
 	gc->ngpio = bank->nr_pins;
 	gc->label = bank->name;
 	gc->parent = bank->dev;
+	gc->can_sleep = true;
 
 	ret = gpiochip_add_data(gc, bank);
 	if (ret) {
-- 
2.47.3
Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Sebastian Reichel 4 weeks ago
Hi,

On Tue, Jan 06, 2026 at 10:00:11AM +0100, Bartosz Golaszewski wrote:
> The GPIO controller is configured as non-sleeping but it uses generic
> pinctrl helpers which use a mutex for synchronization.
> 
> This can cause the following lockdep splat with shared GPIOs enabled on
> boards which have multiple devices using the same GPIO:
> 
> BUG: sleeping function called from invalid context at
> kernel/locking/mutex.c:591
> in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 12, name:
> kworker/u16:0
> preempt_count: 1, expected: 0
> RCU nest depth: 0, expected: 0
> 6 locks held by kworker/u16:0/12:
>   #0: ffff0001f0018d48 ((wq_completion)events_unbound#2){+.+.}-{0:0},
> at: process_one_work+0x18c/0x604
>   #1: ffff8000842dbdf0 (deferred_probe_work){+.+.}-{0:0}, at:
> process_one_work+0x1b4/0x604
>   #2: ffff0001f18498f8 (&dev->mutex){....}-{4:4}, at:
> __device_attach+0x38/0x1b0
>   #3: ffff0001f75f1e90 (&gdev->srcu){.+.?}-{0:0}, at:
> gpiod_direction_output_raw_commit+0x0/0x360
>   #4: ffff0001f46e3db8 (&shared_desc->spinlock){....}-{3:3}, at:
> gpio_shared_proxy_direction_output+0xd0/0x144 [gpio_shared_proxy]
>   #5: ffff0001f180ee90 (&gdev->srcu){.+.?}-{0:0}, at:
> gpiod_direction_output_raw_commit+0x0/0x360
> irq event stamp: 81450
> hardirqs last  enabled at (81449): [<ffff8000813acba4>]
> _raw_spin_unlock_irqrestore+0x74/0x78
> hardirqs last disabled at (81450): [<ffff8000813abfb8>]
> _raw_spin_lock_irqsave+0x84/0x88
> softirqs last  enabled at (79616): [<ffff8000811455fc>]
> __alloc_skb+0x17c/0x1e8
> softirqs last disabled at (79614): [<ffff8000811455fc>]
> __alloc_skb+0x17c/0x1e8
> CPU: 2 UID: 0 PID: 12 Comm: kworker/u16:0 Not tainted
> 6.19.0-rc4-next-20260105+ #11975 PREEMPT
> Hardware name: Hardkernel ODROID-M1 (DT)
> Workqueue: events_unbound deferred_probe_work_func
> Call trace:
>   show_stack+0x18/0x24 (C)
>   dump_stack_lvl+0x90/0xd0
>   dump_stack+0x18/0x24
>   __might_resched+0x144/0x248
>   __might_sleep+0x48/0x98
>   __mutex_lock+0x5c/0x894
>   mutex_lock_nested+0x24/0x30
>   pinctrl_get_device_gpio_range+0x44/0x128
>   pinctrl_gpio_direction+0x3c/0xe0
>   pinctrl_gpio_direction_output+0x14/0x20
>   rockchip_gpio_direction_output+0xb8/0x19c
>   gpiochip_direction_output+0x38/0x94
>   gpiod_direction_output_raw_commit+0x1d8/0x360
>   gpiod_direction_output_nonotify+0x7c/0x230
>   gpiod_direction_output+0x34/0xf8
>   gpio_shared_proxy_direction_output+0xec/0x144 [gpio_shared_proxy]
>   gpiochip_direction_output+0x38/0x94
>   gpiod_direction_output_raw_commit+0x1d8/0x360
>   gpiod_direction_output_nonotify+0x7c/0x230
>   gpiod_configure_flags+0xbc/0x480
>   gpiod_find_and_request+0x1a0/0x574
>   gpiod_get_index+0x58/0x84
>   devm_gpiod_get_index+0x20/0xb4
>   devm_gpiod_get_optional+0x18/0x30
>   rockchip_pcie_probe+0x98/0x380
>   platform_probe+0x5c/0xac
>   really_probe+0xbc/0x298
> 
> Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
> Cc: stable@vger.kernel.org
> Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Closes: https://lore.kernel.org/all/d035fc29-3b03-4cd6-b8ec-001f93540bc6@samsung.com/
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> ---
>  drivers/gpio/gpio-rockchip.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
> index 47174eb3ba76..bae2061f15fc 100644
> --- a/drivers/gpio/gpio-rockchip.c
> +++ b/drivers/gpio/gpio-rockchip.c
> @@ -593,6 +593,7 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
>  	gc->ngpio = bank->nr_pins;
>  	gc->label = bank->name;
>  	gc->parent = bank->dev;
> +	gc->can_sleep = true;

This means all operations are marked as can_sleep, even though
pinctrl operations are only used for the direction setting.
I.e. the common get/set operations always worked in atomic mode,
but now complain. See for example:

https://lore.kernel.org/all/20260108-media-synopsys-hdmirx-fix-gpio-cansleep-v1-1-3570518d8bab@kernel.org/

It's not a big issue for the hdmirx driver specifically, but I wonder
how many more (less often tested) rockchip drivers use GPIOs from their
IRQ handler.

Considering setting or getting the GPIO from atomic context is much
more common than changing the direction - is there some way to
describe the sleep behavior in a more specific way in the GPIO
controller?

Greetings,

-- Sebastian
Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Bartosz Golaszewski 3 weeks, 5 days ago
On Sat, Jan 10, 2026 at 12:55 AM Sebastian Reichel
<sebastian.reichel@collabora.com> wrote:
>
> Hi,
>
> On Tue, Jan 06, 2026 at 10:00:11AM +0100, Bartosz Golaszewski wrote:
> > The GPIO controller is configured as non-sleeping but it uses generic
> > pinctrl helpers which use a mutex for synchronization.
> >
> > This can cause the following lockdep splat with shared GPIOs enabled on
> > boards which have multiple devices using the same GPIO:
> >

[snip]

> >
> > Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
> > Cc: stable@vger.kernel.org
> > Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > Closes: https://lore.kernel.org/all/d035fc29-3b03-4cd6-b8ec-001f93540bc6@samsung.com/
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> > ---
> >  drivers/gpio/gpio-rockchip.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
> > index 47174eb3ba76..bae2061f15fc 100644
> > --- a/drivers/gpio/gpio-rockchip.c
> > +++ b/drivers/gpio/gpio-rockchip.c
> > @@ -593,6 +593,7 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
> >       gc->ngpio = bank->nr_pins;
> >       gc->label = bank->name;
> >       gc->parent = bank->dev;
> > +     gc->can_sleep = true;
>
> This means all operations are marked as can_sleep, even though
> pinctrl operations are only used for the direction setting.
> I.e. the common get/set operations always worked in atomic mode,
> but now complain. See for example:
>
> https://lore.kernel.org/all/20260108-media-synopsys-hdmirx-fix-gpio-cansleep-v1-1-3570518d8bab@kernel.org/
>
> It's not a big issue for the hdmirx driver specifically, but I wonder
> how many more (less often tested) rockchip drivers use GPIOs from their
> IRQ handler.
>
> Considering setting or getting the GPIO from atomic context is much
> more common than changing the direction - is there some way to
> describe the sleep behavior in a more specific way in the GPIO
> controller?
>

No, there's no such switch at the moment. This is because there are
paths that we can take, where we *do* end up setting direction from
gpiod_set_value(). For instance:

gpiod_set_value()
  gpiod_set_value_nocheck()
    gpio_set_open_drain_value_commit()
      gpiochip_direction_output()

I'm afraid, for correctness, it has to be either sleeping, or not. I
would love - at some point - to make pinctrl mostly lockless with
SRCU, like we did with GPIO. That would solve this issue correctly.
But until then, I'm afraid we need to keep a chip-global switch for
sleeping.

Bartosz
Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Robin Murphy 2 weeks, 1 day ago
On 2026-01-12 9:08 am, Bartosz Golaszewski wrote:
> On Sat, Jan 10, 2026 at 12:55 AM Sebastian Reichel
> <sebastian.reichel@collabora.com> wrote:
>>
>> Hi,
>>
>> On Tue, Jan 06, 2026 at 10:00:11AM +0100, Bartosz Golaszewski wrote:
>>> The GPIO controller is configured as non-sleeping but it uses generic
>>> pinctrl helpers which use a mutex for synchronization.
>>>
>>> This can cause the following lockdep splat with shared GPIOs enabled on
>>> boards which have multiple devices using the same GPIO:
>>>
> 
> [snip]
> 
>>>
>>> Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
>>> Cc: stable@vger.kernel.org
>>> Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>> Closes: https://lore.kernel.org/all/d035fc29-3b03-4cd6-b8ec-001f93540bc6@samsung.com/
>>> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
>>> ---
>>>   drivers/gpio/gpio-rockchip.c | 1 +
>>>   1 file changed, 1 insertion(+)
>>>
>>> diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
>>> index 47174eb3ba76..bae2061f15fc 100644
>>> --- a/drivers/gpio/gpio-rockchip.c
>>> +++ b/drivers/gpio/gpio-rockchip.c
>>> @@ -593,6 +593,7 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
>>>        gc->ngpio = bank->nr_pins;
>>>        gc->label = bank->name;
>>>        gc->parent = bank->dev;
>>> +     gc->can_sleep = true;
>>
>> This means all operations are marked as can_sleep, even though
>> pinctrl operations are only used for the direction setting.
>> I.e. the common get/set operations always worked in atomic mode,
>> but now complain. See for example:
>>
>> https://lore.kernel.org/all/20260108-media-synopsys-hdmirx-fix-gpio-cansleep-v1-1-3570518d8bab@kernel.org/
>>
>> It's not a big issue for the hdmirx driver specifically, but I wonder
>> how many more (less often tested) rockchip drivers use GPIOs from their
>> IRQ handler.

Yeah, seems this finally reached my distro kernel and now the kernel log 
on one of my boards is totally flooded from gpio_ir_recv_irq() 
(legitimately) calling gpio_get_value()... that's not really OK :/

Thanks,
Robin.

>> Considering setting or getting the GPIO from atomic context is much
>> more common than changing the direction - is there some way to
>> describe the sleep behavior in a more specific way in the GPIO
>> controller?
>>
> 
> No, there's no such switch at the moment. This is because there are
> paths that we can take, where we *do* end up setting direction from
> gpiod_set_value(). For instance:
> 
> gpiod_set_value()
>    gpiod_set_value_nocheck()
>      gpio_set_open_drain_value_commit()
>        gpiochip_direction_output()
> 
> I'm afraid, for correctness, it has to be either sleeping, or not. I
> would love - at some point - to make pinctrl mostly lockless with
> SRCU, like we did with GPIO. That would solve this issue correctly.
> But until then, I'm afraid we need to keep a chip-global switch for
> sleeping.
> 
> Bartosz
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip

Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Diederik de Haas 2 weeks ago
On Fri Jan 23, 2026 at 2:27 PM CET, Robin Murphy wrote:
> On 2026-01-12 9:08 am, Bartosz Golaszewski wrote:
>> On Sat, Jan 10, 2026 at 12:55 AM Sebastian Reichel
>> <sebastian.reichel@collabora.com> wrote:
>>> On Tue, Jan 06, 2026 at 10:00:11AM +0100, Bartosz Golaszewski wrote:
>>>> The GPIO controller is configured as non-sleeping but it uses generic
>>>> pinctrl helpers which use a mutex for synchronization.
>>>>
>>>> This can cause the following lockdep splat with shared GPIOs enabled on
>>>> boards which have multiple devices using the same GPIO:
>>>>
>> 
>> [snip]
>> 
>>>>
>>>> Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
>>>> Cc: stable@vger.kernel.org
>>>> Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>>> Closes: https://lore.kernel.org/all/d035fc29-3b03-4cd6-b8ec-001f93540bc6@samsung.com/
>>>> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
>>>> ---
>>>>   drivers/gpio/gpio-rockchip.c | 1 +
>>>>   1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
>>>> index 47174eb3ba76..bae2061f15fc 100644
>>>> --- a/drivers/gpio/gpio-rockchip.c
>>>> +++ b/drivers/gpio/gpio-rockchip.c
>>>> @@ -593,6 +593,7 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
>>>>        gc->ngpio = bank->nr_pins;
>>>>        gc->label = bank->name;
>>>>        gc->parent = bank->dev;
>>>> +     gc->can_sleep = true;
>>>
>>> This means all operations are marked as can_sleep, even though
>>> pinctrl operations are only used for the direction setting.
>>> I.e. the common get/set operations always worked in atomic mode,
>>> but now complain. See for example:
>>>
>>> https://lore.kernel.org/all/20260108-media-synopsys-hdmirx-fix-gpio-cansleep-v1-1-3570518d8bab@kernel.org/
>>>
>>> It's not a big issue for the hdmirx driver specifically, but I wonder
>>> how many more (less often tested) rockchip drivers use GPIOs from their
>>> IRQ handler.
>
> Yeah, seems this finally reached my distro kernel and now the kernel log 
> on one of my boards is totally flooded from gpio_ir_recv_irq() 
> (legitimately) calling gpio_get_value()... that's not really OK :/

Yeah, I'm getting it too on several of my boards, like on Rock64:
https://paste.sr.ht/~diederik/154c5023a3a50d77f1da2195e7bb9a96f6a88555
(that's just a fraction as dmesg ran out of its buffer ...)
Also mentioned here:
https://lore.kernel.org/all/DFOEGOTI1AQ9.175GP7V1VK1XU@cknow-tech.com/

Diederik

>
> Thanks,
> Robin.
>
>>> Considering setting or getting the GPIO from atomic context is much
>>> more common than changing the direction - is there some way to
>>> describe the sleep behavior in a more specific way in the GPIO
>>> controller?
>>>
>> 
>> No, there's no such switch at the moment. This is because there are
>> paths that we can take, where we *do* end up setting direction from
>> gpiod_set_value(). For instance:
>> 
>> gpiod_set_value()
>>    gpiod_set_value_nocheck()
>>      gpio_set_open_drain_value_commit()
>>        gpiochip_direction_output()
>> 
>> I'm afraid, for correctness, it has to be either sleeping, or not. I
>> would love - at some point - to make pinctrl mostly lockless with
>> SRCU, like we did with GPIO. That would solve this issue correctly.
>> But until then, I'm afraid we need to keep a chip-global switch for
>> sleeping.
>> 
>> Bartosz
>> 
>> _______________________________________________
>> Linux-rockchip mailing list
>> Linux-rockchip@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Bartosz Golaszewski 2 weeks ago
On Fri, Jan 23, 2026 at 2:27 PM Robin Murphy <robin.murphy@arm.com> wrote:
>
> >>
> >> It's not a big issue for the hdmirx driver specifically, but I wonder
> >> how many more (less often tested) rockchip drivers use GPIOs from their
> >> IRQ handler.
>
> Yeah, seems this finally reached my distro kernel and now the kernel log
> on one of my boards is totally flooded from gpio_ir_recv_irq()
> (legitimately) calling gpio_get_value()... that's not really OK :/
>

This has always been a sleeping driver. The driver does not know the
firmware configuration it'll be passed and - as I explained above -
depending on the lookup flags, we may call .direction_output() and
descend into pinctrl which uses mutexes. Ideally, we'd make
GPIO-facing pinctrl operations not sleeping but this is a long-time
project and quite complex. Telling the GPIO core that it cannot sleep
is simply incorrect - even if it worked for this particular use-case -
and has an impact on paths we're choosing.

Can the GPIO reading in the gpio-ir-recv driver be done from a
high-priority workqueue by any chance? Or can we make it a threaded
interrupt?

Bartosz
Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Robin Murphy 2 weeks ago
On 2026-01-23 7:27 pm, Bartosz Golaszewski wrote:
> On Fri, Jan 23, 2026 at 2:27 PM Robin Murphy <robin.murphy@arm.com> wrote:
>>
>>>>
>>>> It's not a big issue for the hdmirx driver specifically, but I wonder
>>>> how many more (less often tested) rockchip drivers use GPIOs from their
>>>> IRQ handler.
>>
>> Yeah, seems this finally reached my distro kernel and now the kernel log
>> on one of my boards is totally flooded from gpio_ir_recv_irq()
>> (legitimately) calling gpio_get_value()... that's not really OK :/
>>
> 
> This has always been a sleeping driver. The driver does not know the
> firmware configuration it'll be passed and - as I explained above -
> depending on the lookup flags, we may call .direction_output() and
> descend into pinctrl which uses mutexes. Ideally, we'd make
> GPIO-facing pinctrl operations not sleeping but this is a long-time
> project and quite complex. Telling the GPIO core that it cannot sleep
> is simply incorrect - even if it worked for this particular use-case -
> and has an impact on paths we're choosing.
> 
> Can the GPIO reading in the gpio-ir-recv driver be done from a
> high-priority workqueue by any chance? Or can we make it a threaded
> interrupt?

rockchip_gpio_get() is essentially nothing but a readl(), please explain 
how that could sleep? Saying that countless in-tree and out-of-tree 
arbitrary GPIO consumer drivers should pointlessly refactor just to 
avoid the GPIO core spewing spurious WARN()s is not reasonable.

I appreciate there are cases where the warning most definitely *is* 
relevant, which is why I picked up this discussion rather than proposing 
a revert, even though the documentation says:

  * @can_sleep: flag must be set iff get()/set() methods sleep, as they

where since neither rockchip_gpio_get() nor rockchip_gpio_set() 
themselves sleep, apparently this flag must *not* be set. It's 
irrelevant that a higher-level gpiod_set_value() invocation might end up 
calling .set_direction before it gets as far as calling .set - that's 
not the gpio_chip's fault, and gpiolib knows exactly what it's doing.

What I'm getting at is that getting, and even (directly) setting a 
GPIO's value can reasonably be expected to be more common and applicable 
in a wider range of circumstances than changing its configuration, so 
the former should not be unfairly penalised because of the latter. This 
case is clearly distinct from external GPIO expanders on buses that 
fundamentally can't guarantee fast memory-mapped access at all, so 
trying to conflate it under the same flag doesn't fit, and that needs 
fixing ASAP, before the reverts *do* start piling in. Maybe that just 
means some new dir_can_sleep or more abstract dir_needs_pinctrl flag 
might suffice, maybe it's something more involved; I don't really know, 
and I don't have the bandwidth to take this on myself.

Thanks,
Robin.
Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Heiko Stübner 2 weeks ago
Am Freitag, 23. Januar 2026, 21:57:50 Mitteleuropäische Normalzeit schrieb Robin Murphy:
> On 2026-01-23 7:27 pm, Bartosz Golaszewski wrote:
> > On Fri, Jan 23, 2026 at 2:27 PM Robin Murphy <robin.murphy@arm.com> wrote:
> >>
> >>>>
> >>>> It's not a big issue for the hdmirx driver specifically, but I wonder
> >>>> how many more (less often tested) rockchip drivers use GPIOs from their
> >>>> IRQ handler.
> >>
> >> Yeah, seems this finally reached my distro kernel and now the kernel log
> >> on one of my boards is totally flooded from gpio_ir_recv_irq()
> >> (legitimately) calling gpio_get_value()... that's not really OK :/
> >>
> > 
> > This has always been a sleeping driver. The driver does not know the
> > firmware configuration it'll be passed and - as I explained above -
> > depending on the lookup flags, we may call .direction_output() and
> > descend into pinctrl which uses mutexes. Ideally, we'd make
> > GPIO-facing pinctrl operations not sleeping but this is a long-time
> > project and quite complex. Telling the GPIO core that it cannot sleep
> > is simply incorrect - even if it worked for this particular use-case -
> > and has an impact on paths we're choosing.
> > 
> > Can the GPIO reading in the gpio-ir-recv driver be done from a
> > high-priority workqueue by any chance? Or can we make it a threaded
> > interrupt?
> 
> rockchip_gpio_get() is essentially nothing but a readl(), please explain 
> how that could sleep? Saying that countless in-tree and out-of-tree 
> arbitrary GPIO consumer drivers should pointlessly refactor just to 
> avoid the GPIO core spewing spurious WARN()s is not reasonable.
> 
> I appreciate there are cases where the warning most definitely *is* 
> relevant, which is why I picked up this discussion rather than proposing 
> a revert, even though the documentation says:
> 
>   * @can_sleep: flag must be set iff get()/set() methods sleep, as they
> 
> where since neither rockchip_gpio_get() nor rockchip_gpio_set() 
> themselves sleep, apparently this flag must *not* be set. It's 
> irrelevant that a higher-level gpiod_set_value() invocation might end up 
> calling .set_direction before it gets as far as calling .set - that's 
> not the gpio_chip's fault, and gpiolib knows exactly what it's doing.
> 
> What I'm getting at is that getting, and even (directly) setting a 
> GPIO's value can reasonably be expected to be more common and applicable 
> in a wider range of circumstances than changing its configuration, so 
> the former should not be unfairly penalised because of the latter. This 
> case is clearly distinct from external GPIO expanders on buses that 
> fundamentally can't guarantee fast memory-mapped access at all, so 
> trying to conflate it under the same flag doesn't fit, and that needs 
> fixing ASAP, before the reverts *do* start piling in. Maybe that just 
> means some new dir_can_sleep or more abstract dir_needs_pinctrl flag 
> might suffice, maybe it's something more involved; I don't really know, 
> and I don't have the bandwidth to take this on myself.

the sadest part here is, that the dive from gpio to pinctrl is sort of
a remant of the past. Originally it was meant to "automatically" set
the gpio pinmux, but nowadays we (at least try to) have pinctrl entries
doing that separately.

But of course that's hard to enforce now, because we can't really know
where gpios without pinctrl might hide, and of course newer kernels
need to still run with old DTBs.

But...

rockchip_pmx_gpio_set_direction()'s only function is to set the GPIO
pinmux - it does not handle the actual the actual direction.

Can't we move the pinctrl_gpio_direction_input/_output() call just over
to the request callback of the gpiochip?


Heiko
Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Robin Murphy 2 weeks ago
On 2026-01-23 9:52 pm, Heiko Stübner wrote:
> Am Freitag, 23. Januar 2026, 21:57:50 Mitteleuropäische Normalzeit schrieb Robin Murphy:
>> On 2026-01-23 7:27 pm, Bartosz Golaszewski wrote:
>>> On Fri, Jan 23, 2026 at 2:27 PM Robin Murphy <robin.murphy@arm.com> wrote:
>>>>
>>>>>>
>>>>>> It's not a big issue for the hdmirx driver specifically, but I wonder
>>>>>> how many more (less often tested) rockchip drivers use GPIOs from their
>>>>>> IRQ handler.
>>>>
>>>> Yeah, seems this finally reached my distro kernel and now the kernel log
>>>> on one of my boards is totally flooded from gpio_ir_recv_irq()
>>>> (legitimately) calling gpio_get_value()... that's not really OK :/
>>>>
>>>
>>> This has always been a sleeping driver. The driver does not know the
>>> firmware configuration it'll be passed and - as I explained above -
>>> depending on the lookup flags, we may call .direction_output() and
>>> descend into pinctrl which uses mutexes. Ideally, we'd make
>>> GPIO-facing pinctrl operations not sleeping but this is a long-time
>>> project and quite complex. Telling the GPIO core that it cannot sleep
>>> is simply incorrect - even if it worked for this particular use-case -
>>> and has an impact on paths we're choosing.
>>>
>>> Can the GPIO reading in the gpio-ir-recv driver be done from a
>>> high-priority workqueue by any chance? Or can we make it a threaded
>>> interrupt?
>>
>> rockchip_gpio_get() is essentially nothing but a readl(), please explain
>> how that could sleep? Saying that countless in-tree and out-of-tree
>> arbitrary GPIO consumer drivers should pointlessly refactor just to
>> avoid the GPIO core spewing spurious WARN()s is not reasonable.
>>
>> I appreciate there are cases where the warning most definitely *is*
>> relevant, which is why I picked up this discussion rather than proposing
>> a revert, even though the documentation says:
>>
>>    * @can_sleep: flag must be set iff get()/set() methods sleep, as they
>>
>> where since neither rockchip_gpio_get() nor rockchip_gpio_set()
>> themselves sleep, apparently this flag must *not* be set. It's
>> irrelevant that a higher-level gpiod_set_value() invocation might end up
>> calling .set_direction before it gets as far as calling .set - that's
>> not the gpio_chip's fault, and gpiolib knows exactly what it's doing.
>>
>> What I'm getting at is that getting, and even (directly) setting a
>> GPIO's value can reasonably be expected to be more common and applicable
>> in a wider range of circumstances than changing its configuration, so
>> the former should not be unfairly penalised because of the latter. This
>> case is clearly distinct from external GPIO expanders on buses that
>> fundamentally can't guarantee fast memory-mapped access at all, so
>> trying to conflate it under the same flag doesn't fit, and that needs
>> fixing ASAP, before the reverts *do* start piling in. Maybe that just
>> means some new dir_can_sleep or more abstract dir_needs_pinctrl flag
>> might suffice, maybe it's something more involved; I don't really know,
>> and I don't have the bandwidth to take this on myself.
> 
> the sadest part here is, that the dive from gpio to pinctrl is sort of
> a remant of the past. Originally it was meant to "automatically" set
> the gpio pinmux, but nowadays we (at least try to) have pinctrl entries
> doing that separately.
> 
> But of course that's hard to enforce now, because we can't really know
> where gpios without pinctrl might hide, and of course newer kernels
> need to still run with old DTBs.
> 
> But...
> 
> rockchip_pmx_gpio_set_direction()'s only function is to set the GPIO
> pinmux - it does not handle the actual the actual direction.
> 
> Can't we move the pinctrl_gpio_direction_input/_output() call just over
> to the request callback of the gpiochip?

In fact, after an hour or so chasing through the code, is that not just
pretty much this? (Not even compile tested as I'd rather go to bed now...)

Cheers,
Robin.

----->8-----
diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
index 47174eb3ba76..118edd57c252 100644
--- a/drivers/gpio/gpio-rockchip.c
+++ b/drivers/gpio/gpio-rockchip.c
@@ -164,12 +164,6 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip,
  	unsigned long flags;
  	u32 data = input ? 0 : 1;
  
-
-	if (input)
-		pinctrl_gpio_direction_input(chip, offset);
-	else
-		pinctrl_gpio_direction_output(chip, offset);
-
  	raw_spin_lock_irqsave(&bank->slock, flags);
  	rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr);
  	raw_spin_unlock_irqrestore(&bank->slock, flags);
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index e44ef262beec..2fc67aeafdb3 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -3545,10 +3545,9 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
  	return 0;
  }
  
-static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
-					   struct pinctrl_gpio_range *range,
-					   unsigned offset,
-					   bool input)
+static int rockchip_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
+					    struct pinctrl_gpio_range *range,
+					    unsigned int offset)
  {
  	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
  	struct rockchip_pin_bank *bank;
@@ -3562,7 +3561,7 @@ static const struct pinmux_ops rockchip_pmx_ops = {
  	.get_function_name	= rockchip_pmx_get_func_name,
  	.get_function_groups	= rockchip_pmx_get_groups,
  	.set_mux		= rockchip_pmx_set,
-	.gpio_set_direction	= rockchip_pmx_gpio_set_direction,
+	.gpio_request_enable	= rockchip_pmx_gpio_request_enable,
  };
  
  /*

Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Bartosz Golaszewski 1 week, 6 days ago
On Sat, 24 Jan 2026 00:45:25 +0100, Robin Murphy <robin.murphy@arm.com> said:
> On 2026-01-23 9:52 pm, Heiko Stübner wrote:
>> Am Freitag, 23. Januar 2026, 21:57:50 Mitteleuropäische Normalzeit schrieb Robin Murphy:
>>> On 2026-01-23 7:27 pm, Bartosz Golaszewski wrote:
>>>> On Fri, Jan 23, 2026 at 2:27 PM Robin Murphy <robin.murphy@arm.com> wrote:
>>>>>
>>>>>>>
>>>>>>> It's not a big issue for the hdmirx driver specifically, but I wonder
>>>>>>> how many more (less often tested) rockchip drivers use GPIOs from their
>>>>>>> IRQ handler.
>>>>>
>>>>> Yeah, seems this finally reached my distro kernel and now the kernel log
>>>>> on one of my boards is totally flooded from gpio_ir_recv_irq()
>>>>> (legitimately) calling gpio_get_value()... that's not really OK :/
>>>>>
>>>>
>>>> This has always been a sleeping driver. The driver does not know the
>>>> firmware configuration it'll be passed and - as I explained above -
>>>> depending on the lookup flags, we may call .direction_output() and
>>>> descend into pinctrl which uses mutexes. Ideally, we'd make
>>>> GPIO-facing pinctrl operations not sleeping but this is a long-time
>>>> project and quite complex. Telling the GPIO core that it cannot sleep
>>>> is simply incorrect - even if it worked for this particular use-case -
>>>> and has an impact on paths we're choosing.
>>>>
>>>> Can the GPIO reading in the gpio-ir-recv driver be done from a
>>>> high-priority workqueue by any chance? Or can we make it a threaded
>>>> interrupt?
>>>

Let me circle back to my earlier question. Would the following change work?

diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index a6418ef782bc..1f95e54bd146 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -26,6 +26,11 @@ struct gpio_rc_dev {
 };

 static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id)
+{
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t gpio_ir_recv_irq_thread(int irq, void *dev_id)
 {
 	int val;
 	struct gpio_rc_dev *gpio_dev = dev_id;
@@ -120,9 +125,10 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)

 	platform_set_drvdata(pdev, gpio_dev);

-	return devm_request_irq(dev, gpio_dev->irq, gpio_ir_recv_irq,
-				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-				"gpio-ir-recv-irq", gpio_dev);
+	return devm_request_threaded_irq(dev, gpio_dev->irq, gpio_ir_recv_irq,
+					 gpio_ir_recv_irq_thread,
+					 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+					 "gpio-ir-recv-irq", gpio_dev);
 }

 static void gpio_ir_recv_remove(struct platform_device *pdev)

>>> rockchip_gpio_get() is essentially nothing but a readl(), please explain
>>> how that could sleep? Saying that countless in-tree and out-of-tree
>>> arbitrary GPIO consumer drivers should pointlessly refactor just to
>>> avoid the GPIO core spewing spurious WARN()s is not reasonable.
>>>

Right, so gpiod_get_value() is a bit different from gpiod_set_value() because
it indeed can't descend into pinctrl.

>>> I appreciate there are cases where the warning most definitely *is*
>>> relevant, which is why I picked up this discussion rather than proposing
>>> a revert, even though the documentation says:
>>>
>>>    * @can_sleep: flag must be set iff get()/set() methods sleep, as they
>>>
>>> where since neither rockchip_gpio_get() nor rockchip_gpio_set()
>>> themselves sleep, apparently this flag must *not* be set. It's
>>> irrelevant that a higher-level gpiod_set_value() invocation might end up
>>> calling .set_direction before it gets as far as calling .set - that's
>>> not the gpio_chip's fault, and gpiolib knows exactly what it's doing.
>>>

Well, the wording may be unfortunate and it's probably been this way for a
long time. I don't know the history here, this probably needs to be revised.

Please keep in mind: I don't deal with a single rockchip driver but with
a generic subsystem supporting hundreds of GPIO drivers and thousands of
users across the kernel tree. Not to mention all the API abuse like people
calling direction_output() from atomic context etc. We have all kinds of
combinations of sleeping and non-sleeping consumers and suppliers. It's
sometimes hard to find the middle ground.

Maybe the core GPIO code should not try to simulate open-source/open-drain
on non-sleeping chips for gpiod_set_value(). Or maybe we need a .uses_pinctrl
flag parallel to .cansleep which tells GPIO core that while set/get don't
sleep, direction_output/input may.

>
>> rockchip_pmx_gpio_set_direction()'s only function is to set the GPIO
>> pinmux - it does not handle the actual the actual direction.
>>
>> Can't we move the pinctrl_gpio_direction_input/_output() call just over
>> to the request callback of the gpiochip?
>

What if the user calls gpiod_direction_output() on a pin set to input?

> In fact, after an hour or so chasing through the code, is that not just
> pretty much this? (Not even compile tested as I'd rather go to bed now...)
>
> Cheers,
> Robin.
>
> ----->8-----
> diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
> index 47174eb3ba76..118edd57c252 100644
> --- a/drivers/gpio/gpio-rockchip.c
> +++ b/drivers/gpio/gpio-rockchip.c
> @@ -164,12 +164,6 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip,
>   	unsigned long flags;
>   	u32 data = input ? 0 : 1;
>
> -
> -	if (input)
> -		pinctrl_gpio_direction_input(chip, offset);
> -	else
> -		pinctrl_gpio_direction_output(chip, offset);
> -
>   	raw_spin_lock_irqsave(&bank->slock, flags);
>   	rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr);
>   	raw_spin_unlock_irqrestore(&bank->slock, flags);
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
> index e44ef262beec..2fc67aeafdb3 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c
> @@ -3545,10 +3545,9 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
>   	return 0;
>   }
>
> -static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
> -					   struct pinctrl_gpio_range *range,
> -					   unsigned offset,
> -					   bool input)
> +static int rockchip_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
> +					    struct pinctrl_gpio_range *range,
> +					    unsigned int offset)
>   {
>   	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
>   	struct rockchip_pin_bank *bank;
> @@ -3562,7 +3561,7 @@ static const struct pinmux_ops rockchip_pmx_ops = {
>   	.get_function_name	= rockchip_pmx_get_func_name,
>   	.get_function_groups	= rockchip_pmx_get_groups,
>   	.set_mux		= rockchip_pmx_set,
> -	.gpio_set_direction	= rockchip_pmx_gpio_set_direction,
> +	.gpio_request_enable	= rockchip_pmx_gpio_request_enable,
>   };
>
>   /*
>

I'm not sure what's going on here. You don't really need to call
pinctrl_gpio_direction_input/output()?

I'm putting it on my TODO list to figure out a proper way of interacting
with pinctrl. At the same time, I want to fix your problem so the .uses_pinctrl
flag sounds like a solution. This would make gpio-shared-proxy still use
a mutex but we wouldn't warn in gpiod_get_value(). Unless you can simply switch
to a threaded interrupt in the IR driver. Maybe the latency would be
negligible?

Bartosz
Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Bartosz Golaszewski 1 month ago
On Tue, 06 Jan 2026 10:00:11 +0100, Bartosz Golaszewski wrote:
> The GPIO controller is configured as non-sleeping but it uses generic
> pinctrl helpers which use a mutex for synchronization.
> 
> This can cause the following lockdep splat with shared GPIOs enabled on
> boards which have multiple devices using the same GPIO:
> 
> BUG: sleeping function called from invalid context at
> kernel/locking/mutex.c:591
> in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 12, name:
> kworker/u16:0
> preempt_count: 1, expected: 0
> RCU nest depth: 0, expected: 0
> 6 locks held by kworker/u16:0/12:
>   #0: ffff0001f0018d48 ((wq_completion)events_unbound#2){+.+.}-{0:0},
> at: process_one_work+0x18c/0x604
>   #1: ffff8000842dbdf0 (deferred_probe_work){+.+.}-{0:0}, at:
> process_one_work+0x1b4/0x604
>   #2: ffff0001f18498f8 (&dev->mutex){....}-{4:4}, at:
> __device_attach+0x38/0x1b0
>   #3: ffff0001f75f1e90 (&gdev->srcu){.+.?}-{0:0}, at:
> gpiod_direction_output_raw_commit+0x0/0x360
>   #4: ffff0001f46e3db8 (&shared_desc->spinlock){....}-{3:3}, at:
> gpio_shared_proxy_direction_output+0xd0/0x144 [gpio_shared_proxy]
>   #5: ffff0001f180ee90 (&gdev->srcu){.+.?}-{0:0}, at:
> gpiod_direction_output_raw_commit+0x0/0x360
> irq event stamp: 81450
> hardirqs last  enabled at (81449): [<ffff8000813acba4>]
> _raw_spin_unlock_irqrestore+0x74/0x78
> hardirqs last disabled at (81450): [<ffff8000813abfb8>]
> _raw_spin_lock_irqsave+0x84/0x88
> softirqs last  enabled at (79616): [<ffff8000811455fc>]
> __alloc_skb+0x17c/0x1e8
> softirqs last disabled at (79614): [<ffff8000811455fc>]
> __alloc_skb+0x17c/0x1e8
> CPU: 2 UID: 0 PID: 12 Comm: kworker/u16:0 Not tainted
> 6.19.0-rc4-next-20260105+ #11975 PREEMPT
> Hardware name: Hardkernel ODROID-M1 (DT)
> Workqueue: events_unbound deferred_probe_work_func
> Call trace:
>   show_stack+0x18/0x24 (C)
>   dump_stack_lvl+0x90/0xd0
>   dump_stack+0x18/0x24
>   __might_resched+0x144/0x248
>   __might_sleep+0x48/0x98
>   __mutex_lock+0x5c/0x894
>   mutex_lock_nested+0x24/0x30
>   pinctrl_get_device_gpio_range+0x44/0x128
>   pinctrl_gpio_direction+0x3c/0xe0
>   pinctrl_gpio_direction_output+0x14/0x20
>   rockchip_gpio_direction_output+0xb8/0x19c
>   gpiochip_direction_output+0x38/0x94
>   gpiod_direction_output_raw_commit+0x1d8/0x360
>   gpiod_direction_output_nonotify+0x7c/0x230
>   gpiod_direction_output+0x34/0xf8
>   gpio_shared_proxy_direction_output+0xec/0x144 [gpio_shared_proxy]
>   gpiochip_direction_output+0x38/0x94
>   gpiod_direction_output_raw_commit+0x1d8/0x360
>   gpiod_direction_output_nonotify+0x7c/0x230
>   gpiod_configure_flags+0xbc/0x480
>   gpiod_find_and_request+0x1a0/0x574
>   gpiod_get_index+0x58/0x84
>   devm_gpiod_get_index+0x20/0xb4
>   devm_gpiod_get_optional+0x18/0x30
>   rockchip_pcie_probe+0x98/0x380
>   platform_probe+0x5c/0xac
>   really_probe+0xbc/0x298
> 
> [...]

Applied, thanks!

[1/1] gpio: rockchip: mark the GPIO controller as sleeping
      commit: 20cf2aed89ac6d78a0122e31c875228e15247194

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Re: [PATCH] gpio: rockchip: mark the GPIO controller as sleeping
Posted by Heiko Stuebner 1 month ago
Am Dienstag, 6. Januar 2026, 10:00:11 Mitteleuropäische Normalzeit schrieb Bartosz Golaszewski:
> The GPIO controller is configured as non-sleeping but it uses generic
> pinctrl helpers which use a mutex for synchronization.
> 
> This can cause the following lockdep splat with shared GPIOs enabled on
> boards which have multiple devices using the same GPIO:
> 
> BUG: sleeping function called from invalid context at
> kernel/locking/mutex.c:591
> in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 12, name:
> kworker/u16:0
> preempt_count: 1, expected: 0
> RCU nest depth: 0, expected: 0
> 6 locks held by kworker/u16:0/12:
>   #0: ffff0001f0018d48 ((wq_completion)events_unbound#2){+.+.}-{0:0},
> at: process_one_work+0x18c/0x604
>   #1: ffff8000842dbdf0 (deferred_probe_work){+.+.}-{0:0}, at:
> process_one_work+0x1b4/0x604
>   #2: ffff0001f18498f8 (&dev->mutex){....}-{4:4}, at:
> __device_attach+0x38/0x1b0
>   #3: ffff0001f75f1e90 (&gdev->srcu){.+.?}-{0:0}, at:
> gpiod_direction_output_raw_commit+0x0/0x360
>   #4: ffff0001f46e3db8 (&shared_desc->spinlock){....}-{3:3}, at:
> gpio_shared_proxy_direction_output+0xd0/0x144 [gpio_shared_proxy]
>   #5: ffff0001f180ee90 (&gdev->srcu){.+.?}-{0:0}, at:
> gpiod_direction_output_raw_commit+0x0/0x360
> irq event stamp: 81450
> hardirqs last  enabled at (81449): [<ffff8000813acba4>]
> _raw_spin_unlock_irqrestore+0x74/0x78
> hardirqs last disabled at (81450): [<ffff8000813abfb8>]
> _raw_spin_lock_irqsave+0x84/0x88
> softirqs last  enabled at (79616): [<ffff8000811455fc>]
> __alloc_skb+0x17c/0x1e8
> softirqs last disabled at (79614): [<ffff8000811455fc>]
> __alloc_skb+0x17c/0x1e8
> CPU: 2 UID: 0 PID: 12 Comm: kworker/u16:0 Not tainted
> 6.19.0-rc4-next-20260105+ #11975 PREEMPT
> Hardware name: Hardkernel ODROID-M1 (DT)
> Workqueue: events_unbound deferred_probe_work_func
> Call trace:
>   show_stack+0x18/0x24 (C)
>   dump_stack_lvl+0x90/0xd0
>   dump_stack+0x18/0x24
>   __might_resched+0x144/0x248
>   __might_sleep+0x48/0x98
>   __mutex_lock+0x5c/0x894
>   mutex_lock_nested+0x24/0x30
>   pinctrl_get_device_gpio_range+0x44/0x128
>   pinctrl_gpio_direction+0x3c/0xe0
>   pinctrl_gpio_direction_output+0x14/0x20
>   rockchip_gpio_direction_output+0xb8/0x19c
>   gpiochip_direction_output+0x38/0x94
>   gpiod_direction_output_raw_commit+0x1d8/0x360
>   gpiod_direction_output_nonotify+0x7c/0x230
>   gpiod_direction_output+0x34/0xf8
>   gpio_shared_proxy_direction_output+0xec/0x144 [gpio_shared_proxy]
>   gpiochip_direction_output+0x38/0x94
>   gpiod_direction_output_raw_commit+0x1d8/0x360
>   gpiod_direction_output_nonotify+0x7c/0x230
>   gpiod_configure_flags+0xbc/0x480
>   gpiod_find_and_request+0x1a0/0x574
>   gpiod_get_index+0x58/0x84
>   devm_gpiod_get_index+0x20/0xb4
>   devm_gpiod_get_optional+0x18/0x30
>   rockchip_pcie_probe+0x98/0x380
>   platform_probe+0x5c/0xac
>   really_probe+0xbc/0x298
> 
> Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
> Cc: stable@vger.kernel.org
> Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Closes: https://lore.kernel.org/all/d035fc29-3b03-4cd6-b8ec-001f93540bc6@samsung.com/
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

Acked-by: Heiko Stuebner <heiko@sntech.de>