* Re: [PATCH RFC] ACPI: processor: idle: Do not propagate acpi_processor_ffh_lpi_probe() -ENODEV
From: lihuisong (C) @ 2026-04-20 6:38 UTC (permalink / raw)
To: Rafael J. Wysocki, Breno Leitao
Cc: Sudeep Holla, Len Brown, lpieralisi, catalin.marinas, will,
Rafael J. Wysocki, linux-acpi, linux-kernel, pjaroszynski,
guohanjun, linux-arm-kernel, rmikey, kernel-team, lihuisong
In-Reply-To: <CAJZ5v0hftnagiLTPCEjqviyug5g5NQCztX1o0w5NOY8d=5cz+g@mail.gmail.com>
On 4/15/2026 10:03 PM, Rafael J. Wysocki wrote:
> On Wed, Apr 15, 2026 at 3:32 AM lihuisong (C) <lihuisong@huawei.com> wrote:
>>
>> On 4/14/2026 8:25 PM, Sudeep Holla wrote:
>>> On Tue, Apr 14, 2026 at 07:31:29PM +0800, lihuisong (C) wrote:
>>>> On 4/14/2026 6:21 PM, Breno Leitao wrote:
>>>>> Hello Huisong,
>>>>>
>>>>> On Tue, Apr 14, 2026 at 05:43:51PM +0800, lihuisong (C) wrote:
>>>>>> But it is a real issue. Thanks for your report.
>>>>>> I think the best way to fix your issue is that remove this verification in
>>>>>> psci_acpi_cpu_init_idle().
>>>>>> Because it is legal for platform to report one LPI state.
>>>>>> This function just needs to verify the LPI states which are FFH.
>>>>> Thank you for the prompt feedback.
>>>>>
>>>>> Would this approach work?
>>>>>
>>>>> commit 6c9d52840a4f778cc989838ba76ee51416e85de3
>>>>> Author: Breno Leitao <leitao@debian.org>
>>>>> Date: Tue Apr 14 03:16:08 2026 -0700
>>>>>
>>>>> ACPI: processor: idle: Allow platforms with only one LPI state
>>>>> psci_acpi_cpu_init_idle() rejects platforms where power.count - 1 <= 0
>>>>> by returning -ENODEV. However, having a single LPI state (WFI) is a
>>>>> valid configuration. The function's purpose is to verify FFH idle states,
>>>>> and when count is zero, there are simply no FFH states to validate —
>>>>> this is not an error.
>>>>> On NVIDIA Grace (aarch64) systems with PSCIv1.1, power.count is 1 for
>>>>> all 72 CPUs, so the probe fails with -ENODEV. After commit cac173bea57d
>>>>> ("ACPI: processor: idle: Rework the handling of
>>>>> acpi_processor_ffh_lpi_probe()"), this failure propagates up and prevents
>>>>> cpuidle registration entirely.
>>>>> Change the check from (count <= 0) to (count < 0) so that platforms
>>>>> with only WFI are accepted. The for loop naturally handles count == 0
>>>>> by not iterating.
>>>>> Fixes: cac173bea57d ("ACPI: processor: idle: Rework the handling of acpi_processor_ffh_lpi_probe()")
>>>>> Signed-off-by: Breno Leitao <leitao@debian.org>
>>>>>
>>>>> diff --git a/drivers/acpi/arm64/cpuidle.c b/drivers/acpi/arm64/cpuidle.c
>>>>> index 801f9c4501425..7791b751042ce 100644
>>>>> --- a/drivers/acpi/arm64/cpuidle.c
>>>>> +++ b/drivers/acpi/arm64/cpuidle.c
>>>>> @@ -31,7 +31,7 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
>>>>> return -EOPNOTSUPP;
>>>>> count = pr->power.count - 1;
>>>>> - if (count <= 0)
>>>>> + if (count < 0)
>>>>> return -ENODEV;
>>>>> for (i = 0; i < count; i++) {
>>>> This count already verified in acpi_processor_get_lpi_info.
>>>>
>>>> I suggest modifing it as below:
>>>>
>>>> -->
>>>>
>>>> git diff
>>>> diff --git a/drivers/acpi/arm64/cpuidle.c b/drivers/acpi/arm64/cpuidle.c
>>>> index 801f9c450142..c68a5db8ebba 100644
>>>> --- a/drivers/acpi/arm64/cpuidle.c
>>>> +++ b/drivers/acpi/arm64/cpuidle.c
>>>> @@ -16,7 +16,7 @@
>>>>
>>>> static int psci_acpi_cpu_init_idle(unsigned int cpu)
>>>> {
>>>> - int i, count;
>>>> + int i;
>>>> struct acpi_lpi_state *lpi;
>>>> struct acpi_processor *pr = per_cpu(processors, cpu);
>>>>
>>>> @@ -30,14 +30,10 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
>>>> if (!psci_ops.cpu_suspend)
>>>> return -EOPNOTSUPP;
>>>>
>>>> - count = pr->power.count - 1;
>>>> - if (count <= 0)
>>>> - return -ENODEV;
>>>> -
>>> It was intentionally designed this way, as there is little value in defining
>>> only WFI in the _LPI tables. In the absence of a cpuidle driver/LPI entry,
>>> arch_cpu_idle() is invoked, which is sufficient and avoids unnecessary
>>> complexity, only to ultimately execute wfi() anyway.
>> Yeah, it's correct. The code flow will be more simple and high-efficiency.
>> This looks good to me.
>>
>>
>> But cpuidle sysfs under per CPU is created when firmware just reports
>> WFI state before
>> my commit cac173bea57d ("ACPI: processor: idle: Rework the handling of
>> acpi_processor_ffh_lpi_probe()").
>> However, these platforms will no longer be created now and some
>> statistics for state0 are also missing.
>> This change in behavor is visiable to user space.I'm not sure if it is
>> acceptable.
>> What do you think, Rafael?
> I think that it would be good to restore the previous behavior,
> especially if it has been changed inadvertently.
Agreed.
Can you send it again using my proposal, @breno?
We can send out other patch to discuss it if need to optimize the point
Sudeep mentioned.
>
^ permalink raw reply
* Re: [PATCH v7 2/4] KVM: arm64: PMU: Protect the list of PMUs with RCU
From: Akihiko Odaki @ 2026-04-20 6:21 UTC (permalink / raw)
To: Marc Zyngier
Cc: Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Catalin Marinas, Will Deacon, Kees Cook, Gustavo A. R. Silva,
Paolo Bonzini, Jonathan Corbet, Shuah Khan, linux-arm-kernel,
kvmarm, linux-kernel, linux-hardening, devel, kvm, linux-doc,
linux-kselftest
In-Reply-To: <87mryzauib.wl-maz@kernel.org>
On 2026/04/19 23:34, Marc Zyngier wrote:
> On Sat, 18 Apr 2026 09:14:24 +0100,
> Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
>>
>> Convert the list of PMUs to a RCU-protected list that has primitives to
>> avoid read-side contention.
>>
>> Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
>> ---
>> arch/arm64/kvm/pmu-emul.c | 14 ++++++--------
>> 1 file changed, 6 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
>> index 59ec96e09321..ef5140bbfe28 100644
>> --- a/arch/arm64/kvm/pmu-emul.c
>> +++ b/arch/arm64/kvm/pmu-emul.c
>> @@ -7,9 +7,9 @@
>> #include <linux/cpu.h>
>> #include <linux/kvm.h>
>> #include <linux/kvm_host.h>
>> -#include <linux/list.h>
>> #include <linux/perf_event.h>
>> #include <linux/perf/arm_pmu.h>
>> +#include <linux/rculist.h>
>> #include <linux/uaccess.h>
>> #include <asm/kvm_emulate.h>
>> #include <kvm/arm_pmu.h>
>> @@ -26,7 +26,6 @@ static bool kvm_pmu_counter_is_enabled(struct kvm_pmc *pmc);
>>
>> bool kvm_supports_guest_pmuv3(void)
>> {
>> - guard(mutex)(&arm_pmus_lock);
>> return !list_empty(&arm_pmus);
>
> Please read include/linux/rculist.h and the discussion about the
> interaction of list_empty() with RCU-protected lists. How about using
> list_first_or_null_rcu() for peace of mind?
list_first_or_null_rcu() is useful to replace a sequence of list_empty()
and list_first_entry() that is protected by a lock, but this function
instead requires the invariant that nobody deletes an element from the
list, and list_first_or_null_rcu() does not allow removing the requirement.
The header file says:
> Where are list_empty_rcu() and list_first_entry_rcu()?
>
> They do not exist because they would lead to subtle race conditions:
>
> if (!list_empty_rcu(mylist)) {
> struct foo *bar = list_first_entry_rcu(mylist, struct foo,
> list_member);
> do_something(bar);
> }
>
> The list might be non-empty when list_empty_rcu() checks it, but it
> might have become empty by the time that list_first_entry_rcu()
> rereads the ->next pointer, which would result in a SEGV.
>
> When not using RCU, it is OK for list_first_entry() to re-read that
> pointer because both functions should be protected by some lock that
> blocks writers.
>
> When using RCU, list_empty() uses READ_ONCE() to fetch the
> RCU-protected ->next pointer and then compares it to the address of
> the list head. However, it neither dereferences this pointer nor
> provides this pointer to its caller. Thus, READ_ONCE() suffices
> (that is, rcu_dereference() is not needed), which means that
> list_empty() can be used anywhere you would want to use
> list_empty_rcu(). Just don't expect anything useful to happen if you
> do a subsequent lockless call to list_first_entry_rcu()!!!
>
> See list_first_or_null_rcu for an alternative.
However, kvm_supports_guest_pmuv3() locked a mutex when calling
list_empty() and unlocked it immediately after that, instead of
re-reading list_first_entry(). This construct inherently had a race
condition with code that deletes an element; when the caller of
kvm_supports_guest_pmuv3() decides to enable guest PMUv3, the host PMU
may have been gone. But it was still safe because no one deletes an element.
The same logic also applies when using RCU. As the comment says, we can
use list_empty() instead of the hypothetical list_empty_rcu() macro
because we don't expect it to magically enable something like
list_first_entry_rcu(). This function instead keep relying on the fact
that no one deletes an element of the list.
Regards,
Akihiko Odaki
^ permalink raw reply
* [PATCH v2 2/2] arm64: dts: amlogic: add support for X98Q
From: christian.koever-draxl @ 2026-04-20 6:18 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, neil.armstrong, khilman
Cc: jbrunet, martin.blumenstingl, funderscore, devicetree,
linux-kernel, linux-arm-kernel, linux-amlogic,
christian.koever-draxl
In-Reply-To: <20260420061854.5421-1-christian.koever-draxl@student.uibk.ac.at>
From: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
Signed-off-by: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
---
arch/arm64/boot/dts/amlogic/Makefile | 1 +
.../boot/dts/amlogic/meson-s4-s905w2-x98q.dts | 250 ++++++++++++++++++
2 files changed, 251 insertions(+)
create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 15f9c817e502..c7752684dea6 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -85,6 +85,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-ugoos-am3.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-s4-s905w2-x98q.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-s4-s905y4-khadas-vim1s.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
new file mode 100644
index 000000000000..26c60a4c2a43
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
@@ -0,0 +1,250 @@
+
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2026 Christian Stefan Köver-Draxl
+ * Based on meson-s4-s905y4-khadas-vim1s.dts:
+ * - Copyright (c) 2026 Khadas Technology Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "meson-s4.dtsi"
+
+/ {
+ model = "Shenzhen Amediatech Technology Co., Ltd X98Q";
+ compatible = "amediatech,x98q", "amlogic,s905w2", "amlogic,s4";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ mmc0 = &emmc; /* eMMC */
+ mmc1 = &sd; /* SD card */
+ mmc2 = &sdio; /* SDIO */
+ serial0 = &uart_b;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* 52 MiB reserved for ARM Trusted Firmware */
+ secmon_reserved: secmon@5000000 {
+ reg = <0x0 0x05000000 0x0 0x3400000>;
+ no-map;
+ };
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio GPIOB_9 GPIO_ACTIVE_LOW>;
+ };
+
+ sdio_32k: sdio-32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ clocks = <&sdio_32k>;
+ clock-names = "ext_clock";
+ };
+
+ main_5v: regulator-main-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ sd_3v3: regulator-sd-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "SD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio GPIOD_4 GPIO_ACTIVE_LOW>;
+ regulator-always-on;
+ };
+
+ vddio_sd: regulator-vddio-sd {
+ compatible = "regulator-gpio";
+ regulator-name = "VDDIO_SD";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio GPIOD_9 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <1800000 1 3300000 0>;
+ };
+
+ vddao_3v3: regulator-vddao-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&main_5v>;
+ regulator-always-on;
+ };
+
+ vddio_ao1v8: regulator-vddio-ao1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_AO1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ };
+
+ /* SY8120B1ABC DC/DC Regulator. */
+ vddcpu: regulator-vddcpu {
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU";
+ regulator-min-microvolt = <689000>;
+ regulator-max-microvolt = <1049000>;
+
+ vin-supply = <&main_5v>;
+
+ pwms = <&pwm_ij 1 1500 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ /* Voltage Duty-Cycle */
+ voltage-table = <1049000 0>,
+ <1039000 3>,
+ <1029000 6>,
+ <1019000 9>,
+ <1009000 12>,
+ <999000 14>,
+ <989000 17>,
+ <979000 20>,
+ <969000 23>,
+ <959000 26>,
+ <949000 29>,
+ <939000 31>,
+ <929000 34>,
+ <919000 37>,
+ <909000 40>,
+ <899000 43>,
+ <889000 45>,
+ <879000 48>,
+ <869000 51>,
+ <859000 54>,
+ <849000 56>,
+ <839000 59>,
+ <829000 62>,
+ <819000 65>,
+ <809000 68>,
+ <799000 70>,
+ <789000 73>,
+ <779000 76>,
+ <769000 79>,
+ <759000 81>,
+ <749000 84>,
+ <739000 87>,
+ <729000 89>,
+ <719000 92>,
+ <709000 95>,
+ <699000 98>,
+ <689000 100>;
+ };
+};
+
+&emmc {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+ pinctrl-1 = <&emmc_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_ao1v8>;
+};
+
+ðmac {
+ status = "okay";
+ phy-handle = <&internal_ephy>;
+ phy-mode = "rmii";
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_pins>;
+ pinctrl-names = "default";
+};
+
+&pwm_ef {
+ status = "okay";
+ pinctrl-0 = <&pwm_e_pins1>;
+ pinctrl-names = "default";
+};
+
+&pwm_ij {
+ status = "okay";
+};
+
+&sd {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-1 = <&sdcard_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <50000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddao_3v3>;
+};
+
+/*
+* Wireless SDIO Module (Amlogic W150S1)
+* Note: There is no driver for this at the moment.
+*/
+
+&sdio {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+
+ no-sd;
+ no-mmc;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_ao1v8>;
+};
+
+&uart_b {
+ status = "okay";
+};
--
2.53.0
^ permalink raw reply related
* [PATCH v2 0/2] Add support for Amediatech X98Q (Amlogic S905W2)
From: christian.koever-draxl @ 2026-04-20 6:18 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, neil.armstrong, khilman
Cc: jbrunet, martin.blumenstingl, funderscore, devicetree,
linux-kernel, linux-arm-kernel, linux-amlogic,
christian.koever-draxl
From: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
Supported features:
- 1GB/2GB RAM (via U-Boot memory fixup)
- 10/100 Ethernet (Internal PHY)
- eMMC and SD card storage
- PWM-based CPU voltage regulation
- UART (Serial console)
Changes in v2:
- Split dt-bindings and dts changes into separate patches.
- Updated model string to match documented vendor prefix.
- Put vddio_sd states array in a single line.
- Added a clarifying comment for the unsupported Amlogic W150S1 Wi-Fi module.
Notes:
- The console uses uart_b at 921600 baud.
- Verified memory via /proc/device-tree; U-Boot patches the node to around 2GB.
- Tested on the 2GB RAM plus 16GB eMMC variant.
Christian Stefan Kövér-Draxl (2):
dt-bindings: arm: amlogic: add X98Q compatible
arm64: dts: amlogic: add support for X98Q
.../devicetree/bindings/arm/amlogic.yaml | 7 +
arch/arm64/boot/dts/amlogic/Makefile | 1 +
.../boot/dts/amlogic/meson-s4-s905w2-x98q.dts | 250 ++++++++++++++++++
3 files changed, 258 insertions(+)
create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
--
2.53.0
^ permalink raw reply
* [PATCH v2 1/2] dt-bindings: arm: amlogic: add X98Q compatible
From: christian.koever-draxl @ 2026-04-20 6:18 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, neil.armstrong, khilman
Cc: jbrunet, martin.blumenstingl, funderscore, devicetree,
linux-kernel, linux-arm-kernel, linux-amlogic,
christian.koever-draxl
In-Reply-To: <20260420061854.5421-1-christian.koever-draxl@student.uibk.ac.at>
From: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
Signed-off-by: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
---
Documentation/devicetree/bindings/arm/amlogic.yaml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index a885278bc4e2..82671d58d1da 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -254,6 +254,13 @@ properties:
- khadas,vim1s
- const: amlogic,s905y4
- const: amlogic,s4
+
+ - description: Boards with the Amlogic Meson S4 S905W2 SoC
+ items:
+ - enum:
+ - amediatech,x98q
+ - const: amlogic,s905w2
+ - const: amlogic,s4
- description: Boards with the Amlogic S6 S905X5 SoC
items:
--
2.53.0
^ permalink raw reply related
* Re: [PATCH V13 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
From: mani @ 2026-04-20 5:59 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Sherry Sun, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, Frank Li, s.hauer@pengutronix.de,
kernel@pengutronix.de, festevam@gmail.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, bhelgaas@google.com, Hongxing Zhu,
l.stach@pengutronix.de, imx@lists.linux.dev,
linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20260417195533.GA92707@bhelgaas>
On Fri, Apr 17, 2026 at 02:55:33PM -0500, Bjorn Helgaas wrote:
> On Fri, Apr 17, 2026 at 03:17:16AM +0000, Sherry Sun wrote:
> > > On Thu, Apr 16, 2026 at 07:14:12PM +0800, Sherry Sun wrote:
> > > > Introduce generic helper functions to parse Root Port device
> > > > tree nodes and extract common properties like reset GPIOs. This
> > > > allows multiple PCI host controller drivers to share the same
> > > > parsing logic.
> > > >
> > > > Define struct pci_host_port to hold common Root Port properties
> > > > (currently only reset GPIO descriptor) and add
> > > > pci_host_common_parse_ports() to parse Root Port nodes from
> > > > device tree.
> > >
> > > Are the Root Port and the RC the only possible places for 'reset'
> > > GPIO descriptions in DT? I think PERST# routing is outside the
> > > PCIe spec, so it seems like a system could provide a PERST# GPIO
> > > routed to any Switch Upstream Port or Endpoint (I assume a PERST#
> > > connected to a switch would apply to both the upstream port and
> > > the downstream ports).
> >
> > Thanks for the feedback. You're right that PERST# routing could
> > theoretically be connected to any device in the hierarchy. However,
> > for this patch series, I've focused on the most common use case in
> > practice: use Root Port level PERST# instead of the legacy Root
> > Complex level PERST#.
> >
> > Root Port level PERST# - This is the primary target, where each Root
> > Port has individual control over devices connected to it. RC level
> > PERST# - Legacy binding support, where a single GPIO controls all
> > ports.
> >
> > We can extend this framework later if real hardware emerges that
> > needs Switch or EP-level PERST# control. I can add a comment
> > documenting this limitation if needed.
> >
> > BTW, Mani and Rob had some great discussions in dt-schema about
> > PERST# and WAKE# sideband signals settings.
>
> > You can check here:
> > https://github.com/devicetree-org/dt-schema/issues/168
> > https://github.com/devicetree-org/dt-schema/pull/126
> > https://github.com/devicetree-org/dt-schema/pull/170
>
> The upshot of all those conversations is that WAKE# and PERST# can be
> routed to arbitrary devices independent of the PCI topology.
>
> I think extending host-generic to look for 'reset' in Root Port nodes
> is the right thing. My concern is more about where we store it. This
> patch saves it in a new "pci_host_port" struct, but someday we'll want
> a place to save the PERST# GPIOs for several slots behind a switch.
> Then we'll have two different ways to save the same information.
>
Even if there are PERST# GPIOs from the host, connected to downstream ports of a
PCIe switch, they could be stored in the Root Port's (pci_host_port) struct as a
list of PERST#. This is what pcie-qcom driver does.
It is too clumsy to handle PERST# individually for each device. We tried it
before with pwrctrl, but it always ended up biting us on who gets to control the
PERST#. We can't let pwrctrl handle PERST# for a switch port and host controller
driver handle it for RP. And we cannot let pwrctrl handle PERST# for all ports,
because, host controller drivers also need to control them for RC
initialization.
That's why it was decided to handle PERST# for all ports in the host controller
drivers. So following that pattern, this helper could also be extended to parse
the PERST# from all ports defined in DT and store them in the same Root Port
struct.
It should be trivial to implement this logic in the current helper. @Sherry:
Could you please implement this logic?
> WAKE# signals might be more pertinent -- we definitely need to support
> multiple WAKE# signals below a single Root Port, and it seems like
> PERST# and WAKE# GPIOs should be saved the same place.
>
> I'm wondering if both should go in the pci_dev itself. I guess the
> implication is that a pci_dev->reset GPIO would describe a PERST#
> connected to the device *below* the pci_dev, at least for Downstream
> Ports.
>
Problem is, PERST# needs to be controlled even before 'pci_dev' gets created. We
create 'pci_dev' only when a device get's detected. But the PERST# assertion and
deassertion happens even before the pci_host_probe() call, which is the starting
point for enumeration. That's why storing it as a list in 'pci_host_bridge'
makes it accessible by the host controller drivers.
> I don't know about WAKE# signals. When it's in a connector, there's
> probably only a single possible WAKE# per Downstream Port. But is it
> possible have multiple WAKE# signals from a multi-function device
> that's on the motherboard? Saving the WAKE# GPIO in the Downstream
> Port wouldn't accommodate that case.
AFAIK, a single device can have only one WAKE# irrespective of how many function
it exposes. PCIe base spec doesn't indicate whether it is per-device or
per-function, but the form factor specfications like CEM, Mini-CEM define it as
a per-device signal.
Moreover, unlike PERST#, WAKE# is not driven by the host system. Host just needs
to register an IRQ handler to service the interrupts raised by the device. So it
can be parsed *after* enumerating a device and stored in 'pci_dev' as done in
Krishna's series:
https://lore.kernel.org/linux-pci/20260403-wakeirq_support-v9-0-1cbecf3b58d7@oss.qualcomm.com/
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCH v3 8/8] unwind: arm64: Use sframe to unwind interrupt frames.
From: Dylan Hatch @ 2026-04-20 5:56 UTC (permalink / raw)
To: Jens Remus
Cc: Roman Gushchin, Weinan Liu, Will Deacon, Josh Poimboeuf,
Indu Bhagat, Peter Zijlstra, Steven Rostedt, Catalin Marinas,
Jiri Kosina, Mark Rutland, Prasanna Kumar T S M, Puranjay Mohan,
Song Liu, joe.lawrence, linux-toolchains, linux-kernel,
live-patching, linux-arm-kernel, Heiko Carstens
In-Reply-To: <95f9d11a-dd92-433e-a8db-cbebe94e1611@linux.ibm.com>
On Fri, Apr 17, 2026 at 8:45 AM Jens Remus <jremus@linux.ibm.com> wrote:
>
> > + case UNWIND_CFA_RULE_FP_OFFSET:
> > + if (state->common.fp < state->common.sp)
> > + return -EINVAL;
>
> I wonder whether that check is valid in kernel? Looking at
> call_on_irq_stack() saving SP in FP and then loading SP with the IRQ SP.
> Is that condition always true then?
Good catch. I will double-check this.
>
> > + cfa = state->common.fp;
> > + break;
> > + case UNWIND_CFA_RULE_REG_OFFSET:
> > + case UNWIND_CFA_RULE_REG_OFFSET_DEREF:
> > + if (!regs)
>
> if (!regs || frame.cfa.regnum > 30)
>
> > + return -EINVAL;
> > + cfa = regs->regs[frame.cfa.regnum];
>
> In unwind user this is guarded by a topmost frame check, as arbitrary
> registers are otherwise not available. Isn't this necessary in the
> kernel case?
It is necessary, though as you point out the way I wrote the check is
not as obvious as it probably should be.
The saved state->regs is set when the current frame is recovered from
the saved PC of a struct pt_regs, and then immediately set back to
NULL after the next frame has been recovered. In other words, the
state->regs is only ever set when it is relevant to the current frame,
which occurs when state->source == KUNWIND_SOURCE_REGS_PC. This only
happens when the topmost frame is recovered from a pt_regs, or when a
pt_regs is recovered from the stack due to an interrupt.
I can make this more readable by adding an explicit check for
KUNWIND_SOURCE_REGS_PC in addition to state->regs != NULL.
>
> > + break;
> > + default:
> > + WARN_ON_ONCE(1);
> > + return -EINVAL;
> > + }
> > + cfa += frame.cfa.offset;
> > +
> > + /*
> > + * CFA typically points to a higher address than RA or FP, so don't
> > + * consume from the stack when we read it.
> > + */
> > + if (frame.cfa.rule & UNWIND_RULE_DEREF &&
> > + !get_word(&state->common, &cfa))
> > + return -EINVAL;
> > +
> > + /* CFA alignment 8 bytes */
> > + if (cfa & 0x7)
> > + return -EINVAL;
> > +
> > + /* Get the Return Address (RA) */
> > + switch (frame.ra.rule) {
> > + case UNWIND_RULE_RETAIN:
> > + if (!regs)
> > + return -EINVAL;
> > + ra = regs->regs[30];
>
> Likewise: Topmost frame check not required to access arbitrary registers
> (including RA/LR)? Furthermore, provided don't have a thinko, LR may
> only be in LR in the topmost frame. In any other frame it must have
> been saved. Otherwise there would be an endless return loop.
>
> > + source = KUNWIND_SOURCE_REGS_LR;
> > + break;
> > + /* UNWIND_USER_RULE_CFA_OFFSET not implemented on purpose */
> > + case UNWIND_RULE_CFA_OFFSET_DEREF:
> > + ra = cfa + frame.ra.offset;
> > + break;
> > + case UNWIND_RULE_REG_OFFSET:
> > + case UNWIND_RULE_REG_OFFSET_DEREF:
> > + if (!regs)
>
> if (!regs || frame.cfa.regnum > 30)
>
> > + return -EINVAL;
> > + ra = regs->regs[frame.cfa.regnum];
>
> Likewise: Topmost frame check not required to access arbitrary registers?
>
> > + ra += frame.ra.offset;
> > + break;
> > + default:
> > + WARN_ON_ONCE(1);
> > + return -EINVAL;
> > + }
> > +
> > + /* Get the Frame Pointer (FP) */
> > + switch (frame.fp.rule) {
> > + case UNWIND_RULE_RETAIN:
> > + fp = state->common.fp;
> > + break;
> > + /* UNWIND_USER_RULE_CFA_OFFSET not implemented on purpose */
> > + case UNWIND_RULE_CFA_OFFSET_DEREF:
> > + fp = cfa + frame.fp.offset;
> > + break;
> > + case UNWIND_RULE_REG_OFFSET:
> > + case UNWIND_RULE_REG_OFFSET_DEREF:
> > + if (!regs)
>
> if (!regs || frame.cfa.regnum > 30)
>
> > + return -EINVAL;
> > + fp = regs->regs[frame.fp.regnum];
>
> Likewise: Topmost frame check not required to access arbitrary registers?
>
> > + fp += frame.fp.offset;
> > + break;
> > + default:
> > + WARN_ON_ONCE(1);
> > + return -EINVAL;
> > + }
> > +
> > + /*
> > + * Consume RA and FP from the stack. The frame record puts FP at a lower
> > + * address than RA, so we always read FP first.
> > + */
> > + if (frame.fp.rule & UNWIND_RULE_DEREF &&
> > + !get_word(&state->common, &fp))
> > + return -EINVAL;
> > +
> > + if (frame.ra.rule & UNWIND_RULE_DEREF &&
> > + get_consume_word(&state->common, &ra))
> > + return -EINVAL;
> > +
> > + state->common.pc = ra;
> > + state->common.sp = cfa;
> > + state->common.fp = fp;
> > +
> > + state->source = source;
> > +
> > + return 0;
> > +}
> Thanks and regards,
> Jens
> --
> Jens Remus
> Linux on Z Development (D3303)
> jremus@de.ibm.com / jremus@linux.ibm.com
>
> IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
> IBM Data Privacy Statement: https://www.ibm.com/privacy/
>
Thanks,
Dylan
^ permalink raw reply
* Re: [PATCH 2/5] media: synopsys: Add support for multiple streams
From: Frank Li @ 2026-04-20 5:42 UTC (permalink / raw)
To: Guoniu Zhou
Cc: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Laurent Pinchart, linux-media, linux-kernel, devicetree, imx,
linux-arm-kernel, linux-rockchip
In-Reply-To: <20260415-csi2_imx95-v1-2-7d63f3508719@oss.nxp.com>
On Wed, Apr 15, 2026 at 11:46:53AM +0800, Guoniu Zhou wrote:
> The current driver only supports single stream operation. Add support
> for multiple concurrent streams by tracking enabled streams with a
> bitmask and only initializing the hardware once for the first stream.
>
> This enables use cases such as surround view systems where multiple
> camera streams need to be processed simultaneously through the same
> CSI-2 receiver interface.
>
> Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
> ---
> drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 45 ++++++++++++++----------
> 1 file changed, 27 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> index 46e2a4315ac2..85a2a95bf080 100644
> --- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> +++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> @@ -113,6 +113,7 @@ struct dw_mipi_csi2rx_device {
>
> enum v4l2_mbus_type bus_type;
> u32 lanes_num;
> + u64 enabled_streams;
>
> const struct dw_mipi_csi2rx_drvdata *drvdata;
> };
> @@ -528,28 +529,31 @@ static int dw_mipi_csi2rx_enable_streams(struct v4l2_subdev *sd,
> DW_MIPI_CSI2RX_PAD_SRC,
> &streams_mask);
>
It maybe simpler
u64 enabled_streams = csi2->enabled_streams;
csi2->enabled_streams |= streams_mask;
if (!enabled_stream)
return 0;
....
err:
si2->enabled_streams &= ~streams_mask;
Frank
> - ret = pm_runtime_resume_and_get(dev);
> - if (ret)
> - goto err;
> + if (!csi2->enabled_streams) {
> + ret = pm_runtime_resume_and_get(dev);
> + if (ret)
> + return ret;
>
> - ret = dw_mipi_csi2rx_start(csi2);
> - if (ret) {
> - dev_err(dev, "failed to enable CSI hardware\n");
> - goto err_pm_runtime_put;
> + ret = dw_mipi_csi2rx_start(csi2);
> + if (ret) {
> + pm_runtime_put(dev);
> + dev_err(dev, "failed to enable CSI hardware\n");
> + return ret;
> + }
> }
>
> ret = v4l2_subdev_enable_streams(remote_sd, remote_pad->index, mask);
> - if (ret)
> - goto err_csi_stop;
> + if (ret) {
> + if (!csi2->enabled_streams) {
> + dw_mipi_csi2rx_stop(csi2);
> + pm_runtime_put(dev);
> + }
> + return ret;
> + }
>
> - return 0;
> + csi2->enabled_streams |= streams_mask;
>
> -err_csi_stop:
> - dw_mipi_csi2rx_stop(csi2);
> -err_pm_runtime_put:
> - pm_runtime_put(dev);
> -err:
> - return ret;
> + return 0;
> }
>
> static int dw_mipi_csi2rx_disable_streams(struct v4l2_subdev *sd,
> @@ -572,10 +576,15 @@ static int dw_mipi_csi2rx_disable_streams(struct v4l2_subdev *sd,
> &streams_mask);
>
> ret = v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask);
> + if (ret)
> + dev_err(dev, "failed to disable streams on remote subdev: %d\n", ret);
>
> - dw_mipi_csi2rx_stop(csi2);
> + csi2->enabled_streams &= ~streams_mask;
>
> - pm_runtime_put(dev);
> + if (!csi2->enabled_streams) {
> + dw_mipi_csi2rx_stop(csi2);
> + pm_runtime_put(dev);
> + }
>
> return ret;
> }
>
> --
> 2.34.1
>
^ permalink raw reply
* Re: [PATCH v2 1/3] dt-bindings: arm: aspeed: add Anacapa EVT1 EVT2 board
From: Colin Huang @ 2026-04-20 5:41 UTC (permalink / raw)
To: Conor Dooley
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, colin.huang2
In-Reply-To: <20260409-foster-stability-f77b38c6f7a0@spud>
Conor Dooley <conor@kernel.org> 於 2026年4月9日週四 下午11:36寫道:
>
> On Thu, Apr 09, 2026 at 07:40:26PM +0800, Colin Huang wrote:
> > Document Anacapa BMC EVT1 and EVT2 compatibles.
> >
> > Signed-off-by: Colin Huang <u8813345@gmail.com>
>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> pw-bot: not-applicable
Hi
Could anyone let me know, what is my next step which I need to do?
I can't find the changed in for-next branch of
https://git.kernel.org/pub/scm/linux/kernel/git/bmc/linux.git .
Thanks.
Regard,
Colin Huang
^ permalink raw reply
* Re: [PATCH v7 1/4] KVM: arm64: PMU: Add kvm_pmu_enabled_counter_mask()
From: Akihiko Odaki @ 2026-04-20 5:27 UTC (permalink / raw)
To: Marc Zyngier
Cc: Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Catalin Marinas, Will Deacon, Kees Cook, Gustavo A. R. Silva,
Paolo Bonzini, Jonathan Corbet, Shuah Khan, linux-arm-kernel,
kvmarm, linux-kernel, linux-hardening, devel, kvm, linux-doc,
linux-kselftest
In-Reply-To: <87o6jfavhx.wl-maz@kernel.org>
On 2026/04/19 23:13, Marc Zyngier wrote:
> On Sat, 18 Apr 2026 09:14:23 +0100,
> Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
>>
>> This function will be useful to enumerate enabled counters.
>
> Consider expanding this commit message a bit. Something along the
> lines of:
>
> "Add kvm_pmu_enabled_counter_mask() as an accessor returning a 64bit
> mask of the counters enabled on a given vcpu.
>
> This will eventually be useful to iterate over the counters."
That looks better. I think I'll use that message for the next version.
Regards,
Akihiko Odaki
^ permalink raw reply
* [PATCH] drm/mediatek: Convert legacy DRM logging to drm_* helpers in mtk_dsi.c
From: Abhishek Rajput @ 2026-04-20 5:20 UTC (permalink / raw)
To: chunkuang.hu, p.zabel, airlied, simona, matthias.bgg,
angelogioacchino.delregno
Cc: dri-devel, linux-mediatek, linux-kernel, linux-arm-kernel,
abhiraj21put
Replace DRM_INFO(), DRM_WARN() and DRM_ERROR() calls in
drivers/gpu/drm/mediatek/mtk_dsi.c with the corresponding
drm_info(), drm_warn() and drm_err() helpers.
The drm_*() logging helpers take a struct drm_device * argument,
allowing the DRM core to prefix log messages with the correct device
name and instance. This is required to correctly distinguish log
messages on systems with multiple GPUs.
This change aligns the radeon driver with the DRM TODO item:
"Convert logging to drm_* functions with drm_device parameter".
Signed-off-by: Abhishek Rajput <abhiraj21put@gmail.com>
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 0e2bcd5f67b7..a67ad575f5f0 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -510,6 +510,7 @@ static void mtk_dsi_config_vdo_timing_per_line_lp(struct mtk_dsi *dsi)
u32 delta;
struct mtk_phy_timing *timing = &dsi->phy_timing;
struct videomode *vm = &dsi->vm;
+ struct drm_device *drm = dsi->bridge.dev;
if (dsi->format == MIPI_DSI_FMT_RGB565)
dsi_tmp_buf_bpp = 2;
@@ -543,7 +544,7 @@ static void mtk_dsi_config_vdo_timing_per_line_lp(struct mtk_dsi *dsi)
horizontal_backporch_byte /
horizontal_front_back_byte;
} else {
- DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
+ drm_warn(drm, "HFP + HBP less than d-phy, FPS will under 60Hz\n");
}
if ((dsi->mode_flags & MIPI_DSI_HS_PKT_END_ALIGNED) &&
@@ -623,12 +624,13 @@ static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
{
s32 ret = 0;
unsigned long jiffies = msecs_to_jiffies(timeout);
+ struct drm_device *drm = dsi->bridge.dev;
ret = wait_event_interruptible_timeout(dsi->irq_wait_queue,
dsi->irq_data & irq_flag,
jiffies);
if (ret == 0) {
- DRM_WARN("Wait DSI IRQ(0x%08x) Timeout\n", irq_flag);
+ drm_warn(drm, "Wait DSI IRQ(0x%08x) Timeout\n", irq_flag);
mtk_dsi_enable(dsi);
mtk_dsi_reset_engine(dsi);
@@ -663,9 +665,10 @@ static s32 mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi, u8 irq_flag, u32 t)
{
mtk_dsi_irq_data_clear(dsi, irq_flag);
mtk_dsi_set_cmd_mode(dsi);
+ struct drm_device *drm = dsi->bridge.dev;
if (!mtk_dsi_wait_for_irq_done(dsi, irq_flag, t)) {
- DRM_ERROR("failed to switch cmd mode\n");
+ drm_err(drm, "failed to switch cmd mode\n");
return -ETIME;
} else {
return 0;
@@ -849,11 +852,12 @@ static void mtk_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state)
{
struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+ struct drm_device *drm = bridge->dev;
int ret;
ret = mtk_dsi_poweron(dsi);
if (ret < 0)
- DRM_ERROR("failed to power on dsi\n");
+ drm_err(drm, "failed to power on dsi\n");
}
static void mtk_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge,
@@ -916,7 +920,7 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
ret = drm_simple_encoder_init(drm, &dsi->encoder,
DRM_MODE_ENCODER_DSI);
if (ret) {
- DRM_ERROR("Failed to encoder init to drm\n");
+ drm_err(drm, "Failed to encoder init to drm\n");
return ret;
}
@@ -932,7 +936,7 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
if (IS_ERR(dsi->connector)) {
- DRM_ERROR("Unable to create bridge connector\n");
+ drm_err(drm, "Unable to create bridge connector\n");
ret = PTR_ERR(dsi->connector);
goto err_cleanup_encoder;
}
@@ -985,6 +989,7 @@ static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
{
struct mtk_dsi *dsi = host_to_dsi(host);
struct device *dev = host->dev;
+ struct drm_device *drm = dsi->bridge.dev;
int ret;
dsi->lanes = device->lanes;
@@ -1012,7 +1017,7 @@ static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
ret = component_add(host->dev, &mtk_dsi_component_ops);
if (ret) {
- DRM_ERROR("failed to add dsi_host component: %d\n", ret);
+ drm_err(drm, "failed to add dsi_host component: %d\n", ret);
drm_bridge_remove(&dsi->bridge);
return ret;
}
@@ -1034,11 +1039,12 @@ static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
{
int ret;
u32 val;
+ struct drm_device *drm = dsi->bridge.dev;
ret = readl_poll_timeout(dsi->regs + DSI_INTSTA, val, !(val & DSI_BUSY),
4, 2000000);
if (ret) {
- DRM_WARN("polling dsi wait not busy timeout!\n");
+ drm_warn(drm, "polling dsi wait not busy timeout!\n");
mtk_dsi_enable(dsi);
mtk_dsi_reset_engine(dsi);
@@ -1123,6 +1129,7 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
const struct mipi_dsi_msg *msg)
{
struct mtk_dsi *dsi = host_to_dsi(host);
+ struct drm_device *drm = dsi->bridge.dev;
ssize_t recv_cnt;
u8 read_data[16];
void *src_addr;
@@ -1153,7 +1160,7 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
}
if (!msg->rx_buf) {
- DRM_ERROR("dsi receive buffer size may be NULL\n");
+ drm_err(drm, "dsi receive buffer size may be NULL\n");
ret = -EINVAL;
goto restore_dsi_mode;
}
@@ -1177,7 +1184,7 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
if (recv_cnt)
memcpy(msg->rx_buf, src_addr, recv_cnt);
- DRM_INFO("dsi get %zd byte data from the panel address(0x%x)\n",
+ drm_info(drm, "dsi get %zd byte data from the panel address(0x%x)\n",
recv_cnt, *((u8 *)(msg->tx_buf)));
restore_dsi_mode:
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] arm: kernel: add NULL pointer check in early_mem()
From: Austin Kim @ 2026-04-20 5:04 UTC (permalink / raw)
To: linux; +Cc: linux-arm-kernel, linux-kernel
In-Reply-To: <ac9Zd3K+PQTGBZAC@adminpc-PowerEdge-R7525>
2026년 4월 3일 (금) 오후 3:08, Austin Kim <austindh.kim@gmail.com>님이 작성:
>
> The 'early_mem' function handles memory-related boot parameters.
> If the parameter 'p' is passed as NULL, it could lead to an
> uninitialized or invalid memory access during parsing.
>
> This patch adds a NULL pointer check at the beginning of the
> function to return early if no argument is provided, ensuring
> system stability during the early boot process.
>
> Signed-off-by: Austin Kim <austindh.kim@gmail.com>
> ---
> arch/arm/kernel/setup.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index 0bfd66c7a..b718a7df3 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -830,6 +830,8 @@ static int __init early_mem(char *p)
> u64 start;
> char *endp;
>
> + if (!p)
> + return 1;
Hello, Maintainers
If you are available, would you please leave any comments over this patch?
BR,
Austin Kim
> /*
> * If the user specifies memory size, we
> * blow away any automatically generated
> --
> 2.34.1
>
^ permalink raw reply
* Re: [PATCH v3 7/8] sframe: Introduce in-kernel SFRAME_VALIDATION.
From: Dylan Hatch @ 2026-04-20 5:02 UTC (permalink / raw)
To: Jens Remus
Cc: Roman Gushchin, Weinan Liu, Will Deacon, Josh Poimboeuf,
Indu Bhagat, Peter Zijlstra, Steven Rostedt, Catalin Marinas,
Jiri Kosina, Mark Rutland, Prasanna Kumar T S M, Puranjay Mohan,
Song Liu, joe.lawrence, linux-toolchains, linux-kernel,
live-patching, linux-arm-kernel, Heiko Carstens
In-Reply-To: <de7bd273-3650-4378-8fd8-a51217e7284b@linux.ibm.com>
On Thu, Apr 16, 2026 at 8:04 AM Jens Remus <jremus@linux.ibm.com> wrote:
>
> Hello Dylan!
>
> On 4/6/2026 8:49 PM, Dylan Hatch wrote:
> > Generalize the __safe* helpers to support a non-user-access code path.
> > Allow for kernel FDE read failures due to the presence of .rodata.text.
> > This section contains code that can't be executed by the kernel
> > direclty, and thus lies ouside the normal kernel-text bounds.
>
> Nits: s/direclty/directly/ s/ouside/outside/
>
> Could you please explain the issue? How/why does .sframe for
> .rodata.text pose an issue for .sframe verification?
__read_fde checks that the fde_addr it extracts is within the bounds
of sec->text_start and sec->text_end. In the case of the vmlinux
.sframe section, this is _stext and _etext. However on arm64, there is
an .rodata.text section that lies outside this range. From
arch/arm64/kernel/vmlinux.lds.S:
/* code sections that are never executed via the kernel mapping */
.rodata.text : {
TRAMP_TEXT
HIBERNATE_TEXT
KEXEC_TEXT
IDMAP_TEXT
. = ALIGN(PAGE_SIZE);
}
So __read_fde fails for functions in this section. Under normal SFrame
usage for unwinding, we should never need to look up a PC value in
these functions because they will never be executed by the kernel.
However, we still hit this error when validating all FDEs.
I think ideally we might prevent sframe data from being generated for
this code (maybe from the linker script somehow?), but I don't know of
a simple way to do this. Alternatively, we can check for FDEs located
in .rodata.text during validation, but this seems to only be present
in arm64, so maybe we would need an arch-specific hook to do this? I'm
open to suggestions.
>
> > Signed-off-by: Dylan Hatch <dylanbhatch@google.com>
>
> > diff --git a/kernel/unwind/sframe.c b/kernel/unwind/sframe.c
>
> > @@ -690,6 +699,13 @@ static int sframe_validate_section(struct sframe_section *sec)
> > int ret;
> >
> > ret = safe_read_fde(sec, i, &fde);
> > + /*
> > + * Code in .rodata.text is not considered part of normal kernel
> > + * text, but there is no easy way to prevent sframe data from
> > + * being generated for it.
> > + */
> > + if (ret && sec->sec_type == SFRAME_KERNEL)
> > + continue;
> > if (ret)
> > return ret;
> >
> Thanks and regards,
> Jens
> --
> Jens Remus
> Linux on Z Development (D3303)
> jremus@de.ibm.com / jremus@linux.ibm.com
>
> IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
> IBM Data Privacy Statement: https://www.ibm.com/privacy/
>
Thanks,
Dylan
^ permalink raw reply
* Re: [PATCH 1/6] drm/connector: report IRQ_HPD events to drm_connector_oob_hotplug_event()
From: Tomi Valkeinen @ 2026-04-20 4:50 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Bjorn Andersson,
Konrad Dybcio, Pengyu Luo, Nikita Travkin, Yongxing Mou
In-Reply-To: <6z572fdjkvjqvedifwvotgdy4lcrifiqvkjpnutousjqc6764r@zepfzkqy2kbu>
Hi,
On 18/04/2026 01:32, Dmitry Baryshkov wrote:
> On Thu, Apr 16, 2026 at 11:10:03AM +0300, Tomi Valkeinen wrote:
>> Hi,
>>
>> On 16/04/2026 02:22, Dmitry Baryshkov wrote:
>>> The DisplayPort standard defines a special kind of events called IRQ.
>>> These events are used to notify DP Source about the events on the Sink
>>> side. It is extremely important for DP MST handling, where the MST
>>> events are reported through this IRQ.
>>>
>>> In case of the USB-C DP AltMode there is no actual HPD pulse, but the
>>> events are ported through the bits in the AltMode VDOs.
>>>
>>> Extend the drm_connector_oob_hotplug_event() interface and report IRQ
>>> events to the DisplayPort Sink drivers.
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
>>> ---
>>> drivers/gpu/drm/drm_connector.c | 4 +++-
>>> drivers/usb/typec/altmodes/displayport.c | 12 ++++++++----
>>> include/drm/drm_connector.h | 3 ++-
>>> 3 files changed, 13 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>>> index 47dc53c4a738..5fdacbd84bd7 100644
>>> --- a/drivers/gpu/drm/drm_connector.c
>>> +++ b/drivers/gpu/drm/drm_connector.c
>>> @@ -3510,6 +3510,7 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
>>> * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector
>>> * @connector_fwnode: fwnode_handle to report the event on
>>> * @status: hot plug detect logical state
>>> + * @irq_hpd: HPD pulse detected
>>> *
>>> * On some hardware a hotplug event notification may come from outside the display
>>> * driver / device. An example of this is some USB Type-C setups where the hardware
>>> @@ -3520,7 +3521,8 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
>>> * a drm_connector reference through calling drm_connector_find_by_fwnode().
>>> */
>>> void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
>>> - enum drm_connector_status status)
>>> + enum drm_connector_status status,
>>> + bool irq_hpd)
>> I find the "IRQ HPD" naming always confusing, even if I'm somewhat familiar
>> with DP, but if someone has mainly worked on HDMI, I'm sure it's even worse.
>>
>> Can we define this a bit more precisely? Is 'irq_hpd' only for displayport?
>> If so, perhaps 'dp_irq_hpd' or 'displayport_irq_hpd'. I might even call it
>> 'dp_hpd_pulse', but maybe that's not good as the spec talks about HPD pulse
>> for both short and long ones (although in the kernel doc you just write "HPD
>> pulse")... The kernel doc could be expanded a bit to make it clear what this
>> flag indicates.
>
> I attempted to stay away from defining a DP-specific flag, keeping it
> generic enough. HDMI is pretty close (IMO) to requiring separate flag in
If it's not specifically the DP IRQ HPD, then we need to define what it
means. I tried to think what it would mean with HDMI, but I didn't come
up with anything.
> Linux. Likewise I'd rather not use "pulse". The DP AltMode defines a bit
> in the VDO rather than a pulse.
>
> Anyway, if irq_hpd doesn't sound precise enough, what about "bool
> extra_irq"? This would convey that this is the extra hpd-related IRQ,
> but it would also be obvious that it's not related to the HPD pin
> itself.
We'd still need to define what exactly it means. I think it might be
better to just define it as the DP IRQ HPD, as then the meaning is clear.
Also, would an enum flags parameter be better than a bool parameter?
Tomi
^ permalink raw reply
* Re: [PATCH v5 4/4] Input: charlieplex_keypad: add GPIO charlieplex keypad
From: Dmitry Torokhov @ 2026-04-20 4:47 UTC (permalink / raw)
To: Hugo Villeneuve
Cc: robin, andy, geert, robh, krzk+dt, conor+dt, hvilleneuve,
mkorpershoek, matthias.bgg, angelogioacchino.delregno, lee,
alexander.sverdlin, marek.vasut, akurz, devicetree, linux-kernel,
linux-input, linux-arm-kernel, linux-mediatek
In-Reply-To: <20260312180304.3865850-5-hugo@hugovil.com>
Hi Hugo,
On Thu, Mar 12, 2026 at 02:00:58PM -0400, Hugo Villeneuve wrote:
> +
> +static void charlieplex_keypad_report_key(struct input_dev *input)
> +{
> + struct charlieplex_keypad *keypad = input_get_drvdata(input);
> + const unsigned short *keycodes = input->keycode;
> +
> + if (keypad->current_code > 0) {
> + input_event(input, EV_MSC, MSC_SCAN, keypad->current_code);
> + input_report_key(input, keycodes[keypad->current_code], 0);
This needs input_sync() as otherwise userspace is free to only recognize
the last MSC_SCAN event.
> + }
> +
> + if (keypad->debounce_code) {
> + input_event(input, EV_MSC, MSC_SCAN, keypad->debounce_code);
> + input_report_key(input, keycodes[keypad->debounce_code], 1);
> + }
> +
> + input_sync(input);
> + keypad->current_code = keypad->debounce_code;
> +}
> +
> +static void charlieplex_keypad_check_switch_change(struct input_dev *input,
> + int code)
> +{
> + struct charlieplex_keypad *keypad = input_get_drvdata(input);
> +
> + if (code != keypad->debounce_code) {
> + keypad->debounce_count = 0;
> + keypad->debounce_code = code;
> + } else if (keypad->debounce_count < keypad->debounce_threshold) {
This does not work if debouncing is disabled (debounce threshold is 0).
> + keypad->debounce_count++;
> +
> + if (keypad->debounce_count >= keypad->debounce_threshold &&
> + keypad->debounce_code != keypad->current_code)
> + charlieplex_keypad_report_key(input);
> + }
> +}
> +
> +static void charlieplex_keypad_poll(struct input_dev *input)
> +{
> + struct charlieplex_keypad *keypad = input_get_drvdata(input);
> + int code;
> +
> + code = 0;
> + for (unsigned int oline = 0; oline < keypad->nlines; oline++) {
> + DECLARE_BITMAP(values, MATRIX_MAX_ROWS);
> + int err;
> +
> + /* Activate only one line as output at a time. */
> + gpiod_direction_output(keypad->line_gpios->desc[oline], 1);
> +
> + if (keypad->settling_time_us)
> + fsleep(keypad->settling_time_us);
> +
> + /* Read input on all other lines. */
> + err = gpiod_get_array_value_cansleep(keypad->line_gpios->ndescs,
> + keypad->line_gpios->desc,
> + keypad->line_gpios->info, values);
> + if (err)
> + return;
We need to deactivate the line on error too.
> +
> + for (unsigned int iline = 0; iline < keypad->nlines; iline++) {
> + if (iline == oline)
> + continue; /* Do not read active output line. */
> +
> + /* Check if GPIO is asserted. */
> + if (test_bit(iline, values)) {
> + code = MATRIX_SCAN_CODE(oline, iline,
> + get_count_order(keypad->nlines));
> + /*
> + * Exit loop immediately since we cannot detect
> + * more than one key press at a time.
> + */
> + break;
> + }
> + }
> +
> + gpiod_direction_input(keypad->line_gpios->desc[oline]);
> +
> + if (code)
> + break;
> + }
> +
> + charlieplex_keypad_check_switch_change(input, code);
> +}
> +
> +static int charlieplex_keypad_init_gpio(struct platform_device *pdev,
> + struct charlieplex_keypad *keypad)
> +{
> + char **pin_names;
> + char label[32];
> +
> + snprintf(label, sizeof(label), "%s-pin", pdev->name);
> +
> + keypad->line_gpios = devm_gpiod_get_array(&pdev->dev, "line", GPIOD_IN);
> + if (IS_ERR(keypad->line_gpios))
> + return PTR_ERR(keypad->line_gpios);
> +
> + keypad->nlines = keypad->line_gpios->ndescs;
> +
> + if (keypad->nlines > MATRIX_MAX_ROWS)
> + return -EINVAL;
> +
> + pin_names = devm_kasprintf_strarray(&pdev->dev, label, keypad->nlines);
> + if (IS_ERR(pin_names))
> + return PTR_ERR(pin_names);
> +
> + for (unsigned int i = 0; i < keypad->line_gpios->ndescs; i++)
> + gpiod_set_consumer_name(keypad->line_gpios->desc[i], pin_names[i]);
> +
> + return 0;
> +}
> +
> +static int charlieplex_keypad_probe(struct platform_device *pdev)
> +{
> + struct charlieplex_keypad *keypad;
> + unsigned int debounce_interval_ms;
> + unsigned int poll_interval_ms;
> + struct input_dev *input_dev;
> + int err;
> +
> + keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
> + if (!keypad)
> + return -ENOMEM;
> +
> + input_dev = devm_input_allocate_device(&pdev->dev);
> + if (!input_dev)
> + return -ENOMEM;
> +
> + keypad->input_dev = input_dev;
> +
> + device_property_read_u32(&pdev->dev, "poll-interval", &poll_interval_ms);
> + device_property_read_u32(&pdev->dev, "debounce-delay-ms", &debounce_interval_ms);
> + device_property_read_u32(&pdev->dev, "settling-time-us", &keypad->settling_time_us);
Not all of these are required properties. If they are missing the driver
will operate on garbage values.
> +
> + keypad->current_code = -1;
> + keypad->debounce_code = -1;
> + keypad->debounce_threshold = DIV_ROUND_UP(debounce_interval_ms, poll_interval_ms);
This will bomb if poll interval is 0.
> +
> + err = charlieplex_keypad_init_gpio(pdev, keypad);
> + if (err)
> + return err;
> +
> + input_dev->name = pdev->name;
> + input_dev->id.bustype = BUS_HOST;
> +
> + err = matrix_keypad_build_keymap(NULL, NULL, keypad->nlines,
> + keypad->nlines, NULL, input_dev);
> + if (err)
> + dev_err_probe(&pdev->dev, -ENOMEM, "failed to build keymap\n");
Missing "return".
> +
> + if (device_property_read_bool(&pdev->dev, "autorepeat"))
> + __set_bit(EV_REP, input_dev->evbit);
> +
> + input_set_capability(input_dev, EV_MSC, MSC_SCAN);
> +
> + err = input_setup_polling(input_dev, charlieplex_keypad_poll);
> + if (err)
> + dev_err_probe(&pdev->dev, err, "unable to set up polling\n");
Missing "return".
I fixed it up and applied, please take a look in my 'next' branch and
tell me if I messed up.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v2 4/4] arm64: dts: amlogic: t7: Add clk measure support
From: Jian Hu @ 2026-04-20 3:25 UTC (permalink / raw)
To: Ronald Claveau
Cc: devicetree, linux-arm-kernel, linux-amlogic, linux-kernel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Neil Armstrong,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl
In-Reply-To: <ae61c52d-814c-40fa-b02a-833377d840a8@aliel.fr>
Hi Ronald,
Thanks for your review.
On 4/17/2026 5:48 PM, Ronald Claveau wrote:
> [ EXTERNAL EMAIL ]
>
> Hello Jian,
>
> On 4/15/26 10:33 AM, Jian Hu via B4 Relay wrote:
>> From: Jian Hu <jian.hu@amlogic.com>
>>
>> Add the clock measure device to the T7 SoC family.
>>
>> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
>> ---
>> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 5 +++++
>> 1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
>> index 7fe72c94ed62..cec2ea74850d 100644
>> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
>> @@ -701,6 +701,11 @@ pwm_ao_cd: pwm@60000 {
>> status = "disabled";
>> };
>>
>> + clock-measurer@48000 {
>> + compatible = "amlogic,t7-clk-measure";
>> + reg = <0x0 0x48000 0x0 0x1c>;
>> + };
>> +
> Can you please order by reg, it should be between pwm_ao_gh and pwm_ab.
> Thank you.
According to the "Order of Nodes" chapter in
Documentation/devicetree/bindings/dts-coding-style.rst,
nodes of the same type should be grouped together, and this takes higher
priority.
So I have placed the clock-measure node after all PWM nodes to avoid
splitting the PWM group.
Best regards,
Jian
^ permalink raw reply
* Re: [PATCH] net: lpc_eth: Fix a possible memory leak in lpc_mii_probe()
From: Ma Ke @ 2026-04-20 3:24 UTC (permalink / raw)
To: vz
Cc: alexandre.belloni, andrew+netdev, davem, edumazet, kuba,
linux-arm-kernel, linux-kernel, make24, netdev, pabeni,
piotr.wojtaszczyk, stable
In-Reply-To: <60dea9e5-9890-49ab-b806-713c388d6e08@mleia.com>
>Hello Ma Ke.
>
>On 4/1/26 16:18, Ma Ke wrote:
>> On 3/30/26 13:04, Vladimir Zapolskiy wrote:
>>> On 3/30/26 11:16, Ma Ke wrote:
>>>> lpc_mii_probe() calls of_phy_find_device() to obtain a phy_device
>>>> pointer. of_phy_find_device() increments the refcount of the device.
>>>> The current implementation does not decrement the refcount after using
>>>> the pointer, which leads to a memory leak.
>>>
>>> this is correct, there is an actual detected bug.
>>>
>>>>
>>>> Add phy_device_free() to balance the refcount.
>>>
>>> But this does not sound right, you shoud use of_node_put(pldat->phy_node).
>>>
>>>>
>>>> Found by code review.
>>>>
>>>> Signed-off-by: Ma Ke <make24@iscas.ac.cn>
>>>> Cc: stable@vger.kernel.org
>>>> Fixes: 3503bf024b3e ("net: lpc_eth: parse phy nodes from device tree")
>>>> ---
>>>> drivers/net/ethernet/nxp/lpc_eth.c | 11 ++++++-----
>>>> 1 file changed, 6 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
>>>> index 8b9a3e3bba30..8ce7c9bb6dd6 100644
>>>> --- a/drivers/net/ethernet/nxp/lpc_eth.c
>>>> +++ b/drivers/net/ethernet/nxp/lpc_eth.c
>>>> @@ -751,7 +751,7 @@ static void lpc_handle_link_change(struct net_device *ndev)
>>>> static int lpc_mii_probe(struct net_device *ndev)
>>>> {
>>>> struct netdata_local *pldat = netdev_priv(ndev);
>>>> - struct phy_device *phydev;
>>>> + struct phy_device *phydev, *phydev_tmp;
>>>>
>>>> /* Attach to the PHY */
>>>> if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII)
>>>> @@ -760,17 +760,18 @@ static int lpc_mii_probe(struct net_device *ndev)
>>>> netdev_info(ndev, "using RMII interface\n");
>>>>
>>>> if (pldat->phy_node)
>>>> - phydev = of_phy_find_device(pldat->phy_node);
>>>> + phydev_tmp = of_phy_find_device(pldat->phy_node);
>>>> else
>>>> - phydev = phy_find_first(pldat->mii_bus);
>>>> - if (!phydev) {
>>>> + phydev_tmp = phy_find_first(pldat->mii_bus);
>>>> + if (!phydev_tmp) {
>>>
>>> I didn't get it, why the new phydev_tmp is needed above, please
>>> restore the original code above.
>>>
>>>> netdev_err(ndev, "no PHY found\n");
>>>> return -ENODEV;
>>>> }
>>>>
>>>> - phydev = phy_connect(ndev, phydev_name(phydev),
>>>> + phydev = phy_connect(ndev, phydev_name(phydev_tmp),
>>>> &lpc_handle_link_change,
>>>> lpc_phy_interface_mode(&pldat->pdev->dev));
>>>> + phy_device_free(phydev_tmp);
>>>
>>> This is plainly wrong and has to be dropped or changed to
>>>
>>> if (pldat->phy_node)
>>> of_node_put(pldat->phy_node);
>>>
>>>> if (IS_ERR(phydev)) {
>>>> netdev_err(ndev, "Could not attach to PHY\n");
>>>> return PTR_ERR(phydev);
>>>
>>> Is it AI generated fix or what?.. The change looks bad, it introduces
>>> more severe issues than it fixes.
>>>
>>> If you think you cannot create a proper change, let me know.
>>>
>> Thank you very much for your detailed review and guidance.
>>
>> Now I think your point probably is: you are saying that the real leak
>> is not from of_phy_find_device(), but from the device node
>
>I was pretty indelicate in my comment, let's split the change into parts.
>
>1) I still do not understand, why phydev_tmp is introduced, please explain
>or remove this part of the change;
>
>2) phydev = of_phy_find_device() requires phy_device_free(phydev), but
>I do not see why phy_find_first() requires it, while it was added in your
>change.
>
>Let's start from resolving these two points.
>
>> pldat->phy_node which was obtained earlier (probably by
>> of_parse_phandle()) and never freed by of_node_put(). And you suggest
>> to add of_node_put(pldat->phy_node) instead of my wrong
>> phy_device_free().
>>
>> However, I am still a little confused. In lpc_mii_probe(),
>> of_phy_find_device() is called. From my understanding, this function
>> increases the reference count of the device. To balance it, I thought
>> phy_device_free() (which calls put_device()) should be used.
>>
>> Could you please kindly advise the correct patch? I will follow your
>> guidance and submit a proper fix.
>>
>> I apologize again for my previous wrong patch. Thank you very much for
>> your help.
>
> --
> Best wishes,
> Vladimir
Hello Vladimir,
Thank you for the detailed explanation and for pointing out my mistakes.
> 1) I still do not understand, why phydev_tmp is introduced, please explain
> or remove this part of the change;
I added phydev_tmp because I thought I needed to keep the original
phy_device pointer for releasing after phy_connect(). But as you
implied, it's perhaps unnecessary and only makes the code less
readable. I will drop this change completely in the next version.
> 2) phydev = of_phy_find_device() requires phy_device_free(phydev), but
> I do not see why phy_find_first() requires it, while it was added in your
> change.
You are absolutely right. I mistakenly assumed that both functions
return a reference-counted pointer. phy_find_first() does not
increment the refcount, so calling phy_device_free() on it is wrong
and dangerous. My patch introduced a new bug there.
Now I understand that only the of_phy_find_device() branch needs a
corresponding put_device(). I will prepare a corrected patch that only
releases the reference in that specific path (including on the error
path after phy_connect() failure). I will also look at the phy_node
reference leak you hinted at.
Thank you again for your guidance. I will send a v2 after fixing it
properly.
Best regards,
Ma Ke
^ permalink raw reply
* Re: [PATCH v7 3/6] drm/bridge: simple: Add the Lontium LT8711UXD DP-to-HDMI bridge
From: Dmitry Baryshkov @ 2026-04-20 3:06 UTC (permalink / raw)
To: Dennis Gilmore
Cc: Alexey Charkov, Andrew Lunn, Andrzej Hajda, Chaoyi Chen,
Conor Dooley, David Airlie, devicetree, dri-devel, FUKAUMI Naoki,
Heiko Stuebner, Hsun Lai, Jernej Skrabec, Jimmy Hon, John Clark,
Jonas Karlman, Krzysztof Kozlowski, Laurent Pinchart,
linux-arm-kernel, linux-kernel, linux-rockchip, Maarten Lankhorst,
Maxime Ripard, Michael Opdenacker, Michael Riesch, Mykola Kvach,
Neil Armstrong, Peter Robinson, Quentin Schulz, Robert Foss,
Rob Herring, Simona Vetter, Thomas Zimmermann
In-Reply-To: <20260414214104.1363987-4-dennis@ausil.us>
On Tue, Apr 14, 2026 at 04:40:54PM -0500, Dennis Gilmore wrote:
> The Lontium LT8711UXD is a high performance two lane Type-C/DP1.4
> to HDMI2.0 converter, designed to connect a USB Type-C source or
> a DP1.4 source to an HDMI2.0 sink.
>
> Signed-off-by: Dennis Gilmore <dennis@ausil.us>
> ---
> drivers/gpu/drm/bridge/simple-bridge.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* RE: [PATCH V13 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
From: Sherry Sun @ 2026-04-20 2:59 UTC (permalink / raw)
To: Bjorn Helgaas, mani@kernel.org
Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
Frank Li, s.hauer@pengutronix.de, kernel@pengutronix.de,
festevam@gmail.com, lpieralisi@kernel.org, kwilczynski@kernel.org,
bhelgaas@google.com, Hongxing Zhu, l.stach@pengutronix.de,
imx@lists.linux.dev, linux-pci@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20260417195533.GA92707@bhelgaas>
> On Fri, Apr 17, 2026 at 03:17:16AM +0000, Sherry Sun wrote:
> > > On Thu, Apr 16, 2026 at 07:14:12PM +0800, Sherry Sun wrote:
> > > > Introduce generic helper functions to parse Root Port device tree
> > > > nodes and extract common properties like reset GPIOs. This allows
> > > > multiple PCI host controller drivers to share the same parsing
> > > > logic.
> > > >
> > > > Define struct pci_host_port to hold common Root Port properties
> > > > (currently only reset GPIO descriptor) and add
> > > > pci_host_common_parse_ports() to parse Root Port nodes from device
> > > > tree.
> > >
> > > Are the Root Port and the RC the only possible places for 'reset'
> > > GPIO descriptions in DT? I think PERST# routing is outside the PCIe
> > > spec, so it seems like a system could provide a PERST# GPIO routed
> > > to any Switch Upstream Port or Endpoint (I assume a PERST# connected
> > > to a switch would apply to both the upstream port and the downstream
> > > ports).
> >
> > Thanks for the feedback. You're right that PERST# routing could
> > theoretically be connected to any device in the hierarchy. However,
> > for this patch series, I've focused on the most common use case in
> > practice: use Root Port level PERST# instead of the legacy Root
> > Complex level PERST#.
> >
> > Root Port level PERST# - This is the primary target, where each Root
> > Port has individual control over devices connected to it. RC level
> > PERST# - Legacy binding support, where a single GPIO controls all
> > ports.
> >
> > We can extend this framework later if real hardware emerges that needs
> > Switch or EP-level PERST# control. I can add a comment documenting
> > this limitation if needed.
> >
> > BTW, Mani and Rob had some great discussions in dt-schema about PERST#
> > and WAKE# sideband signals settings.
>
> > You can check here:
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> > ub.com%2Fdevicetree-org%2Fdt-
> schema%2Fissues%2F168&data=05%7C02%7Csher
> >
> ry.sun%40nxp.com%7Cd68515fdc0f842ac82d708de9cbb4b2e%7C686ea1d3bc
> 2b4c6f
> >
> a92cd99c5c301635%7C0%7C0%7C639120525411363026%7CUnknown%7CTW
> FpbGZsb3d8
> >
> eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIj
> oiTW
> >
> FpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=ISzWCMSwqYBdw5w%2
> BDB5ERK51Dr
> > Tf2jzGtGh3wKNCMZ8%3D&reserved=0
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> > ub.com%2Fdevicetree-org%2Fdt-
> schema%2Fpull%2F126&data=05%7C02%7Csherry
> > .sun%40nxp.com%7Cd68515fdc0f842ac82d708de9cbb4b2e%7C686ea1d3bc
> 2b4c6fa9
> >
> 2cd99c5c301635%7C0%7C0%7C639120525411380537%7CUnknown%7CTWFp
> bGZsb3d8ey
> >
> JFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiT
> WFp
> >
> bCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=5cohkQIgl0CDlrOmD0dDIbj
> Q3%2BVg
> > VOhiOMDRQD1iwLM%3D&reserved=0
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> > ub.com%2Fdevicetree-org%2Fdt-
> schema%2Fpull%2F170&data=05%7C02%7Csherry
> > .sun%40nxp.com%7Cd68515fdc0f842ac82d708de9cbb4b2e%7C686ea1d3bc
> 2b4c6fa9
> >
> 2cd99c5c301635%7C0%7C0%7C639120525411391138%7CUnknown%7CTWFp
> bGZsb3d8ey
> >
> JFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiT
> WFp
> >
> bCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=WtjyGdvt4s84HynGc3%2F0
> K3UfkZii
> > naNAW1ypEd%2B11RY%3D&reserved=0
>
> The upshot of all those conversations is that WAKE# and PERST# can be
> routed to arbitrary devices independent of the PCI topology.
>
> I think extending host-generic to look for 'reset' in Root Port nodes is the right
> thing. My concern is more about where we store it. This patch saves it in a
> new "pci_host_port" struct, but someday we'll want a place to save the
> PERST# GPIOs for several slots behind a switch.
> Then we'll have two different ways to save the same information.
>
> WAKE# signals might be more pertinent -- we definitely need to support
> multiple WAKE# signals below a single Root Port, and it seems like PERST#
> and WAKE# GPIOs should be saved the same place.
>
> I'm wondering if both should go in the pci_dev itself. I guess the implication
> is that a pci_dev->reset GPIO would describe a PERST# connected to the
> device *below* the pci_dev, at least for Downstream Ports.
Hi Bjorn,
Ok, understand your concern, currently I've defined the struct pci_host_port to
store the common Root Port properties and added the list of 'ports' to struct
pci_host_bridge.
I will let @mani to comment and see if this is the appropriate place to store
these info, or if we should store them in struct pci_dev. Mani, can you please help?
But for now, the motivation for this patch is that many PCI host controller drivers
currently share the same requirement: extracting common Root Port properties like
reset GPIOs (at least currently in many drivers, perst is placed in the root port). We
introduce generic helper functions to parse the Root Port t device tree nodes and extract
these properties so that multiple PCI drivers can share the same parsing logic. I'm not
sure if we should take a step forward here anyway?
Best Regards
Sherry
>
> I don't know about WAKE# signals. When it's in a connector, there's probably
> only a single possible WAKE# per Downstream Port. But is it possible have
> multiple WAKE# signals from a multi-function device that's on the
> motherboard? Saving the WAKE# GPIO in the Downstream Port wouldn't
> accommodate that case.
^ permalink raw reply
* RE: [EXT] Re: [PATCH v2] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Zhipeng Wang @ 2026-04-20 2:26 UTC (permalink / raw)
To: Daniel Baluta (OSS), Marco Felsch
Cc: ulfh@kernel.org, Frank Li, s.hauer@pengutronix.de,
imx@lists.linux.dev, linux-pm@vger.kernel.org, Xuegang Liu,
Jindong Yue, linux-kernel@vger.kernel.org, kernel@pengutronix.de,
festevam@gmail.com, linux-arm-kernel@lists.infradead.org
In-Reply-To: <d44a60ff-c8a3-4347-9199-def61e855066@oss.nxp.com>
> -----Original Message-----
> From: Daniel Baluta (OSS) <daniel.baluta@oss.nxp.com>
> Sent: 2026年4月16日 14:04
> To: Zhipeng Wang <zhipeng.wang_1@nxp.com>; Marco Felsch
> <m.felsch@pengutronix.de>
> Cc: ulfh@kernel.org; Frank Li <frank.li@nxp.com>; s.hauer@pengutronix.de;
> imx@lists.linux.dev; linux-pm@vger.kernel.org; Xuegang Liu
> <xuegang.liu@nxp.com>; Jindong Yue <jindong.yue@nxp.com>;
> linux-kernel@vger.kernel.org; kernel@pengutronix.de; festevam@gmail.com;
> linux-arm-kernel@lists.infradead.org
> Subject: Re: [EXT] Re: [PATCH v2] pmdomain: imx: Make IMX8M/IMX9
> BLK_CTRL tristate
>
> On 4/14/26 04:59, Zhipeng Wang wrote:
> > > On 26-04-13, Zhipeng Wang wrote:
> >>> Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate to
> >>> allow building as loadable modules.
> >> Out of curiosity, why do you want to have a PM driver to be buildable
> >> as module?
> >>
> >> Regards,
> >> Marco
> >>
> > Hi Marco,
> >
> > Thank you for your question.
> >
> > The primary motivation is to support Google's GKI (Generic Kernel
> > Image) requirement for Android devices.
> >
> > GKI separates the kernel into two parts:
> > 1. A unified kernel image (GKI) that is common across all Android
> > devices 2. Vendor-specific drivers that must be built as loadable
> > modules
> >
> > Under the GKI architecture, SoC-specific drivers like IMX8M/IMX9
> > BLK_CTRL cannot be built into the core kernel image. Instead, they
> > must be loadable modules that vendors can ship separately. This allows:
> >
> > - A single kernel binary to support multiple hardware platforms
> > - Vendors to update their drivers independently without rebuilding the
> > entire kernel
> > - Better compliance with Android's kernel update and security policies
> >
> Can you please add the below line in the commit message?
Hi Daniel,
Thank you! V4 sent.
BRs,
Zhipeng
> > For i.MX8M/i.MX9 devices running Android with GKI kernels, the
> > BLK_CTRL drivers need to be loaded as modules during boot. Without
> > tristate support, these devices cannot properly initialize their power
> > domains, making them non-functional under GKI.
>
^ permalink raw reply
* [PATCH v4] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Zhipeng Wang @ 2026-04-20 2:22 UTC (permalink / raw)
To: ulfh, Frank.Li, s.hauer
Cc: kernel, festevam, linux-pm, imx, linux-arm-kernel, linux-kernel,
xuegang.liu, jindong.yue
Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate
to allow building as loadable modules.
This change is required to support Android devices using Generic Kernel
Image (GKI) kernels, where SoC-specific drivers must be built as loadable
modules rather than built into the core kernel image.
For i.MX8M and i.MX9 devices running Android with GKI kernels, the
BLK_CTRL drivers therefore need to be loadable. Without tristate
support, power domains cannot be initialized correctly, making these
systems non-functional under GKI.
Add prompt strings to make these options visible and configurable
in menuconfig, keeping them enabled by default on appropriate platforms.
Also remove the IMX_GPCV2_PM_DOMAINS dependency from IMX9_BLK_CTRL.
This dependency was incorrect from the beginning because i.MX93 uses a
different power domain architecture compared to i.MX8M series:
- i.MX8M uses GPCv2 (General Power Controller v2) for power domain
management, hence IMX8M_BLK_CTRL correctly depends on it.
- i.MX93 uses BLK_CTRL directly without GPCv2. The hardware doesn't
have GPCv2 at all.
Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
Changes in v4:
- No functional changes
- Added detailed explanation about GKI (Generic Kernel Image) requirement
in the commit message to clarify why tristate support is needed for
Android devices
Changes in v3:
- No functional changes
- Fixed typo reported by Frank
- Added Reviewed-by tag from Frank Li
Changes in v2:
- No functional changes
- Expanded commit message to explain the architectural differences between
i.MX8M and i.MX93 power domain management
- Clarified why IMX_GPCV2_PM_DOMAINS dependency removal is correct for
i.MX93
---
drivers/pmdomain/imx/Kconfig | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/pmdomain/imx/Kconfig b/drivers/pmdomain/imx/Kconfig
index 00203615c65e..9168d183b0c5 100644
--- a/drivers/pmdomain/imx/Kconfig
+++ b/drivers/pmdomain/imx/Kconfig
@@ -10,15 +10,18 @@ config IMX_GPCV2_PM_DOMAINS
default y if SOC_IMX7D
config IMX8M_BLK_CTRL
- bool
- default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
+ tristate "i.MX8M BLK CTRL driver"
+ depends on SOC_IMX8M
+ depends on IMX_GPCV2_PM_DOMAINS
depends on PM_GENERIC_DOMAINS
depends on COMMON_CLK
+ default y
config IMX9_BLK_CTRL
- bool
- default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
+ tristate "i.MX93 BLK CTRL driver"
+ depends on SOC_IMX9
depends on PM_GENERIC_DOMAINS
+ default y
config IMX_SCU_PD
bool "IMX SCU Power Domain driver"
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] drm/bridge: imx8qxp-pxl2dpi: avoid of_node_put() on ERR_PTR()
From: Guangshuo Li @ 2026-04-20 2:19 UTC (permalink / raw)
To: Frank Li
Cc: Liu Ying, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Luca Ceresoli, dri-devel, imx, linux-arm-kernel,
linux-kernel, stable
In-Reply-To: <aeWHyhp43ZbgXwFe@lizhi-Precision-Tower-5810>
Hi Frank,
Thanks for the review.
On Mon, 20 Apr 2026 at 09:56, Frank Li <Frank.li@nxp.com> wrote:
>
>
> Please fix
> DEFINE_FREE(device_node, struct device_node *, if (_T) of_node_put(_T))
>
> If (!IS_ERR(_T))
>
You're right, fixing DEFINE_FREE(device_node, ...) is the proper way
to handle this:
if (_T && !IS_ERR(_T)) of_node_put(_T)
This is a better fix than handling it only in this driver.
I'll rework the patch based on your suggestion and send v2 later.
Thanks,
Guangshuo
^ permalink raw reply
* Re: [PATCH 0/3] mm: split the file's i_mmap tree for NUMA
From: Huang Shijie @ 2026-04-20 2:10 UTC (permalink / raw)
To: Mateusz Guzik
Cc: akpm, viro, brauner, linux-mm, linux-kernel, linux-arm-kernel,
linux-fsdevel, muchun.song, osalvador, linux-trace-kernel,
linux-perf-users, linux-parisc, nvdimm, zhongyuan, fangbaoshun,
yingzhiwei
In-Reply-To: <76pfiwabdgsej6q2yxfh3efuqvsyg7mt7rvl5itzzjyhdrto5r@53viaxsackzv>
On Mon, Apr 13, 2026 at 05:33:21PM +0200, Mateusz Guzik wrote:
> On Mon, Apr 13, 2026 at 02:20:39PM +0800, Huang Shijie wrote:
> > In NUMA, there are maybe many NUMA nodes and many CPUs.
> > For example, a Hygon's server has 12 NUMA nodes, and 384 CPUs.
> > In the UnixBench tests, there is a test "execl" which tests
> > the execve system call.
> >
> > When we test our server with "./Run -c 384 execl",
> > the test result is not good enough. The i_mmap locks contended heavily on
> > "libc.so" and "ld.so". For example, the i_mmap tree for "libc.so" can have
> > over 6000 VMAs, all the VMAs can be in different NUMA mode.
> > The insert/remove operations do not run quickly enough.
> >
> > patch 1 & patch 2 are try to hide the direct access of i_mmap.
> > patch 3 splits the i_mmap into sibling trees, and we can get better
> > performance with this patch set:
> > we can get 77% performance improvement(10 times average)
> >
>
> To my reading you kept the lock as-is and only distributed the protected
> state.
>
> While I don't doubt the improvement, I'm confident should you take a
> look at the profile you are going to find this still does not scale with
> rwsem being one of the problems (there are other global locks, some of
> which have experimental patches for).
>
> Apart from that this does nothing to help high core systems which are
> all one node, which imo puts another question mark on this specific
> proposal.
>
> Of course one may question whether a RB tree is the right choice here,
> it may be the lock-protected cost can go way down with merely a better
> data structure.
>
> Regardless of that, for actual scalability, there will be no way around
> decentralazing locking around this and partitioning per some core count
> (not just by numa awareness).
>
> Decentralizing locking is definitely possible, but I have not looked
> into specifics of how problematic it is. Best case scenario it will
> merely with separate locks. Worst case scenario something needs a fully
> stabilized state for traversal, in that case another rw lock can be
> slapped around this, creating locking order read lock -> per-subset
> write lock -- this will suffer scalability due to the read locking, but
> it will still scale drastically better as apart from that there will be
> no serialization. In this setting the problematic consumer will write
> lock the new thing to stabilize the state.
>
I thought over again.
I can change this patch set to support the non-NUMA case by:
1.) Still use one rw lock.
2.) For NUMA, keep the patch set as it is.
3.) For non-NUMA case, split the i_mmap tree to several subtrees.
For example, if a machine has 192 CPUs, split the 32 CPUs as a tree.
So extend the patch set to support both the NUMA and non-NUMA machines.
Thanks
Huang Shijie
^ permalink raw reply
* Re: [PATCH] Input: imx_keypad - Fix spelling mistake "Colums" -> "Columns"
From: Frank Li @ 2026-04-20 1:57 UTC (permalink / raw)
To: Ethan Carter Edwards
Cc: Dmitry Torokhov, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, linux-input, imx, linux-arm-kernel, linux-kernel,
kernel-janitors
In-Reply-To: <20260418-imx-typo-v1-1-2a15e54ad4e7@ethancedwards.com>
On Sat, Apr 18, 2026 at 08:58:32PM -0400, Ethan Carter Edwards wrote:
> There is a spelling mistake in a two comments. Fix them.
>
> Signed-off-by: Ethan Carter Edwards <ethan@ethancedwards.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/input/keyboard/imx_keypad.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
> index 069c1d6376e1..ccde60cd6bb3 100644
> --- a/drivers/input/keyboard/imx_keypad.c
> +++ b/drivers/input/keyboard/imx_keypad.c
> @@ -324,7 +324,7 @@ static void imx_keypad_config(struct imx_keypad *keypad)
> reg_val |= (keypad->cols_en_mask & 0xff) << 8; /* cols */
> writew(reg_val, keypad->mmio_base + KPCR);
>
> - /* Write 0's to KPDR[15:8] (Colums) */
> + /* Write 0's to KPDR[15:8] (Columns) */
> reg_val = readw(keypad->mmio_base + KPDR);
> reg_val &= 0x00ff;
> writew(reg_val, keypad->mmio_base + KPDR);
> @@ -357,7 +357,7 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad)
> reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;
> writew(reg_val, keypad->mmio_base + KPSR);
>
> - /* Colums as open drain and disable all rows */
> + /* Columns as open drain and disable all rows */
> reg_val = (keypad->cols_en_mask & 0xff) << 8;
> writew(reg_val, keypad->mmio_base + KPCR);
> }
>
> ---
> base-commit: c7275b05bc428c7373d97aa2da02d3a7fa6b9f66
> change-id: 20260418-imx-typo-14370bd2ce47
>
> Best regards,
> --
> Ethan Carter Edwards <ethan@ethancedwards.com>
>
^ permalink raw reply
* Re: [PATCH] drm/bridge: imx8qxp-pxl2dpi: avoid of_node_put() on ERR_PTR()
From: Frank Li @ 2026-04-20 1:56 UTC (permalink / raw)
To: Guangshuo Li
Cc: Liu Ying, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Luca Ceresoli, dri-devel, imx, linux-arm-kernel,
linux-kernel, stable
In-Reply-To: <20260419122134.97529-1-lgs201920130244@gmail.com>
On Sun, Apr 19, 2026 at 08:21:34PM +0800, Guangshuo Li wrote:
> imx8qxp_pxl2dpi_get_available_ep_from_port() may return ERR_PTR(-ENODEV)
> or ERR_PTR(-EINVAL). imx8qxp_pxl2dpi_find_next_bridge() stores that
> value in a __free(device_node) variable and then immediately checks
> IS_ERR(ep).
>
> On the error path, returning from the function triggers the cleanup
> handler for __free(device_node). Since the device_node cleanup helper
> only checks for NULL before calling of_node_put(), this results in
> of_node_put(ERR_PTR(...)), which may lead to an invalid kobject_put()
Please fix
DEFINE_FREE(device_node, struct device_node *, if (_T) of_node_put(_T))
If (!IS_ERR(_T))
Frank
> dereference and crash the kernel.
>
> Fix it by avoiding __free(device_node) for the endpoint pointer and
> releasing it explicitly after obtaining the remote port parent.
>
> This issue was found by a custom static analysis tool.
>
> Fixes: ceea3f7806a10 ("drm/bridge: imx8qxp-pxl2dpi: simplify put of device_node pointers")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> ---
> drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c
> index 441fd32dc91c..3610ca94a8e6 100644
> --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c
> +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c
> @@ -264,12 +264,15 @@ imx8qxp_pxl2dpi_get_available_ep_from_port(struct imx8qxp_pxl2dpi *p2d,
>
> static int imx8qxp_pxl2dpi_find_next_bridge(struct imx8qxp_pxl2dpi *p2d)
> {
> - struct device_node *ep __free(device_node) =
> - imx8qxp_pxl2dpi_get_available_ep_from_port(p2d, 1);
> + struct device_node *ep;
> +
> + ep = imx8qxp_pxl2dpi_get_available_ep_from_port(p2d, 1);
> if (IS_ERR(ep))
> return PTR_ERR(ep);
>
> struct device_node *remote __free(device_node) = of_graph_get_remote_port_parent(ep);
> + of_node_put(ep);
> +
> if (!remote || !of_device_is_available(remote)) {
> DRM_DEV_ERROR(p2d->dev, "no available remote\n");
> return -ENODEV;
> --
> 2.43.0
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox