Linux GPIO subsystem development
 help / color / mirror / Atom feed
* Re: [PATCH v6 05/17] pinctrl: airoha: an7581: fix mux/conf of pcie_reset pins
From: Krzysztof Kozlowski @ 2026-06-29  6:42 UTC (permalink / raw)
  To: Mikhail Kshevetskiy
  Cc: Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lorenzo Bianconi, Christian Marangi, AngeloGioacchino Del Regno,
	Benjamin Larsson, linux-gpio, devicetree, linux-kernel,
	linux-mediatek, Markus Gothe, Matheus Sampaio Queiroga
In-Reply-To: <20260628143733.273651-6-mikhail.kshevetskiy@iopsys.eu>

On Sun, Jun 28, 2026 at 05:37:21PM +0300, Mikhail Kshevetskiy wrote:
> In the an7581 case
>  * gpio47 and pcie_reset0 shares pin 60,
>  * gpio48 and pcie_reset1 shares pin 61,
>  * gpio49 and pcie_reset2 shares pin 62.
> but current driver treat them as pins 61--63. This is wrong.
> 
> Also current an7581 pinmux implementation have following issues:
>  * current pcie_reset pin function actually sets corresponding
>    pins as gpios.
>  * there is no proper way to set pcie_reset pins as gpios.
>  * there is no way to set pcie_reset pins as pwm.
> 
> This patch fixes above issues. Also device tree binding schema
> was updated.

Same comment.

Please run scripts/checkpatch.pl on the patches and fix reported
warnings. After that, run also 'scripts/checkpatch.pl --strict' on the
patches and (probably) fix more warnings. Some warnings can be ignored,
especially from --strict run, but the code here looks like it needs a
fix. Feel free to get in touch if the warning is not clear.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v6 17/17] pinctrl: airoha: add support of an7563 SoC
From: Krzysztof Kozlowski @ 2026-06-29  6:43 UTC (permalink / raw)
  To: Mikhail Kshevetskiy
  Cc: Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lorenzo Bianconi, Christian Marangi, AngeloGioacchino Del Regno,
	Benjamin Larsson, linux-gpio, devicetree, linux-kernel,
	linux-mediatek, Markus Gothe, Matheus Sampaio Queiroga
In-Reply-To: <20260628143733.273651-18-mikhail.kshevetskiy@iopsys.eu>

On Sun, Jun 28, 2026 at 05:37:33PM +0300, Mikhail Kshevetskiy wrote:
> This patch adds support of Airoha an7563 SoC pin controller.
> Also it adds corresponding device tree binding schema.
> 
> Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
> ---
>  .../pinctrl/airoha,an7563-pinctrl.yaml        |  348 +++++

I could understand ignoring checkpatch when removing pieces of ABI.
I can imagine it feels logical to someone.

This I do not understand. REQUIREMENT to run checkpatch is there for a reason.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v6 15/17] pinctrl: airoha: add support of en7523 SoC
From: Krzysztof Kozlowski @ 2026-06-29  6:50 UTC (permalink / raw)
  To: Mikhail Kshevetskiy
  Cc: Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Lorenzo Bianconi, Christian Marangi, AngeloGioacchino Del Regno,
	Benjamin Larsson, linux-gpio, devicetree, linux-kernel,
	linux-mediatek, Markus Gothe, Matheus Sampaio Queiroga
In-Reply-To: <20260628143733.273651-16-mikhail.kshevetskiy@iopsys.eu>

On Sun, Jun 28, 2026 at 05:37:31PM +0300, Mikhail Kshevetskiy wrote:
> This patch adds support of Airoha en7523 SoC pin controller.
> Also it adds corresponding device tree binding schema.
> 
> Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
> ---
>  .../pinctrl/airoha,en7523-pinctrl.yaml        |  375 ++++++
>  drivers/pinctrl/airoha/Kconfig                |    6 +
>  drivers/pinctrl/airoha/Makefile               |    1 +
>  drivers/pinctrl/airoha/pinctrl-en7523.c       | 1124 +++++++++++++++++

Please run scripts/checkpatch.pl on the patches and fix reported
warnings. After that, run also 'scripts/checkpatch.pl --strict' on the
patches and (probably) fix more warnings. Some warnings can be ignored,
especially from --strict run, but the code here looks like it needs a
fix. Feel free to get in touch if the warning is not clear.


> +    pinctrl {
> +      compatible = "airoha,en7521-pinctrl";

Wrong compatible.

> +
> +      interrupt-parent = <&gic>;
> +      interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;


^ permalink raw reply

* Re: [PATCH 00/32] x86/msr: Drop 32-bit MSR interfaces
From: Arnd Bergmann @ 2026-06-29  6:52 UTC (permalink / raw)
  To: Juergen Gross, linux-kernel, linux-pm, linux-edac@vger.kernel.org,
	x86, linux-acpi, kvm, linux-coco, linux-pci, virtualization,
	linux-ide, dri-devel, linux-fbdev, linux-crypto,
	open list:GPIO SUBSYSTEM, linux-hyperv, linux-hwmon,
	linux-perf-users, linux-mtd, platform-driver-x86
  Cc: Rafael J . Wysocki, Daniel Lezcano, Zhang Rui,
	lukasz.luba@arm.com, Jason Baron, Borislav Petkov, Tony Luck,
	Yazen Ghannam, Len Brown, Pavel Machek, Thomas Gleixner,
	Ingo Molnar, Dave Hansen, H. Peter Anvin, Sean Christopherson,
	Paolo Bonzini, Kirill A. Shutemov, Rick Edgecombe, Pu Wen,
	Bjorn Helgaas, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Viresh Kumar,
	Reinette Chatre, Dave Martin, James Morse, Babu Moger,
	Tony W Wang-oc, Damien Le Moal, Niklas Cassel, Dave Airlie,
	Helge Deller, linux-geode, Olivia Mackall, Herbert Xu,
	Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
	Guenter Roeck, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark, Josh Poimboeuf,
	Pawan Gupta, Vitaly Kuznetsov, Andy Lutomirski, Boris Ostrovsky,
	Huang Rui, Mario Limonciello, Perry Yuan, K Prateek Nayak,
	srinivas.pandruvada@linux.intel.com, Artem Bityutskiy,
	Artem Bityutskiy, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Ashok Raj, Hans de Goede, Ilpo Järvinen,
	Rajneesh Bhardwaj, David E Box, xen-devel
In-Reply-To: <20260629060526.3638272-1-jgross@suse.com>

On Mon, Jun 29, 2026, at 08:04, Juergen Gross wrote:
> For accessing the MSR registers on the local CPU, there are 2 types of
> interfaces: the "modern" 64-bit ones (rdmsrq() etc.) and the 32-bit
> ones (rdmsr() etc.) which are using the upper and lower 32-bit halves
> of the 64-bit wide MSR register values.
>
> The 32-bit interfaces are not optimal for 3 reasons:
>
> - They are based on primitives using 64-bit sized values anyway.
>
> - Modern x86 CPUs have added support for MSR access instructions using
>   an immediate value instead of a register for addressing the MSR,
>   while the value is in a 64-bit register.
>
> - rdmsr() is a macro storing the upper and lower 32-bit halves in
>   variables specified as macro parameters. This is obscuring variable
>   assignment through a macro. Additionally rdmsrq() is mimicking this
>   pattern by being a macro, too, with the target variable specified as
>   a parameter as well.
>
> For those reasons drop the 32-bit interfaces for accessing the x86 MSR
> registers completely and only use the 64-bit variants.

Hi Jürgen,

I assume this is fine, but since you don't mention it explicitly here,
please clarify what this means for 32-bit CPUs without the rdmsrq
instruction. Those will continue using the same instructions as before
and just change the calling conventions, right?

> Note that most patches of this series are independent from each other.
> Only the patches removing a specific interface (patches 7, 15, 26 and
> 30) and the last two patches of the series depend on all previous
> patches.

It looks like you are touching most files twice or more here, to
first convert from rdmsr to rdmsrq and then to change the
two-argument rdmsrq() macro to a single-argument inline. If you
introduce the inline version of rdmsrq() first, you should be
able to skip the second step (patch 31) as they could be able
to coexist.

     Arnd

^ permalink raw reply

* Re: [PATCH 00/32] x86/msr: Drop 32-bit MSR interfaces
From: Jürgen Groß @ 2026-06-29  7:01 UTC (permalink / raw)
  To: Arnd Bergmann, linux-kernel, linux-pm, linux-edac@vger.kernel.org,
	x86, linux-acpi, kvm, linux-coco, linux-pci, virtualization,
	linux-ide, dri-devel, linux-fbdev, linux-crypto,
	open list:GPIO SUBSYSTEM, linux-hyperv, linux-hwmon,
	linux-perf-users, linux-mtd, platform-driver-x86
  Cc: Rafael J . Wysocki, Daniel Lezcano, Zhang Rui,
	lukasz.luba@arm.com, Jason Baron, Borislav Petkov, Tony Luck,
	Yazen Ghannam, Len Brown, Pavel Machek, Thomas Gleixner,
	Ingo Molnar, Dave Hansen, H. Peter Anvin, Sean Christopherson,
	Paolo Bonzini, Kirill A. Shutemov, Rick Edgecombe, Pu Wen,
	Bjorn Helgaas, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Viresh Kumar,
	Reinette Chatre, Dave Martin, James Morse, Babu Moger,
	Tony W Wang-oc, Damien Le Moal, Niklas Cassel, Dave Airlie,
	Helge Deller, linux-geode, Olivia Mackall, Herbert Xu,
	Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
	Guenter Roeck, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark, Josh Poimboeuf,
	Pawan Gupta, Vitaly Kuznetsov, Andy Lutomirski, Boris Ostrovsky,
	Huang Rui, Mario Limonciello, Perry Yuan, K Prateek Nayak,
	srinivas.pandruvada@linux.intel.com, Artem Bityutskiy,
	Artem Bityutskiy, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Ashok Raj, Hans de Goede, Ilpo Järvinen,
	Rajneesh Bhardwaj, David E Box, xen-devel
In-Reply-To: <d7c1db52-529a-43cc-ac7d-38b52627e8bc@app.fastmail.com>


[-- Attachment #1.1.1: Type: text/plain, Size: 2378 bytes --]

On 29.06.26 08:52, Arnd Bergmann wrote:
> On Mon, Jun 29, 2026, at 08:04, Juergen Gross wrote:
>> For accessing the MSR registers on the local CPU, there are 2 types of
>> interfaces: the "modern" 64-bit ones (rdmsrq() etc.) and the 32-bit
>> ones (rdmsr() etc.) which are using the upper and lower 32-bit halves
>> of the 64-bit wide MSR register values.
>>
>> The 32-bit interfaces are not optimal for 3 reasons:
>>
>> - They are based on primitives using 64-bit sized values anyway.
>>
>> - Modern x86 CPUs have added support for MSR access instructions using
>>    an immediate value instead of a register for addressing the MSR,
>>    while the value is in a 64-bit register.
>>
>> - rdmsr() is a macro storing the upper and lower 32-bit halves in
>>    variables specified as macro parameters. This is obscuring variable
>>    assignment through a macro. Additionally rdmsrq() is mimicking this
>>    pattern by being a macro, too, with the target variable specified as
>>    a parameter as well.
>>
>> For those reasons drop the 32-bit interfaces for accessing the x86 MSR
>> registers completely and only use the 64-bit variants.
> 
> Hi Jürgen,
> 
> I assume this is fine, but since you don't mention it explicitly here,
> please clarify what this means for 32-bit CPUs without the rdmsrq
> instruction. Those will continue using the same instructions as before
> and just change the calling conventions, right?

Yes. I thought this would be clear from the following:

   - They are based on primitives using 64-bit sized values anyway.

> 
>> Note that most patches of this series are independent from each other.
>> Only the patches removing a specific interface (patches 7, 15, 26 and
>> 30) and the last two patches of the series depend on all previous
>> patches.
> 
> It looks like you are touching most files twice or more here, to
> first convert from rdmsr to rdmsrq and then to change the
> two-argument rdmsrq() macro to a single-argument inline. If you
> introduce the inline version of rdmsrq() first, you should be
> able to skip the second step (patch 31) as they could be able
> to coexist.

I've discussed how to structure the series with Ingo Molnar before [1]. The
current approach was his preference.


Juergen

[1]: https://lore.kernel.org/lkml/f8d02c78-4681-4043-a5fa-921fa790b1b4@suse.com/

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply

* Re: [PATCH 00/32] x86/msr: Drop 32-bit MSR interfaces
From: Arnd Bergmann @ 2026-06-29  8:06 UTC (permalink / raw)
  To: Juergen Gross, linux-kernel, linux-pm, linux-edac@vger.kernel.org,
	x86, linux-acpi, kvm, linux-coco, linux-pci, virtualization,
	linux-ide, dri-devel, linux-fbdev, linux-crypto,
	open list:GPIO SUBSYSTEM, linux-hyperv, linux-hwmon,
	linux-perf-users, linux-mtd, platform-driver-x86
  Cc: Rafael J . Wysocki, Daniel Lezcano, Zhang Rui,
	lukasz.luba@arm.com, Jason Baron, Borislav Petkov, Tony Luck,
	Yazen Ghannam, Len Brown, Pavel Machek, Thomas Gleixner,
	Ingo Molnar, Dave Hansen, H. Peter Anvin, Sean Christopherson,
	Paolo Bonzini, Kirill A. Shutemov, Rick Edgecombe, Pu Wen,
	Bjorn Helgaas, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Viresh Kumar,
	Reinette Chatre, Dave Martin, James Morse, Babu Moger,
	Tony W Wang-oc, Damien Le Moal, Niklas Cassel, Dave Airlie,
	Helge Deller, linux-geode, Olivia Mackall, Herbert Xu,
	Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
	Guenter Roeck, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark, Josh Poimboeuf,
	Pawan Gupta, Vitaly Kuznetsov, Andy Lutomirski, Boris Ostrovsky,
	Huang Rui, Mario Limonciello, Perry Yuan, K Prateek Nayak,
	srinivas.pandruvada@linux.intel.com, Artem Bityutskiy,
	Artem Bityutskiy, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Ashok Raj, Hans de Goede, Ilpo Järvinen,
	Rajneesh Bhardwaj, David E Box, xen-devel
In-Reply-To: <c1608c48-13c2-4290-826b-28b5ca51eaf7@suse.com>

On Mon, Jun 29, 2026, at 09:01, Jürgen Groß wrote:
> On 29.06.26 08:52, Arnd Bergmann wrote:
>> On Mon, Jun 29, 2026, at 08:04, Juergen Gross wrote:
>> 
>> I assume this is fine, but since you don't mention it explicitly here,
>> please clarify what this means for 32-bit CPUs without the rdmsrq
>> instruction. Those will continue using the same instructions as before
>> and just change the calling conventions, right?
>
> Yes. I thought this would be clear from the following:
>
>    - They are based on primitives using 64-bit sized values anyway.

Right, that was my reading of it as well, but it's not entirely
clear when the function name is the same as the mnemonic of an
instruction that only exists on newer CPUs and the later patch
descriptions (e.g. 25/32 that I was Cc's on) have a much shorter
explanation.

>>> Note that most patches of this series are independent from each other.
>>> Only the patches removing a specific interface (patches 7, 15, 26 and
>>> 30) and the last two patches of the series depend on all previous
>>> patches.
>> 
>> It looks like you are touching most files twice or more here, to
>> first convert from rdmsr to rdmsrq and then to change the
>> two-argument rdmsrq() macro to a single-argument inline. If you
>> introduce the inline version of rdmsrq() first, you should be
>> able to skip the second step (patch 31) as they could be able
>> to coexist.
>
> I've discussed how to structure the series with Ingo Molnar before [1]. The
> current approach was his preference.

Ok.

      Arnd

^ permalink raw reply

* Re: [PATCH 00/32] x86/msr: Drop 32-bit MSR interfaces
From: Jürgen Groß @ 2026-06-29  8:15 UTC (permalink / raw)
  To: Arnd Bergmann, linux-kernel, linux-pm, linux-edac@vger.kernel.org,
	x86, linux-acpi, kvm, linux-coco, linux-pci, virtualization,
	linux-ide, dri-devel, linux-fbdev, linux-crypto,
	open list:GPIO SUBSYSTEM, linux-hyperv, linux-hwmon,
	linux-perf-users, linux-mtd, platform-driver-x86
  Cc: Rafael J . Wysocki, Daniel Lezcano, Zhang Rui,
	lukasz.luba@arm.com, Jason Baron, Borislav Petkov, Tony Luck,
	Yazen Ghannam, Len Brown, Pavel Machek, Thomas Gleixner,
	Ingo Molnar, Dave Hansen, H. Peter Anvin, Sean Christopherson,
	Paolo Bonzini, Kirill A. Shutemov, Rick Edgecombe, Pu Wen,
	Bjorn Helgaas, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Viresh Kumar,
	Reinette Chatre, Dave Martin, James Morse, Babu Moger,
	Tony W Wang-oc, Damien Le Moal, Niklas Cassel, Dave Airlie,
	Helge Deller, linux-geode, Olivia Mackall, Herbert Xu,
	Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
	Guenter Roeck, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark, Josh Poimboeuf,
	Pawan Gupta, Vitaly Kuznetsov, Andy Lutomirski, Boris Ostrovsky,
	Huang Rui, Mario Limonciello, Perry Yuan, K Prateek Nayak,
	srinivas.pandruvada@linux.intel.com, Artem Bityutskiy,
	Artem Bityutskiy, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Ashok Raj, Hans de Goede, Ilpo Järvinen,
	Rajneesh Bhardwaj, David E Box, xen-devel
In-Reply-To: <7332feff-2649-496c-8e49-b0a19eb54a32@app.fastmail.com>


[-- Attachment #1.1.1: Type: text/plain, Size: 972 bytes --]

On 29.06.26 10:06, Arnd Bergmann wrote:
> On Mon, Jun 29, 2026, at 09:01, Jürgen Groß wrote:
>> On 29.06.26 08:52, Arnd Bergmann wrote:
>>> On Mon, Jun 29, 2026, at 08:04, Juergen Gross wrote:
>>>
>>> I assume this is fine, but since you don't mention it explicitly here,
>>> please clarify what this means for 32-bit CPUs without the rdmsrq
>>> instruction. Those will continue using the same instructions as before
>>> and just change the calling conventions, right?
>>
>> Yes. I thought this would be clear from the following:
>>
>>     - They are based on primitives using 64-bit sized values anyway.
> 
> Right, that was my reading of it as well, but it's not entirely
> clear when the function name is the same as the mnemonic of an
> instruction that only exists on newer CPUs and the later patch

There is no RDMSRQ instruction on any x86 CPU. Are you mixing this up with
WRMSRNS/RDMSR using an immediate for addressing the MSR?


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply

* Re: [PATCH 0/2] gpio: kunit: add test cases for software node hogs
From: Bartosz Golaszewski @ 2026-06-29  8:27 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, Bartosz Golaszewski
  Cc: linux-gpio, linux-kernel
In-Reply-To: <20260610-gpio-kunit-swnode-hog-v1-0-37b3bf37096c@oss.qualcomm.com>


On Wed, 10 Jun 2026 15:29:16 +0200, Bartosz Golaszewski wrote:
> This series adds test cases for software node based GPIO hogs and also
> contains a small code shrink in existing tests.
> 
> 

Applied, thanks!

[1/2] gpio: kunit: shrink initialization code
      https://git.kernel.org/brgl/c/069547f9d8f817d5d0ba7a8276b0ddefd22222ee
[2/2] gpio: kunit: add test cases for software node hogs
      https://git.kernel.org/brgl/c/a05cfd98c5eca766a4a127bde6278095fc367442

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

^ permalink raw reply

* Re: [PATCH 4/9] MIPS: TXX9: rbtx4927: Use GPIO lookup table for TXx9 LEDs
From: Geert Uytterhoeven @ 2026-06-29  8:38 UTC (permalink / raw)
  To: XIAO WU
  Cc: Thomas Bogendoerfer, Linus Walleij, Bartosz Golaszewski,
	Arnd Bergmann, linux-mips, linux-gpio, linux-kernel
In-Reply-To: <tencent_58921190AD10FFE0501A235142CA54786B09@qq.com>

Hi Xiao,

On Sun, 28 Jun 2026 at 21:23, XIAO WU <xiaowu.417@qq.com> wrote:
> I came across the Sashiko AI review of this series and reproduced the
> use-after-free that it flagged in rbtx4927_gpioled_init() — a KASAN
> slab-use-after-free triggers when platform_device_add() fails on the
> error path.
>
> The Sashiko review is at:
> https://sashiko.dev/#/patchset/cover.1782389357.git.geert@linux-m68k.org
>
> In rbtx4927_gpioled_init() (arch/mips/txx9/rbtx4927/setup.c), this
> patch introduces a GPIO lookup table that references the platform
> device name.  The error path looks like:
>
> ```c
> pdev = platform_device_alloc("leds-gpio", 0);
> if (!pdev)
>      return;
> pdev->dev.platform_data = &pdata;
> if (platform_device_add(pdev))
>      platform_device_put(pdev);       // frees pdev on error!
> rbtx4927_gpioled_table.dev_id = dev_name(&pdev->dev);  // UAF!
> ```
>
> If platform_device_add() fails (e.g., because a device with the same
> name already exists in the platform bus), platform_device_put() drops
> the last reference and frees the struct platform_device.  The code then
> unconditionally calls dev_name(&pdev->dev) on the freed pointer, and
> assigns the dangling pointer into the global GPIO lookup table.
>
> This is a classic use-after-free: the freed memory can be reallocated
> and overwritten, and the GPIO lookup table will later dereference a
> dangling or corrupted dev_id pointer.

Thanks, I will fix that in v2.

>
> For comparison, the iocled equivalent introduced in patch 6 handles
> this correctly with a goto:
>
> ```c
> if (platform_device_add(pdev))
>      goto out_pdev;   // skips dev_name()
> txx9_iocled_table.dev_id = dev_name(&pdev->dev);
> ...
> out_pdev:
>      platform_device_put(pdev);
> ```
>
> === Reproduction ===
>
> Kernel: 7.1.0-next-20260623-gaca8efd71d03-dirty #3 PREEMPT(full)
> Arch:   x86_64 (QEMU Standard PC Q35 + ICH9, 2009)
> Config: CONFIG_KASAN=y
>
> The UAF pattern is reproduced via a kernel module that mirrors the
> same platform_device_add / dev_name error path sequence.  The module
> loads at boot via late_initcall.

[...]

> Build: insert into kernel tree and build with CONFIG_POC_UAF=m
> Run:   insmod poc_uaf.ko (twice, so the second load hits -EEXIST)

Thanks for verifying! But TBH, I think writing a PoC for this is a
bit over the top...

And if the platform_device_add() in rbtx4927_gpioled_init() would
ever fail, that would be due to out-of-memory, and the system would
be dead anyway.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH 00/32] x86/msr: Drop 32-bit MSR interfaces
From: Arnd Bergmann @ 2026-06-29  8:38 UTC (permalink / raw)
  To: Juergen Gross, linux-kernel, linux-pm, linux-edac@vger.kernel.org,
	x86, linux-acpi, kvm, linux-coco, linux-pci, virtualization,
	linux-ide, dri-devel, linux-fbdev, linux-crypto,
	open list:GPIO SUBSYSTEM, linux-hyperv, linux-hwmon,
	linux-perf-users, linux-mtd, platform-driver-x86
  Cc: Rafael J . Wysocki, Daniel Lezcano, Zhang Rui,
	lukasz.luba@arm.com, Jason Baron, Borislav Petkov, Tony Luck,
	Yazen Ghannam, Len Brown, Pavel Machek, Thomas Gleixner,
	Ingo Molnar, Dave Hansen, H. Peter Anvin, Sean Christopherson,
	Paolo Bonzini, Kirill A. Shutemov, Rick Edgecombe, Pu Wen,
	Bjorn Helgaas, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Viresh Kumar,
	Reinette Chatre, Dave Martin, James Morse, Babu Moger,
	Tony W Wang-oc, Damien Le Moal, Niklas Cassel, Dave Airlie,
	Helge Deller, linux-geode, Olivia Mackall, Herbert Xu,
	Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
	Guenter Roeck, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark, Josh Poimboeuf,
	Pawan Gupta, Vitaly Kuznetsov, Andy Lutomirski, Boris Ostrovsky,
	Huang Rui, Mario Limonciello, Perry Yuan, K Prateek Nayak,
	srinivas.pandruvada@linux.intel.com, Artem Bityutskiy,
	Artem Bityutskiy, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Ashok Raj, Hans de Goede, Ilpo Järvinen,
	Rajneesh Bhardwaj, David E Box, xen-devel
In-Reply-To: <9acced19-573d-4923-9329-8be408d2e555@suse.com>

On Mon, Jun 29, 2026, at 10:15, Jürgen Groß wrote:
> On 29.06.26 10:06, Arnd Bergmann wrote:
>> On Mon, Jun 29, 2026, at 09:01, Jürgen Groß wrote:
>>> On 29.06.26 08:52, Arnd Bergmann wrote:
>>>> On Mon, Jun 29, 2026, at 08:04, Juergen Gross wrote:
>>>>
>>>> I assume this is fine, but since you don't mention it explicitly here,
>>>> please clarify what this means for 32-bit CPUs without the rdmsrq
>>>> instruction. Those will continue using the same instructions as before
>>>> and just change the calling conventions, right?
>>>
>>> Yes. I thought this would be clear from the following:
>>>
>>>     - They are based on primitives using 64-bit sized values anyway.
>> 
>> Right, that was my reading of it as well, but it's not entirely
>> clear when the function name is the same as the mnemonic of an
>> instruction that only exists on newer CPUs and the later patch
>
> There is no RDMSRQ instruction on any x86 CPU. Are you mixing this up with
> WRMSRNS/RDMSR using an immediate for addressing the MSR?

Yes, I was just confused about the exact definition here and assumed
the single-register output version was actually called rdmsrq.

     Arnd

^ permalink raw reply

* RE: [PATCH v3 2/5] pinctrl: samsung: fix incorrect pin-bank entries on Exynos2200/7885/8890/8895
From: Alim Akhtar @ 2026-06-29  9:23 UTC (permalink / raw)
  To: 'Peter Griffin', 'Youngmin Nam'
  Cc: krzk, s.nawrocki, linus.walleij, semen.protsenko,
	ivo.ivanov.ivanov1, ryu.real, d7271.choe, shin.son, jaewon02.kim,
	linux-arm-kernel, linux-samsung-soc, linux-gpio, linux-kernel
In-Reply-To: <CADrjBPqYT9h_UJKSxBJ_KMQ4yQv4yyTuHaPYjC+K1-6TZj+PXg@mail.gmail.com>

Hi Krzysztof, Peter

> -----Original Message-----
> From: Peter Griffin <peter.griffin@linaro.org>
> Sent: Saturday, March 7, 2026 2:47 AM
> To: Youngmin Nam <youngmin.nam@samsung.com>
> Cc: krzk@kernel.org; s.nawrocki@samsung.com; alim.akhtar@samsung.com;
> linus.walleij@linaro.org; semen.protsenko@linaro.org;
> ivo.ivanov.ivanov1@gmail.com; ryu.real@samsung.com;
> d7271.choe@samsung.com; shin.son@samsung.com;
> jaewon02.kim@samsung.com; linux-arm-kernel@lists.infradead.org; linux-
> samsung-soc@vger.kernel.org; linux-gpio@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Subject: Re: [PATCH v3 2/5] pinctrl: samsung: fix incorrect pin-bank entries on
> Exynos2200/7885/8890/8895
> 
> Hi Youngmin,
> 
> On Tue, 2 Dec 2025 at 09:30, Youngmin Nam
> <youngmin.nam@samsung.com> wrote:
> >
> > This patch corrects wrong pin bank table definitions for 4 SoCs based
> > on their TRMs.
> >
> > Exynos2200
> > - gpq0/1/2 were using EXYNOS_PIN_BANK_EINTN(), which implies a
> >   'bank_type_off' layout (.fld_width = {4,1,2,2,2,2}).
> > - Per the SoC TRM these banks must use the 'alive' layout
> >   (.fld_width = {4,1,4,4}).
> > - Switch them to
> EXYNOS9_PIN_BANK_EINTN(exynos9_bank_type_alive, ...).
> >
> > Exynos7885
> > - etc0, etc1: update bank type to match the SoC TRM.
> > - gpq0 is a non-wakeup interrupt bank; change EINTW -> EINTN accordingly.
> >
> > Exynos8890
> > - Per the SoC TRM, rename bank ect0 to gpb3 and mark it as
> >   a non-external interrupt bank.
> > - gpi1, gpi2: update bank type to match the SoC TRM.
> >   exynos8895_bank_type_off (.fld_width = {4,1,2,3,2,2}) ->
> >   exynos5433_bank_type_off (.fld_width = {4,1,2,4,2,2})
> > - Per the SoC TRM, mark etc1 as a non-external interrupt bank.
> > - apply lower case style for hex numbers.
> >
> > Exynos8895
> > - gpa4 is a non-wakeup interrupt bank per the SoC TRM.
> >   change EINTW -> EINTN. (The bank_type itself was correct and is kept
> >   unchanged.)
> > - apply lower case style for hex numbers.
> >
> > This aligns the pin-bank tables with the documented bitfield layouts
> > and wakeup domains. No DT/ABI change.
> >
> > Signed-off-by: Youngmin Nam <youngmin.nam@samsung.com>
> > Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org>
> > Reviewed-by: Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
> > Tested-by: Sam Protsenko <semen.protsenko@linaro.org>
> > ---
> 
> This patch contains some worthwhile fixes for multiple Exynos SoCs. Do you
> plan to re-send it? I think it would be good to get this merged (even if there
> isn't broad agreement around renaming the pinctrl macros to EXYNOS9_)
> 
Can we relook into this series? 
AFA EXYNOS9_ macro is concern, Exynos990, Exynos9810 etc already support available upstream.
Of course it does not justify why Exynos9, but we can consider all SoCs which has come after 2020 have this newer architecture. 
Or Just have SAMSUNG_ prefix for all such newer SoC.

A unified Macro help in adding new SoC support without much confusion(like I am trying with Exynos8855)

@Youngmin, will you have some time to re-spin these series?

> Thanks,
> 
> Peter


^ permalink raw reply

* Re: [PATCH v3 0/8] x1e80100: Enable PDC wake GPIOs and deepest idle state
From: Konrad Dybcio @ 2026-06-29  9:54 UTC (permalink / raw)
  To: Val Packett, Maulik Shah, Bjorn Andersson, Konrad Dybcio,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner,
	Linus Walleij
  Cc: linux-arm-msm, linux-kernel, devicetree, linux-gpio, Sneh Mankad,
	Stephan Gerhold
In-Reply-To: <439b81a5-b13c-4f1a-9c55-a8b0b56a4de6@packett.cool>

On 6/28/26 8:39 PM, Val Packett wrote:
> 
> On 6/16/26 6:25 AM, Maulik Shah wrote:
>> [..]
>> ---
>> Maulik Shah (7):
>>        irqchip/qcom-pdc: restructure version support
>>        irqchip/qcom-pdc: Move all statics to struct pdc_desc
>>        irqchip/qcom-pdc: Remove pdc_enable_intr() wrapper
>>        irqchip/qcom-pdc: Differentiate between direct SPI and GPIO as SPI
>>        irqchip/qcom-pdc: Configure PDC to pass through mode
>>        Revert "pinctrl: qcom: x1e80100: Bypass PDC wakeup parent for now"
>>        arm64: dts: qcom: x1e80100: Add deepest idle state
>>
>> Stephan Gerhold (1):
>>        pinctrl: qcom: Acknowledge IRQs for PDC interrupt controller
>>
>> [..]
> 
> Something about this series breaks the touchscreen interrupt (<&tlmm 81 IRQ_TYPE_LEVEL_LOW>) on sm7325-motorola-dubai :(
> 
> With this series, that interrupt only happens once (stuck at 1 in /proc/interrupts) so events are not reported. Something something level triggered..??

Could you bisect which of the (hopefully first 6) patches cause it?

Konrad

^ permalink raw reply

* Re: [PATCH v3 2/8] irqchip/qcom-pdc: Move all statics to struct pdc_desc
From: Konrad Dybcio @ 2026-06-29  9:56 UTC (permalink / raw)
  To: Maulik Shah (mkshah), Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Linus Walleij
  Cc: linux-arm-msm, linux-kernel, devicetree, linux-gpio, Sneh Mankad
In-Reply-To: <91fa4b98-d99e-401c-bb1f-f235034f3aab@oss.qualcomm.com>

On 6/25/26 11:19 AM, Maulik Shah (mkshah) wrote:
> 
> 
> On 6/17/2026 6:56 PM, Konrad Dybcio wrote:
>> On 6/16/26 11:25 AM, Maulik Shah wrote:
>>> There are multiple statics used. Move all to struct pdc_desc to better
>>> align with versioning support. Document them.
>>>
>>> No functional impact.
>>>
>>> Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
>>> ---
>>
>> [...]
>>
>>>  static void pdc_enable_intr(struct irq_data *d, bool on)
>>>  {
>>> -	unsigned long flags;
>>> +	guard(raw_spinlock)(&pdc->lock);
>>
>> tglx suggested to use guard(irq) around "the other callsite"..
>> which I'm not sure where it'd be - maybe around __pdc_enable_intr()
>> in pdc_setup_pin_mapping()?
>>
>> Otherwise this patch looks good to me
>>
>> Konrad
> 
> All callers will be from irqchip except pdc_setup_pin_mapping() which was
> invoking lock-less because at that time irqchip is not setup and as such
> can stay lock less.
> 
> Once the patch-3 of this series is applied pdc_setup_pin_mapping() too
> will use the lock as it makes direct use of pdc->enable_intr() where the new lock
> is kept (only for v2.7 version specific enable function).

Ack, thanks

Konrad

^ permalink raw reply

* Re: [PATCH] gpio: dwapb: Defer clock gating until noirq
From: kernel test robot @ 2026-06-29 10:04 UTC (permalink / raw)
  To: Jia Wang via B4 Relay, Hoan Tran, Linus Walleij,
	Bartosz Golaszewski
  Cc: oe-kbuild-all, linux-gpio, linux-kernel, Jia Wang
In-Reply-To: <20260629-gpio-dwapb-wakeup-v1-1-3394f02317da@ultrarisc.com>

Hi Jia,

kernel test robot noticed the following build errors:

[auto build test ERROR on dc59e4fea9d83f03bad6bddf3fa2e52491777482]

url:    https://github.com/intel-lab-lkp/linux/commits/Jia-Wang-via-B4-Relay/gpio-dwapb-Defer-clock-gating-until-noirq/20260629-135404
base:   dc59e4fea9d83f03bad6bddf3fa2e52491777482
patch link:    https://lore.kernel.org/r/20260629-gpio-dwapb-wakeup-v1-1-3394f02317da%40ultrarisc.com
patch subject: [PATCH] gpio: dwapb: Defer clock gating until noirq
config: sparc64-randconfig-001-20260629 (https://download.01.org/0day-ci/archive/20260629/202606291736.mAgOeA65-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260629/202606291736.mAgOeA65-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606291736.mAgOeA65-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/gpio/gpio-dwapb.c: In function 'dwapb_irq_set_wake':
>> drivers/gpio/gpio-dwapb.c:377:7: error: 'struct irq_data' has no member named 'parent_data'
     if (d->parent_data && !!ctx->wake_en != !!wake_en) {
          ^~
>> drivers/gpio/gpio-dwapb.c:378:9: error: implicit declaration of function 'irq_chip_set_wake_parent'; did you mean 'irq_set_parent'? [-Werror=implicit-function-declaration]
      err = irq_chip_set_wake_parent(d, enable);
            ^~~~~~~~~~~~~~~~~~~~~~~~
            irq_set_parent
   cc1: some warnings being treated as errors


vim +377 drivers/gpio/gpio-dwapb.c

   362	
   363	static int dwapb_irq_set_wake(struct irq_data *d, unsigned int enable)
   364	{
   365		struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
   366		struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
   367		struct dwapb_context *ctx = gpio->ports[0].ctx;
   368		irq_hw_number_t bit = irqd_to_hwirq(d);
   369		u32 wake_en = ctx->wake_en;
   370		int err;
   371	
   372		if (enable)
   373			wake_en |= BIT(bit);
   374		else
   375			wake_en &= ~BIT(bit);
   376	
 > 377		if (d->parent_data && !!ctx->wake_en != !!wake_en) {
 > 378			err = irq_chip_set_wake_parent(d, enable);
   379			if (err)
   380				return err;
   381		}
   382	
   383		ctx->wake_en = wake_en;
   384	
   385		return 0;
   386	}
   387	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH 24/32] drivers/gpio: Stop using 32-bit MSR interfaces
From: Bartosz Golaszewski @ 2026-06-29 10:33 UTC (permalink / raw)
  To: Juergen Gross
  Cc: linux-kernel, linux-gpio, Linus Walleij, Bartosz Golaszewski
In-Reply-To: <20260629060526.3638272-25-jgross@suse.com>

On Mon, 29 Jun 2026 08:05:15 +0200, Juergen Gross <jgross@suse.com> said:
> The 32-bit MSR interfaces rdmsr() and wrmsr() are planned to be
> removed. Use the related 64-bit variants instead.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>
> ---

Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

^ permalink raw reply

* Re: [PATCH] gpio: amd-fch: switch to guard() notation
From: Bartosz Golaszewski @ 2026-06-29 10:33 UTC (permalink / raw)
  To: Bartosz Golaszewski, Dmitry Torokhov
  Cc: Bartosz Golaszewski, Linus Walleij, Tj,
	Enrico Weigelt, metux IT consult, linux-gpio, linux-kernel
In-Reply-To: <aZarCgDvMUta4Viq@google.com>


On Wed, 18 Feb 2026 22:46:01 -0800, Dmitry Torokhov wrote:
> guard() is more concise and ensures that lock is released at the end of
> the scope.
> 
> 

Applied, thanks!

[1/1] gpio: amd-fch: switch to guard() notation
      https://git.kernel.org/brgl/c/45bd4e25f81f3afb550f04376a54f4c5e1d5ab11

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

^ permalink raw reply

* Re: [PATCH] gpio: amd-fch: switch to guard() notation
From: Bartosz Golaszewski @ 2026-06-29 10:34 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Tj, Enrico Weigelt, metux IT consult, linux-gpio, linux-kernel,
	Linus Walleij, Bartosz Golaszewski
In-Reply-To: <akCz48E0i6jqzmiC@google.com>

On Sun, 28 Jun 2026 07:42:50 +0200, Dmitry Torokhov
<dmitry.torokhov@gmail.com> said:
> On Thu, Feb 19, 2026 at 06:26:25PM +0100, Linus Walleij wrote:
>> On Thu, Feb 19, 2026 at 7:46 AM Dmitry Torokhov
>> <dmitry.torokhov@gmail.com> wrote:
>>
>> > guard() is more concise and ensures that lock is released at the end of
>> > the scope.
>> >
>> > Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
>>
>> That looks right!
>> Reviewed-by: Linus Walleij <linusw@kernel.org>
>
> Bartosz, do you need me to resubmit?
>
> Thanks.
>
> --
> Dmitry
>

No, it applied fine. Sorry, it fell through the cracks.

Bart

^ permalink raw reply

* [PATCH 0/5] software node: provide support for fw_devlink
From: Bartosz Golaszewski @ 2026-06-29 10:52 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Andy Shevchenko,
	Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Linus Walleij, Dmitry Torokhov
  Cc: linux-kernel, linux-kselftest, kunit-dev, linux-acpi, driver-core,
	linux-gpio, Bartosz Golaszewski

Currently only devicetree systems have their devices' probe ordered
against their suppliers automatically by fw_devlink. Software nodes have
lately been used extensively treewide to describe references to resource
suppliers: most notably, the GPIO subsystem uses it in many places. Now
that the conversion of "dangling" GPIO chip software nodes to using real
links is almost done, it makes sense to ensure no needless probe
deferrals by implementing the add_links() callback from the fwnode
interface.

This series extends software node support to use fw_devlink and adds test
coverage for the new behaviour.

Patch 1 adds new kunit helpers that will be used later on for test
cases.

Patch 2 implements software_node_add_links() modelled on
of_fwnode_add_links(): for every reference property it resolves the
supplier and links to it. There's no allowlist like in DT - a software
node only carries a reference when its author explicitly wants one, so
every reference is an intentional supplier dependency. Graph
"remote-endpoint" references, unregistered supplier software nodes and
self-references are skipped. It also mirrors the device pointer onto a
secondary software node so fw_devlink can find the supplier device, and
purges the fwnode links on release.

Patches 3 and 5 add the tests: a kunit suite for the add_links() op
itself and GPIO tests for a real-life use-case: a GPIO consumer
referencing its provider via a software node.

Patch 4 proposes to add myself as a reviewer of software nodes.

Caveats: a supplier software node must be registered before the consumer
device is added, If the swnode is registered after the consumer was added,
add_links() has already run and set FWNODE_FLAG_LINKS_ADDED, so the late
supplier is missed. Graph/remote- endpoint ordering is left out for now as
well as there are no known users.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
Bartosz Golaszewski (5):
      kunit: provide a set of fwnode-oriented helpers
      software node: add fw_devlink support
      software node: add kunit tests for fw_devlink support
      MAINTAINERS: add myself as reviewer of software node support
      gpio: kunit: add test cases verifying swnode devlink support

 MAINTAINERS                             |   2 +
 drivers/base/swnode.c                   |  79 ++++++++
 drivers/base/test/Kconfig               |   5 +
 drivers/base/test/Makefile              |   3 +
 drivers/base/test/swnode-devlink-test.c | 336 ++++++++++++++++++++++++++++++++
 drivers/gpio/gpiolib-kunit.c            | 272 +++++++++++++++++++++++++-
 include/kunit/fwnode.h                  |  26 +++
 lib/kunit/Makefile                      |   1 +
 lib/kunit/fwnode.c                      | 116 +++++++++++
 9 files changed, 833 insertions(+), 7 deletions(-)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260609-swnode-fw-devlink-cdc8dc4e5cb4

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>


^ permalink raw reply

* [PATCH 1/5] kunit: provide a set of fwnode-oriented helpers
From: Bartosz Golaszewski @ 2026-06-29 10:52 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Andy Shevchenko,
	Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Linus Walleij, Dmitry Torokhov
  Cc: linux-kernel, linux-kselftest, kunit-dev, linux-acpi, driver-core,
	linux-gpio, Bartosz Golaszewski
In-Reply-To: <20260629-swnode-fw-devlink-v1-0-b90058b41839@oss.qualcomm.com>

Provide three new kunit-managed helpers for test cases that need to
register/create dynamic software nodes.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 include/kunit/fwnode.h |  26 +++++++++++
 lib/kunit/Makefile     |   1 +
 lib/kunit/fwnode.c     | 116 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+)

diff --git a/include/kunit/fwnode.h b/include/kunit/fwnode.h
new file mode 100644
index 0000000000000000000000000000000000000000..239bc71eb5072ccead0beb51fc0882bab69c6877
--- /dev/null
+++ b/include/kunit/fwnode.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * KUnit resource management helpers for firmware nodes.
+ *
+ * Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries
+ */
+
+#ifndef _KUNIT_FWNODE_H
+#define _KUNIT_FWNODE_H
+
+struct kunit;
+struct fwnode_handle;
+struct property_entry;
+struct software_node;
+
+struct fwnode_handle *
+kunit_fwnode_create_software_node(struct kunit *test,
+				  const struct property_entry *properties,
+				  const struct fwnode_handle *parent);
+struct fwnode_handle *
+kunit_software_node_register(struct kunit *test,
+			     const struct software_node *node);
+int kunit_software_node_register_node_group(struct kunit *test,
+					    const struct software_node *const *nodes);
+
+#endif /* _KUNIT_FWNODE_H */
diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
index 2e8a6b71a2ab07a738964a7ef0f442fd53e085b1..204e02b10eba1030c6d511991fe2f6271de64603 100644
--- a/lib/kunit/Makefile
+++ b/lib/kunit/Makefile
@@ -11,6 +11,7 @@ kunit-objs +=				test.o \
 					attributes.o \
 					device.o \
 					platform.o \
+					fwnode.o \
 					bug.o
 
 ifeq ($(CONFIG_KUNIT_DEBUGFS),y)
diff --git a/lib/kunit/fwnode.c b/lib/kunit/fwnode.c
new file mode 100644
index 0000000000000000000000000000000000000000..332490f07fae78e0fbf2930f9c80da0cc7dce028
--- /dev/null
+++ b/lib/kunit/fwnode.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries
+ */
+
+#include <kunit/fwnode.h>
+#include <kunit/test.h>
+
+#include <linux/fwnode.h>
+#include <linux/property.h>
+
+KUNIT_DEFINE_ACTION_WRAPPER(fwnode_remove_software_node_wrapper,
+			    fwnode_remove_software_node,
+			    struct fwnode_handle *);
+
+/**
+ * kunit_fwnode_create_software_node() - Create a kunit-managed software node
+ * @test: Test context
+ * @properties: Properties to use to create the new software node
+ * @parent: Parent of this software node
+ *
+ * Create a test-managed software node and return its firmware node handle.
+ * The software node is removed after the test case completes.
+ *
+ * Returns:
+ * Firmware node handle of the newly created software node or IS_ERR() on
+ * failure.
+ */
+struct fwnode_handle *
+kunit_fwnode_create_software_node(struct kunit *test,
+				  const struct property_entry *properties,
+				  const struct fwnode_handle *parent)
+{
+	struct fwnode_handle *fwnode;
+	int ret;
+
+	fwnode = fwnode_create_software_node(properties, parent);
+	if (IS_ERR(fwnode))
+		return fwnode;
+
+	ret = kunit_add_action_or_reset(test, fwnode_remove_software_node_wrapper,
+					fwnode);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return fwnode;
+}
+EXPORT_SYMBOL_GPL(kunit_fwnode_create_software_node);
+
+KUNIT_DEFINE_ACTION_WRAPPER(software_node_unregister_wrapper,
+			    software_node_unregister,
+			    const struct software_node *);
+
+/**
+ * kunit_software_node_register() - Register a kunit-managed software node
+ * @test: Test context
+ * @swnode: Software node to register
+ *
+ * Register a test-managed software node and return its firmware node handle.
+ * The software node is unregistered after the test case completes.
+ *
+ * Returns:
+ * Firmware node handle of the registered software node or IS_ERR() on failure.
+ */
+struct fwnode_handle *
+kunit_software_node_register(struct kunit *test,
+			     const struct software_node *swnode)
+{
+	struct fwnode_handle *fwnode;
+	int ret;
+
+	ret = software_node_register(swnode);
+	if (ret)
+		return ERR_PTR(ret);
+
+	fwnode = software_node_fwnode(swnode);
+	if (WARN_ON(!fwnode))
+		return ERR_PTR(-ENOENT);
+
+	ret = kunit_add_action_or_reset(test, software_node_unregister_wrapper,
+					(void *)swnode);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return fwnode;
+}
+EXPORT_SYMBOL_GPL(kunit_software_node_register);
+
+KUNIT_DEFINE_ACTION_WRAPPER(software_node_unregister_node_group_wrapper,
+			    software_node_unregister_node_group,
+			    const struct software_node *const *);
+
+/**
+ * kunit_software_node_register_node_group() - Register a kunit-managed software node group
+ * @test: Test context
+ * @nodes: Software node group to register
+ *
+ * Register a test-managed software node group. The nodes are unregistered
+ * after the test case completes.
+ *
+ * Returns:
+ * 0 on success, negative error number on failure.
+ */
+int kunit_software_node_register_node_group(struct kunit *test,
+					    const struct software_node *const *nodes)
+{
+	int ret;
+
+	ret = software_node_register_node_group(nodes);
+	if (ret)
+		return ret;
+
+	return kunit_add_action_or_reset(test, software_node_unregister_node_group_wrapper,
+					 (void *)nodes);
+}
+EXPORT_SYMBOL_GPL(kunit_software_node_register_node_group);

-- 
2.47.3


^ permalink raw reply related

* [PATCH 2/5] software node: add fw_devlink support
From: Bartosz Golaszewski @ 2026-06-29 10:52 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Andy Shevchenko,
	Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Linus Walleij, Dmitry Torokhov
  Cc: linux-kernel, linux-kselftest, kunit-dev, linux-acpi, driver-core,
	linux-gpio, Bartosz Golaszewski
In-Reply-To: <20260629-swnode-fw-devlink-v1-0-b90058b41839@oss.qualcomm.com>

Software nodes can be used to describe supplier-consumer relationships
between devices they represent using reference property entries. Unlike
for OF-nodes, driver core cannot yet use these references to create a
probe order that avoids needless probe deferrals on missing providers.

Implement software_node_add_links() modelled on of_fwnode_add_links().
For every DEV_PROP_REF property we resolve each referenced supplier and
create an fwnode link from the node to it. The driver core later promotes
these to device links and defers the consumer until the suppliers are
ready.

There's no allowlist like the one DT needs - devicetree phandles appear
in plenty of non-supplier contexts, but a software node only carries a
reference property when its author explicitly points at another node, so
we treat every reference as an intentional supplier dependency and link
all of them. Graph "remote-endpoint" references are skipped for now: they
go 2-ways between endpoint nodes and would create graph cycles without
the port-parent lifting DT does via get_con_dev(). References to
suppliers that aren't registered yet and self-references are ignored.

fw_devlink resolves the supplier device through fwnode->dev but the core
only records the owning device on the primary fwnode. When the software
node is a device's secondary fwnode, mirror the device pointer onto it in
software_node_notify() so the consumer can actually find the supplier
instead of deferring forever.

While at it: purge the fwnode links in software_node_release() now that
software nodes can own them.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 drivers/base/swnode.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index 869228a65cb365567ddac7db6ad7b8743e0dbca9..48eb67826f9e1917acc7a6a513c1536a7ece0961 100644
--- a/drivers/base/swnode.c
+++ b/drivers/base/swnode.c
@@ -699,6 +699,62 @@ software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode,
 	return 0;
 }
 
+static int software_node_add_links(struct fwnode_handle *fwnode)
+{
+	const struct software_node_ref_args *ref, *ref_array;
+	struct swnode *swnode = to_swnode(fwnode);
+	const struct property_entry *prop;
+	struct fwnode_handle *refnode;
+	unsigned int count, i;
+
+	if (!swnode || !swnode->node->properties)
+		return 0;
+
+	/*
+	 * Unlike Device Tree, where phandles appear in many non-supplier
+	 * contexts and a curated allowlist is required, a software node only
+	 * carries a DEV_PROP_REF property when the author explicitly describes
+	 * a reference to another node. Every such reference is therefore an
+	 * intentional supplier dependency, so we create fwnode links for all
+	 * of them.
+	 */
+	for (prop = swnode->node->properties; prop->name; prop++) {
+		if (prop->type != DEV_PROP_REF || prop->is_inline)
+			continue;
+
+		/*
+		 * TODO: Graph "remote-endpoint" references go both ways
+		 * between endpoint child nodes and would create endpoint
+		 * cycles. Let's leave it out for now until we have potential
+		 * users.
+		 */
+		if (!strcmp(prop->name, "remote-endpoint"))
+			continue;
+
+		ref_array = prop->pointer;
+		count = prop->length / sizeof(*ref_array);
+
+		for (i = 0; i < count; i++) {
+			ref = &ref_array[i];
+
+			if (ref->swnode)
+				refnode = software_node_fwnode(ref->swnode);
+			else if (ref->fwnode)
+				refnode = ref->fwnode;
+			else
+				continue;
+
+			/* Supplier not registered yet, or self-reference. */
+			if (!refnode || refnode == &swnode->fwnode)
+				continue;
+
+			fwnode_link_add(&swnode->fwnode, refnode, 0);
+		}
+	}
+
+	return 0;
+}
+
 static const struct fwnode_operations software_node_ops = {
 	.get = software_node_get,
 	.put = software_node_put,
@@ -716,6 +772,7 @@ static const struct fwnode_operations software_node_ops = {
 	.graph_get_remote_endpoint = software_node_graph_get_remote_endpoint,
 	.graph_get_port_parent = software_node_graph_get_port_parent,
 	.graph_parse_endpoint = software_node_graph_parse_endpoint,
+	.add_links = software_node_add_links,
 };
 
 /* -------------------------------------------------------------------------- */
@@ -787,6 +844,8 @@ static void software_node_release(struct kobject *kobj)
 {
 	struct swnode *swnode = kobj_to_swnode(kobj);
 
+	fwnode_links_purge(&swnode->fwnode);
+
 	if (swnode->parent) {
 		ida_free(&swnode->parent->child_ids, swnode->id);
 		list_del(&swnode->entry);
@@ -1105,6 +1164,17 @@ void software_node_notify(struct device *dev)
 	if (!swnode)
 		return;
 
+	/*
+	 * When the software node is the device's secondary firmware node, the
+	 * core only records the owning device on the primary fwnode (see
+	 * device_add()). fw_devlink resolves a supplier device through
+	 * fwnode->dev, so without this a consumer referencing the software
+	 * node could never find the supplier device and would defer forever.
+	 * Make fwnode.dev point to its owner in that case.
+	 */
+	if (dev_fwnode(dev) != &swnode->fwnode && !swnode->fwnode.dev)
+		swnode->fwnode.dev = dev;
+
 	swnode_get(swnode);
 	ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node");
 	if (ret)
@@ -1127,6 +1197,15 @@ void software_node_notify_remove(struct device *dev)
 
 	sysfs_remove_link(&swnode->kobj, dev_name(dev));
 	sysfs_remove_link(&dev->kobj, "software_node");
+
+	/*
+	 * Drop the device pointer mirrored onto a secondary software node in
+	 * software_node_notify(). For a primary software node the core owns
+	 * fwnode->dev and clears it in device_del().
+	 */
+	if (dev_fwnode(dev) != &swnode->fwnode && swnode->fwnode.dev == dev)
+		swnode->fwnode.dev = NULL;
+
 	swnode_put(swnode);
 
 	if (swnode->managed) {

-- 
2.47.3


^ permalink raw reply related

* [PATCH 3/5] software node: add kunit tests for fw_devlink support
From: Bartosz Golaszewski @ 2026-06-29 10:52 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Andy Shevchenko,
	Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Linus Walleij, Dmitry Torokhov
  Cc: linux-kernel, linux-kselftest, kunit-dev, linux-acpi, driver-core,
	linux-gpio, Bartosz Golaszewski
In-Reply-To: <20260629-swnode-fw-devlink-v1-0-b90058b41839@oss.qualcomm.com>

Add a kunit test suite for fw_devlink support for software nodes.

Most cases call add_links() directly and inspect the resulting fwnode
supplier/consumer lists: a single reference, multiple references, a
reference to an unregistered node, a "remote-endpoint" reference and a
reference array. The last case is end-to-end - it registers real consumer
and supplier platform devices together with their drivers, adds the
consumer first and checks that fw_devlink defers its probe until the
supplier has been bound.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 drivers/base/test/Kconfig               |   5 +
 drivers/base/test/Makefile              |   3 +
 drivers/base/test/swnode-devlink-test.c | 336 ++++++++++++++++++++++++++++++++
 3 files changed, 344 insertions(+)

diff --git a/drivers/base/test/Kconfig b/drivers/base/test/Kconfig
index 2756870615ccab67ec26d8671c1e4dba69342134..1ecf0791241a1b2eee7e1e787772217724abacb9 100644
--- a/drivers/base/test/Kconfig
+++ b/drivers/base/test/Kconfig
@@ -18,3 +18,8 @@ config DRIVER_PE_KUNIT_TEST
 	tristate "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS
 	depends on KUNIT
 	default KUNIT_ALL_TESTS
+
+config DRIVER_SWNODE_KUNIT_TEST
+	tristate "KUnit Tests for software node fw_devlink links" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
diff --git a/drivers/base/test/Makefile b/drivers/base/test/Makefile
index e321dfc7e92266d2073d442f652cadb6e911dba5..1b78a705983c145e29bd166606f2c78682342735 100644
--- a/drivers/base/test/Makefile
+++ b/drivers/base/test/Makefile
@@ -6,3 +6,6 @@ obj-$(CONFIG_DM_KUNIT_TEST)	+= platform-device-test.o
 
 obj-$(CONFIG_DRIVER_PE_KUNIT_TEST) += property-entry-test.o
 CFLAGS_property-entry-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
+
+obj-$(CONFIG_DRIVER_SWNODE_KUNIT_TEST) += swnode-devlink-test.o
+CFLAGS_swnode-devlink-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
diff --git a/drivers/base/test/swnode-devlink-test.c b/drivers/base/test/swnode-devlink-test.c
new file mode 100644
index 0000000000000000000000000000000000000000..42816f8f7c1ee4572b6c87bc91b434c0e0086aa8
--- /dev/null
+++ b/drivers/base/test/swnode-devlink-test.c
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries
+ */
+
+#include <linux/device.h>
+#include <linux/fwnode.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+
+#include <kunit/fwnode.h>
+#include <kunit/platform_device.h>
+#include <kunit/test.h>
+
+static int swnode_count_suppliers(struct fwnode_handle *fwnode)
+{
+	struct fwnode_link *link;
+	int ret = 0;
+
+	/*
+	 * The suppliers and consumers lists should typically only be accessed
+	 * with the fwnode_link_lock taken but it's private to the driver core.
+	 *
+	 * These are tests and at this point nobody should be modifying them so
+	 * let's just access the list.
+	 */
+	list_for_each_entry(link, &fwnode->suppliers, c_hook)
+		ret++;
+
+	return ret;
+}
+
+/* True if a supplier link con->sup exists, checked from both list ends. */
+static bool swnode_has_link(struct fwnode_handle *consumer,
+			    struct fwnode_handle *supplier)
+{
+	bool from_con = false, from_sup = false;
+	struct fwnode_link *link;
+
+	list_for_each_entry(link, &consumer->suppliers, c_hook) {
+		if (link->supplier == supplier && link->consumer == consumer)
+			from_con = true;
+	}
+
+	list_for_each_entry(link, &supplier->consumers, s_hook) {
+		if (link->supplier == supplier && link->consumer == consumer)
+			from_sup = true;
+	}
+
+	return from_con && from_sup;
+}
+
+/* A single reference creates exactly one supplier link, on both list ends. */
+static void swnode_devlink_test_single_ref(struct kunit *test)
+{
+	static const struct software_node supp_swnode = {
+		.name = "swnode-devlink-test-supplier"
+	};
+
+	struct fwnode_handle *cons_fwnode, *supp_fwnode;
+	int ret;
+
+	const struct property_entry props[] = {
+		PROPERTY_ENTRY_REF("supplier", &supp_swnode),
+		{ }
+	};
+
+	supp_fwnode = kunit_software_node_register(test, &supp_swnode);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, supp_fwnode);
+
+	cons_fwnode = kunit_fwnode_create_software_node(test, props, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons_fwnode);
+
+	ret = fwnode_call_int_op(cons_fwnode, add_links);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	KUNIT_EXPECT_EQ(test, swnode_count_suppliers(cons_fwnode), 1);
+	KUNIT_EXPECT_TRUE(test, swnode_has_link(cons_fwnode, supp_fwnode));
+}
+
+/* Multiple distinct references create multiple supplier links. */
+static void swnode_devlink_test_multiple_refs(struct kunit *test)
+{
+	static const struct software_node supp1_swnode = {
+		.name = "swnode-devlink-test-supplier-1"
+	};
+	static const struct software_node supp2_swnode = {
+		.name = "swnode-devlink-test-supplier-2"
+	};
+	static const struct software_node *supp_nodes[] = {
+		&supp1_swnode, &supp2_swnode, NULL
+	};
+
+	const struct property_entry props[] = {
+		PROPERTY_ENTRY_REF("foo", &supp1_swnode),
+		PROPERTY_ENTRY_REF("bar", &supp2_swnode),
+		{ }
+	};
+
+	struct fwnode_handle *fwnode;
+	int ret;
+
+	ret = kunit_software_node_register_node_group(test, supp_nodes);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	fwnode = kunit_fwnode_create_software_node(test, props, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
+
+	ret = fwnode_call_int_op(fwnode, add_links);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	KUNIT_EXPECT_EQ(test, swnode_count_suppliers(fwnode), 2);
+	KUNIT_EXPECT_TRUE(test, swnode_has_link(fwnode, software_node_fwnode(&supp1_swnode)));
+	KUNIT_EXPECT_TRUE(test, swnode_has_link(fwnode, software_node_fwnode(&supp2_swnode)));
+}
+
+/* A reference to an unregistered node creates no link (graceful skip). */
+static void swnode_devlink_test_unregistered_ref(struct kunit *test)
+{
+	static const struct software_node supp_swnode = {
+		.name = "swnode-devlink-test-supplier"
+	};
+
+	const struct property_entry props[] = {
+		PROPERTY_ENTRY_REF("supplier", &supp_swnode),
+		{ }
+	};
+
+	struct fwnode_handle *fwnode;
+	int ret;
+
+	fwnode = kunit_fwnode_create_software_node(test, props, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
+
+	ret = fwnode_call_int_op(fwnode, add_links);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, swnode_count_suppliers(fwnode), 0);
+}
+
+/* Graph "remote-endpoint" references are excluded. */
+static void swnode_devlink_test_remote_endpoint_excluded(struct kunit *test)
+{
+	static const struct software_node ep_swnode = {
+		.name = "swnode-devlink-test-end-point"
+	};
+
+	const struct property_entry props[] = {
+		PROPERTY_ENTRY_REF("remote-endpoint", &ep_swnode),
+		{ }
+	};
+
+	struct fwnode_handle *cons_fwnode, *supp_fwnode;
+	int ret;
+
+	supp_fwnode = kunit_software_node_register(test, &ep_swnode);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, supp_fwnode);
+
+	cons_fwnode = kunit_fwnode_create_software_node(test, props, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons_fwnode);
+
+	ret = fwnode_call_int_op(cons_fwnode, add_links);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, swnode_count_suppliers(cons_fwnode), 0);
+}
+
+/* A reference array creates one link per registered element. */
+static void swnode_devlink_test_ref_array(struct kunit *test)
+{
+	static const struct software_node supp1_swnode = {
+		.name = "swnode-devlink-test-supplier-1"
+	};
+	static const struct software_node supp2_swnode = {
+		.name = "swnode-devlink-test-supplier-2"
+	};
+	static const struct software_node *supp_nodes[] = {
+		&supp1_swnode, &supp2_swnode, NULL
+	};
+	static const struct software_node_ref_args refs[] = {
+		SOFTWARE_NODE_REFERENCE(&supp1_swnode),
+		SOFTWARE_NODE_REFERENCE(&supp2_swnode, 4, 2),
+	};
+
+	const struct property_entry props[] = {
+		PROPERTY_ENTRY_REF_ARRAY("suppliers", refs),
+		{ }
+	};
+
+	struct fwnode_handle *fwnode;
+	int ret;
+
+	ret = kunit_software_node_register_node_group(test, supp_nodes);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	fwnode = kunit_fwnode_create_software_node(test, props, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
+
+	ret = fwnode_call_int_op(fwnode, add_links);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	KUNIT_EXPECT_EQ(test, swnode_count_suppliers(fwnode), 2);
+	KUNIT_EXPECT_TRUE(test, swnode_has_link(fwnode, software_node_fwnode(&supp1_swnode)));
+	KUNIT_EXPECT_TRUE(test, swnode_has_link(fwnode, software_node_fwnode(&supp2_swnode)));
+}
+
+/*
+ * End-to-end test: fw_devlink must defer a consumer's probe until its
+ * supplier has probed.
+ *
+ * The reference created by software_node_add_links() is only useful if the
+ * driver core promotes it to a real device_link and uses it to order probing.
+ * This test drives actual probing through the platform bus and asserts the
+ * supplier binds before the consumer.
+ */
+
+#define SWNODE_DEVLINK_TEST_SUPPLIER	"swnode-link-supplier"
+#define SWNODE_DEVLINK_TEST_CONSUMER	"swnode-link-consumer"
+#define SWNODE_DEVLINK_TEST_TIMEOUT_MS	2000
+
+struct swnode_test_probe_order {
+	/* Names in the order their drivers' .probe ran. */
+	const char *probed[2];
+	unsigned int count;
+	wait_queue_head_t wq;
+};
+
+static int swnode_test_record_probe(struct platform_device *pdev)
+{
+	struct swnode_test_probe_order *order = platform_get_drvdata(pdev);
+
+	if (order && order->count < ARRAY_SIZE(order->probed)) {
+		order->probed[order->count++] = dev_name(&pdev->dev);
+		wake_up_interruptible(&order->wq);
+	}
+
+	return 0;
+}
+
+static struct platform_driver swnode_test_supplier_driver = {
+	.probe = swnode_test_record_probe,
+	.driver = {
+		.name = SWNODE_DEVLINK_TEST_SUPPLIER,
+	},
+};
+
+static struct platform_driver swnode_test_consumer_driver = {
+	.probe = swnode_test_record_probe,
+	.driver = {
+		.name = SWNODE_DEVLINK_TEST_CONSUMER,
+	},
+};
+
+static void swnode_devlink_test_probe_order(struct kunit *test)
+{
+	static const struct software_node supplier_swnode = {
+		.name = "swnode-devlink-test-supplier",
+	};
+
+	const struct property_entry consumer_props[] = {
+		PROPERTY_ENTRY_REF("supplier-ref", &supplier_swnode),
+		{ }
+	};
+
+	struct platform_device *supplier, *consumer;
+	struct swnode_test_probe_order *order;
+	struct fwnode_handle *fwnode;
+	int ret;
+
+	order = kunit_kzalloc(test, sizeof(*order), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, order);
+	init_waitqueue_head(&order->wq);
+
+	fwnode = kunit_software_node_register(test, &supplier_swnode);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
+
+	ret = kunit_platform_driver_register(test, &swnode_test_supplier_driver);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+	ret = kunit_platform_driver_register(test, &swnode_test_consumer_driver);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	supplier = kunit_platform_device_alloc(test, SWNODE_DEVLINK_TEST_SUPPLIER,
+					       PLATFORM_DEVID_NONE);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, supplier);
+	consumer = kunit_platform_device_alloc(test, SWNODE_DEVLINK_TEST_CONSUMER,
+					       PLATFORM_DEVID_NONE);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, consumer);
+
+	platform_set_drvdata(supplier, order);
+	platform_set_drvdata(consumer, order);
+
+	ret = device_add_software_node(&supplier->dev, &supplier_swnode);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+	ret = device_create_managed_software_node(&consumer->dev,
+						  consumer_props, NULL);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = kunit_platform_device_add(test, consumer);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+	ret = kunit_platform_device_add(test, supplier);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = wait_event_interruptible_timeout(order->wq,
+					       order->count == 2,
+					       msecs_to_jiffies(SWNODE_DEVLINK_TEST_TIMEOUT_MS));
+	KUNIT_ASSERT_GT(test, ret, 0);
+
+	KUNIT_EXPECT_STREQ(test, order->probed[0], SWNODE_DEVLINK_TEST_SUPPLIER);
+	KUNIT_EXPECT_STREQ(test, order->probed[1], SWNODE_DEVLINK_TEST_CONSUMER);
+
+	/* Tear down the consumer (and its device link) before the supplier. */
+	kunit_platform_device_unregister(test, consumer);
+
+	device_remove_software_node(&supplier->dev);
+}
+
+static struct kunit_case swnode_test_cases[] = {
+	KUNIT_CASE(swnode_devlink_test_single_ref),
+	KUNIT_CASE(swnode_devlink_test_multiple_refs),
+	KUNIT_CASE(swnode_devlink_test_unregistered_ref),
+	KUNIT_CASE(swnode_devlink_test_remote_endpoint_excluded),
+	KUNIT_CASE(swnode_devlink_test_ref_array),
+	KUNIT_CASE(swnode_devlink_test_probe_order),
+	{ }
+};
+
+static struct kunit_suite swnode_test_suite = {
+	.name = "software-node-links",
+	.test_cases = swnode_test_cases,
+};
+
+kunit_test_suite(swnode_test_suite);
+
+MODULE_DESCRIPTION("Test module for software node fw_devlink support");
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>");
+MODULE_LICENSE("GPL");

-- 
2.47.3


^ permalink raw reply related

* [PATCH 4/5] MAINTAINERS: add myself as reviewer of software node support
From: Bartosz Golaszewski @ 2026-06-29 10:52 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Andy Shevchenko,
	Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Linus Walleij, Dmitry Torokhov
  Cc: linux-kernel, linux-kselftest, kunit-dev, linux-acpi, driver-core,
	linux-gpio, Bartosz Golaszewski
In-Reply-To: <20260629-swnode-fw-devlink-v1-0-b90058b41839@oss.qualcomm.com>

I've been working extensively on software nodes lately and introduced
some changes. Add myself as reviewer so that I can help review any new
proposed changes.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 15011f5752a994cf1b354f490d6c4e411588df88..e30aa3b63eff90bc0ccc39de774986ce17494071 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -25101,10 +25101,12 @@ R:	Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 R:	Daniel Scally <djrscally@gmail.com>
 R:	Heikki Krogerus <heikki.krogerus@linux.intel.com>
 R:	Sakari Ailus <sakari.ailus@linux.intel.com>
+R:	Bartosz Golaszewski <brgl@kernel.org>
 L:	linux-acpi@vger.kernel.org
 S:	Maintained
 F:	drivers/base/property.c
 F:	drivers/base/swnode.c
+F:	drivers/base/test/swnode-devlink-test.c
 F:	include/linux/fwnode.h
 F:	include/linux/property.h
 

-- 
2.47.3


^ permalink raw reply related

* [PATCH 5/5] gpio: kunit: add test cases verifying swnode devlink support
From: Bartosz Golaszewski @ 2026-06-29 10:52 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Andy Shevchenko,
	Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Linus Walleij, Dmitry Torokhov
  Cc: linux-kernel, linux-kselftest, kunit-dev, linux-acpi, driver-core,
	linux-gpio, Bartosz Golaszewski
In-Reply-To: <20260629-swnode-fw-devlink-v1-0-b90058b41839@oss.qualcomm.com>

The software node fw_devlink support already has its own kunit suite, but
that verifies the fwnode links in isolation. Add GPIO tests that prove
the ordering works in a real-life use-case: a GPIO consumer that
references its provider via a software node.

The first suite registers the provider's software node, adds the consumer
device first and checks that fw_devlink defers its probe until the
provider has been added and bound. The second covers the fallback:
with the provider's software node not yet registered no supplier link is
created, so the consumer probes, devm_gpiod_get() returns -EPROBE_DEFER
and the consumer only binds once the provider shows up.

While at it: the existing gpio_unbind_with_consumers() test keeps the
consumer bound while the provider goes away and then operates the orphaned
descriptor. With software nodes now being covered by fw_devlink that would
instead force-unbind the consumer along with the provider, so opt it out
by setting FWNODE_FLAG_LINKS_ADDED.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 drivers/gpio/gpiolib-kunit.c | 272 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 265 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpiolib-kunit.c b/drivers/gpio/gpiolib-kunit.c
index 380b68f879e55433668353bb88067d561142a5bc..3def39f11ece46557cbdf8bae8642b2ad21232f0 100644
--- a/drivers/gpio/gpiolib-kunit.c
+++ b/drivers/gpio/gpiolib-kunit.c
@@ -12,11 +12,14 @@
 #include <linux/platform_device.h>
 #include <linux/property.h>
 
+#include <kunit/fwnode.h>
 #include <kunit/platform_device.h>
 #include <kunit/test.h>
 
 #define GPIO_TEST_PROVIDER		"gpio-test-provider"
 #define GPIO_SWNODE_TEST_CONSUMER	"gpio-swnode-test-consumer"
+#define GPIO_PROBE_ORDER_TEST_CONSUMER	"gpio-probe-order-test-consumer"
+#define GPIO_PROBE_DEFER_TEST_CONSUMER	"gpio-probe-defer-test-consumer"
 #define GPIO_UNBIND_TEST_CONSUMER	"gpio-unbind-test-consumer"
 
 static int gpio_test_provider_get_direction(struct gpio_chip *gc, unsigned int offset)
@@ -213,6 +216,251 @@ static struct kunit_suite gpio_swnode_lookup_test_suite = {
 	.test_cases = gpio_swnode_lookup_tests,
 };
 
+static void gpio_swnode_unregister_swnode(void *data)
+{
+	software_node_unregister(data);
+}
+
+struct gpio_probe_order_pdata {
+	int probe_count;
+	bool gpio_ok;
+};
+
+static const struct gpio_probe_order_pdata gpio_probe_order_pdata_template = {
+	.probe_count = 0,
+	.gpio_ok = false,
+};
+
+static int gpio_probe_order_consumer_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct gpio_probe_order_pdata *pdata = dev_get_platdata(dev);
+	struct gpio_desc *desc;
+
+	pdata->probe_count++;
+
+	desc = devm_gpiod_get(dev, "foo", GPIOD_OUT_HIGH);
+	if (IS_ERR(desc))
+		return PTR_ERR(desc);
+
+	pdata->gpio_ok = true;
+
+	return 0;
+}
+
+static struct platform_driver gpio_probe_order_consumer_driver = {
+	.probe = gpio_probe_order_consumer_probe,
+	.driver = {
+		.name = GPIO_PROBE_ORDER_TEST_CONSUMER,
+	},
+};
+
+/*
+ * Verify that fw_devlink orders the probe of a GPIO consumer after its
+ * provider. The consumer references the provider through a software node and
+ * is registered first. fw_devlink must defer it before its driver's probe()
+ * is ever entered, so the consumer probes exactly once - only after the
+ * provider is added and bound.
+ */
+static void gpio_swnode_probe_order(struct kunit *test)
+{
+	struct gpio_probe_order_pdata *pdata;
+	struct platform_device_info pdevinfo;
+	struct property_entry properties[2];
+	struct platform_device *prvd, *cons;
+	bool bound = false;
+	int ret;
+
+	ret = kunit_platform_driver_register(test, &gpio_test_provider_driver);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = kunit_platform_driver_register(test, &gpio_probe_order_consumer_driver);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = software_node_register(&gpio_test_provider_swnode);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = kunit_add_action_or_reset(test, gpio_swnode_unregister_swnode,
+					(void *)&gpio_test_provider_swnode);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	properties[0] = PROPERTY_ENTRY_GPIO("foo-gpios",
+					    &gpio_test_provider_swnode,
+					    0, GPIO_ACTIVE_HIGH);
+	properties[1] = (struct property_entry){ };
+
+	pdevinfo = (struct platform_device_info){
+		.name = GPIO_PROBE_ORDER_TEST_CONSUMER,
+		.id = PLATFORM_DEVID_NONE,
+		.data = &gpio_probe_order_pdata_template,
+		.size_data = sizeof(gpio_probe_order_pdata_template),
+		.properties = properties,
+	};
+
+	cons = kunit_platform_device_register_full(test, &pdevinfo);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons);
+
+	wait_for_device_probe();
+	scoped_guard(device, &cons->dev)
+		bound = device_is_bound(&cons->dev);
+
+	KUNIT_ASSERT_FALSE(test, bound);
+
+	pdata = dev_get_platdata(&cons->dev);
+	KUNIT_ASSERT_EQ(test, pdata->probe_count, 0);
+	KUNIT_ASSERT_FALSE(test, pdata->gpio_ok);
+
+	pdevinfo = (struct platform_device_info){
+		.name = GPIO_TEST_PROVIDER,
+		.id = PLATFORM_DEVID_NONE,
+		.swnode = &gpio_test_provider_swnode,
+	};
+
+	prvd = kunit_platform_device_register_full(test, &pdevinfo);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, prvd);
+
+	wait_for_device_probe();
+
+	scoped_guard(device, &prvd->dev)
+		bound = device_is_bound(&prvd->dev);
+	KUNIT_ASSERT_TRUE(test, bound);
+
+	scoped_guard(device, &cons->dev)
+		bound = device_is_bound(&cons->dev);
+	KUNIT_ASSERT_TRUE(test, bound);
+
+	pdata = dev_get_platdata(&cons->dev);
+	KUNIT_ASSERT_EQ(test, pdata->probe_count, 1);
+	KUNIT_ASSERT_TRUE(test, pdata->gpio_ok);
+}
+
+struct gpio_probe_defer_pdata {
+	int probe_count;
+	int gpio_err;
+};
+
+static const struct gpio_probe_defer_pdata gpio_probe_defer_pdata_template = {
+	.probe_count = 0,
+	.gpio_err = 0,
+};
+
+static int gpio_probe_defer_consumer_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct gpio_probe_defer_pdata *pdata = dev_get_platdata(dev);
+	struct gpio_desc *desc;
+
+	pdata->probe_count++;
+
+	desc = devm_gpiod_get(dev, "foo", GPIOD_OUT_HIGH);
+	if (IS_ERR(desc)) {
+		pdata->gpio_err = PTR_ERR(desc);
+		return pdata->gpio_err;
+	}
+
+	pdata->gpio_err = 0;
+
+	return 0;
+}
+
+static struct platform_driver gpio_probe_defer_consumer_driver = {
+	.probe = gpio_probe_defer_consumer_probe,
+	.driver = {
+		.name = GPIO_PROBE_DEFER_TEST_CONSUMER,
+	},
+};
+
+/*
+ * Verify that a GPIO consumer referencing a provider whose software node is
+ * not registered yet, defers its probe instead of failing.
+ *
+ * The provider software node is deliberately left unregistered when the
+ * consumer is added. fw_devlink cannot resolve the reference, so it creates no
+ * supplier link and does not order the consumer - the consumer's probe() runs
+ * and reaches devm_gpiod_get(). The swnode GPIO lookup returns -ENOTCONN for a
+ * reference to an unregistered node, which gpiolib maps to -EPROBE_DEFER. Once
+ * the provider software node and device appear, the deferred consumer probes
+ * again and binds.
+ */
+static void gpio_swnode_probe_defer_on_unregistered(struct kunit *test)
+{
+	struct gpio_probe_defer_pdata *pdata;
+	struct platform_device_info pdevinfo;
+	struct property_entry properties[2];
+	struct platform_device *prvd, *cons;
+	struct fwnode_handle *fwnode;
+	bool bound = false;
+	int ret;
+
+	ret = kunit_platform_driver_register(test, &gpio_test_provider_driver);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = kunit_platform_driver_register(test, &gpio_probe_defer_consumer_driver);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	properties[0] = PROPERTY_ENTRY_GPIO("foo-gpios",
+					    &gpio_test_provider_swnode,
+					    0, GPIO_ACTIVE_HIGH);
+	properties[1] = (struct property_entry){ };
+
+	pdevinfo = (struct platform_device_info){
+		.name = GPIO_PROBE_DEFER_TEST_CONSUMER,
+		.id = PLATFORM_DEVID_NONE,
+		.data = &gpio_probe_defer_pdata_template,
+		.size_data = sizeof(gpio_probe_defer_pdata_template),
+		.properties = properties,
+	};
+
+	cons = kunit_platform_device_register_full(test, &pdevinfo);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons);
+
+	wait_for_device_probe();
+	scoped_guard(device, &cons->dev)
+		bound = device_is_bound(&cons->dev);
+
+	KUNIT_ASSERT_FALSE(test, bound);
+
+	pdata = dev_get_platdata(&cons->dev);
+	KUNIT_ASSERT_GT(test, pdata->probe_count, 0);
+	KUNIT_ASSERT_EQ(test, pdata->gpio_err, -EPROBE_DEFER);
+
+	fwnode = kunit_software_node_register(test, &gpio_test_provider_swnode);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
+
+	pdevinfo = (struct platform_device_info){
+		.name = GPIO_TEST_PROVIDER,
+		.id = PLATFORM_DEVID_NONE,
+		.swnode = &gpio_test_provider_swnode,
+	};
+
+	prvd = kunit_platform_device_register_full(test, &pdevinfo);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, prvd);
+
+	wait_for_device_probe();
+
+	scoped_guard(device, &prvd->dev)
+		bound = device_is_bound(&prvd->dev);
+	KUNIT_ASSERT_TRUE(test, bound);
+
+	scoped_guard(device, &cons->dev)
+		bound = device_is_bound(&cons->dev);
+	KUNIT_ASSERT_TRUE(test, bound);
+
+	pdata = dev_get_platdata(&cons->dev);
+	KUNIT_ASSERT_EQ(test, pdata->gpio_err, 0);
+}
+
+static struct kunit_case gpio_swnode_probe_order_tests[] = {
+	KUNIT_CASE(gpio_swnode_probe_order),
+	KUNIT_CASE(gpio_swnode_probe_defer_on_unregistered),
+	{ }
+};
+
+static struct kunit_suite gpio_swnode_probe_order_test_suite = {
+	.name = "gpio-swnode-probe-order",
+	.test_cases = gpio_swnode_probe_order_tests,
+};
+
 static BLOCKING_NOTIFIER_HEAD(gpio_unbind_notifier);
 
 struct gpio_unbind_consumer_drvdata {
@@ -310,15 +558,24 @@ static void gpio_unbind_with_consumers(struct kunit *test)
 					    0, GPIO_ACTIVE_HIGH);
 	properties[1] = (struct property_entry){ };
 
-	pdevinfo = (struct platform_device_info){
-		.name = GPIO_UNBIND_TEST_CONSUMER,
-		.id = PLATFORM_DEVID_NONE,
-		.properties = properties,
-	};
-
-	cons = kunit_platform_device_register_full(test, &pdevinfo);
+	/*
+	 * This test deliberately keeps the consumer bound while the provider
+	 * is unregistered. fw_devlink would force-unbind the consumer before
+	 * the provider so use the FWNODE_FLAG_LINKS_ADDED flag to opt out of
+	 * it as a workaround.
+	 */
+	cons = kunit_platform_device_alloc(test, GPIO_UNBIND_TEST_CONSUMER,
+					   PLATFORM_DEVID_NONE);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons);
 
+	ret = device_create_managed_software_node(&cons->dev, properties, NULL);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	fwnode_set_flag(dev_fwnode(&cons->dev), FWNODE_FLAG_LINKS_ADDED);
+
+	ret = kunit_platform_device_add(test, cons);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
 	wait_for_device_probe();
 	scoped_guard(device, &cons->dev)
 		bound = device_is_bound(&cons->dev);
@@ -350,6 +607,7 @@ static struct kunit_suite gpio_unbind_with_consumers_test_suite = {
 
 kunit_test_suites(
 	&gpio_swnode_lookup_test_suite,
+	&gpio_swnode_probe_order_test_suite,
 	&gpio_unbind_with_consumers_test_suite,
 );
 

-- 
2.47.3


^ permalink raw reply related

* [PATCH] gpio: swnode: remove deprecated lookup mechanism
From: Bartosz Golaszewski @ 2026-06-29 10:54 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, Dmitry Torokhov,
	Andy Shevchenko
  Cc: linux-gpio, linux-kernel, Bartosz Golaszewski

GPIO software node lookup should rely exclusively on matching the
addresses of the referenced firmware nodes. Commit e5d527be7e69 ("gpio:
swnode: don't use the swnode's name as the key for GPIO lookup") tried to
enforce this but had to be reverted: it broke existing users who abused
the software node mechanism by creating "dummy" software nodes named
after the device they want to get GPIOs from, without ever attaching them
to the actual GPIO devices. Those users relied on GPIOLIB matching the
label of the GPIO controller against the name of the software node rather
than on a real firmware node link.

All such users have now been coverted to using attached software nodes
via the fwnode address lookup path and the kernel documentation has been
updated to recommend it as the correct approach. This allows us to remove
the old behavior.

This will allow us to leverage the upcoming support for fw_devlink for
software nodes in GPIO core.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 drivers/gpio/gpiolib-swnode.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/drivers/gpio/gpiolib-swnode.c b/drivers/gpio/gpiolib-swnode.c
index 8d9591aa9304d1eac931d1cb19597ae4b99c40a2..4aa3f3406caaf7e049aa1da153d790e65de3008c 100644
--- a/drivers/gpio/gpiolib-swnode.c
+++ b/drivers/gpio/gpiolib-swnode.c
@@ -41,27 +41,7 @@ static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode)
 		return ERR_PTR(-ENOENT);
 
 fwnode_lookup:
-	gdev = gpio_device_find_by_fwnode(fwnode);
-	if (!gdev && gdev_node && gdev_node->name)
-		/*
-		 * FIXME: We shouldn't need to compare the GPIO controller's
-		 * label against the software node that is supposedly attached
-		 * to it. However there are currently GPIO users that - knowing
-		 * the expected label of the GPIO chip whose pins they want to
-		 * control - set up dummy software nodes named after those GPIO
-		 * controllers, which aren't actually attached to them. In this
-		 * case gpio_device_find_by_fwnode() will fail as no device on
-		 * the GPIO bus is actually associated with the fwnode we're
-		 * looking for.
-		 *
-		 * As a fallback: continue checking the label if we have no
-		 * match. However, the situation described above is an abuse
-		 * of the software node API and should be phased out and the
-		 * following line - eventually removed.
-		 */
-		gdev = gpio_device_find_by_label(gdev_node->name);
-
-	return gdev ?: ERR_PTR(-EPROBE_DEFER);
+	return gpio_device_find_by_fwnode(fwnode) ?: ERR_PTR(-EPROBE_DEFER);
 }
 
 static int swnode_gpio_get_reference(const struct fwnode_handle *fwnode,

---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260625-gpio-swnode-drop-label-matching-a975ad5f0e40

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>


^ permalink raw reply related

* Re: [PATCH 00/32] x86/msr: Drop 32-bit MSR interfaces
From: Ingo Molnar @ 2026-06-29 11:19 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Juergen Gross, linux-kernel, linux-pm, linux-edac@vger.kernel.org,
	x86, linux-acpi, kvm, linux-coco, linux-pci, virtualization,
	linux-ide, dri-devel, linux-fbdev, linux-crypto,
	open list:GPIO SUBSYSTEM, linux-hyperv, linux-hwmon,
	linux-perf-users, linux-mtd, platform-driver-x86,
	Rafael J . Wysocki, Daniel Lezcano, Zhang Rui,
	lukasz.luba@arm.com, Jason Baron, Borislav Petkov, Tony Luck,
	Yazen Ghannam, Len Brown, Pavel Machek, Thomas Gleixner,
	Ingo Molnar, Dave Hansen, H. Peter Anvin, Sean Christopherson,
	Paolo Bonzini, Kirill A. Shutemov, Rick Edgecombe, Pu Wen,
	Bjorn Helgaas, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Viresh Kumar,
	Reinette Chatre, Dave Martin, James Morse, Babu Moger,
	Tony W Wang-oc, Damien Le Moal, Niklas Cassel, Dave Airlie,
	Helge Deller, linux-geode, Olivia Mackall, Herbert Xu,
	Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
	Guenter Roeck, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark, Josh Poimboeuf,
	Pawan Gupta, Vitaly Kuznetsov, Andy Lutomirski, Boris Ostrovsky,
	Huang Rui, Mario Limonciello, Perry Yuan, K Prateek Nayak,
	srinivas.pandruvada@linux.intel.com, Artem Bityutskiy,
	Artem Bityutskiy, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Ashok Raj, Hans de Goede, Ilpo Järvinen,
	Rajneesh Bhardwaj, David E Box, xen-devel
In-Reply-To: <7332feff-2649-496c-8e49-b0a19eb54a32@app.fastmail.com>

* Arnd Bergmann <arnd@arndb.de> wrote:

> >>> Note that most patches of this series are independent from each other.
> >>> Only the patches removing a specific interface (patches 7, 15, 26 and
> >>> 30) and the last two patches of the series depend on all previous
> >>> patches.
> >> 
> >> It looks like you are touching most files twice or more here, to
> >> first convert from rdmsr to rdmsrq and then to change the
> >> two-argument rdmsrq() macro to a single-argument inline. If you
> >> introduce the inline version of rdmsrq() first, you should be
> >> able to skip the second step (patch 31) as they could be able
> >> to coexist.
> >
> > I've discussed how to structure the series with Ingo Molnar before [1]. The
> > current approach was his preference.
> 
> Ok.

Note that the individual patches are IMO significantly easier to review
through the actual 32-bit => 64-bit variable assignment changes done
in isolation (which sometimes include minor cleanups), while
the Coccinelle semantic patch:

   { a(b,c) => c = a(b) }

which changes both the function signature and the order of terms as
well, is just a single add-on treewide patch.

Thanks,

	Ingo

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox