* [PATCH] ASoC: sun4i-spdif: Use guard() for spin locks
From: phucduc.bui @ 2026-05-13 10:50 UTC (permalink / raw)
To: Mark Brown
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Marcus Cooper, Chen Ni,
linux-sound, linux-sunxi, linux-arm-kernel, linux-kernel,
bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Clean up the code using guard() for spin locks.
Merely code refactoring, and no behavior change.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/sunxi/sun4i-spdif.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index c2ec19437cd7..ec00779182db 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -427,10 +427,9 @@ static int sun4i_spdif_get_status(struct snd_kcontrol *kcontrol,
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
struct sun4i_spdif_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
u8 *status = ucontrol->value.iec958.status;
- unsigned long flags;
unsigned int reg;
- spin_lock_irqsave(&host->lock, flags);
+ guard(spinlock_irqsave)(&host->lock);
regmap_read(host->regmap, SUN4I_SPDIF_TXCHSTA0, ®);
@@ -444,8 +443,6 @@ static int sun4i_spdif_get_status(struct snd_kcontrol *kcontrol,
status[4] = reg & 0xff;
status[5] = (reg >> 8) & 0x3;
- spin_unlock_irqrestore(&host->lock, flags);
-
return 0;
}
@@ -455,11 +452,10 @@ static int sun4i_spdif_set_status(struct snd_kcontrol *kcontrol,
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
struct sun4i_spdif_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
u8 *status = ucontrol->value.iec958.status;
- unsigned long flags;
unsigned int reg;
bool chg0, chg1;
- spin_lock_irqsave(&host->lock, flags);
+ guard(spinlock_irqsave)(&host->lock);
reg = (u32)status[3] << 24;
reg |= (u32)status[2] << 16;
@@ -483,8 +479,6 @@ static int sun4i_spdif_set_status(struct snd_kcontrol *kcontrol,
SUN4I_SPDIF_TXCFG_CHSTMODE |
SUN4I_SPDIF_TXCFG_NONAUDIO, reg);
- spin_unlock_irqrestore(&host->lock, flags);
-
return chg0 || chg1;
}
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v4 1/2] firmware: smccc: coco: Manage arm-smccc platform device and CCA auxiliary drivers
From: Catalin Marinas @ 2026-05-13 10:47 UTC (permalink / raw)
To: Aneesh Kumar K.V
Cc: linux-kernel, linux-arm-kernel, Greg KH, Jeremy Linton,
Jonathan Cameron, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
Will Deacon, Suzuki K Poulose
In-Reply-To: <yq5aa4u3u7aq.fsf@kernel.org>
On Wed, May 13, 2026 at 12:26:13PM +0530, Aneesh Kumar K.V wrote:
> Catalin Marinas <catalin.marinas@arm.com> writes:
> > On Mon, Apr 27, 2026 at 11:46:14AM +0530, Aneesh Kumar K.V (Arm) wrote:
> >> diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
> >> index 88b50d660e85..2d2d363aaaee 100644
> >> --- a/arch/arm64/include/asm/rsi.h
> >> +++ b/arch/arm64/include/asm/rsi.h
> >> @@ -10,7 +10,7 @@
> >> #include <linux/jump_label.h>
> >> #include <asm/rsi_cmds.h>
> >>
> >> -#define RSI_PDEV_NAME "arm-cca-dev"
> >> +#define RSI_DEV_NAME "arm-rsi-dev"
> > [...]
> >> diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
> >> index bdee057db2fd..fc9b44b7c687 100644
> >> --- a/drivers/firmware/smccc/smccc.c
> >> +++ b/drivers/firmware/smccc/smccc.c
> >> @@ -12,6 +12,8 @@
> >> #include <linux/platform_device.h>
> >> #include <asm/archrandom.h>
> >>
> >> +#include "rmm.h"
> >> +
> >> static u32 smccc_version = ARM_SMCCC_VERSION_1_0;
> >> static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE;
> >>
> >> @@ -85,6 +87,18 @@ static int __init smccc_devices_init(void)
> >> {
> >> struct platform_device *pdev;
> >>
> >> + pdev = platform_device_register_simple("arm-smccc",
> >> + PLATFORM_DEVID_NONE, NULL, 0);
> >> + if (IS_ERR(pdev)) {
> >> + pr_err("arm-smccc: could not register device: %ld\n", PTR_ERR(pdev));
> >> + } else {
> >> + /*
> >> + * Register the RMI and RSI devices only when firmware exposes
> >> + * the required SMCCC function IDs at a supported revision.
> >> + */
> >> + register_rsi_device(pdev);
> >> + }
> >
> > So as per the cover letter, instead of "arm-cca-dev" as a platform
> > device, we get "arm-smccc" as a platform device with an auxiliary
> > "arm-rsi-dev" child device. This does not get rid of the platform
> > device, it just creates a synthetic platform device to represent the
> > SMCCC firmware interface.
> >
> > Looking at the earlier discussion, I think this is what Greg/Jason were
> > suggesting, except that we do not currently have an SMCCC platform
> > device:
> >
> > https://lore.kernel.org/all/2025101534-frosty-shank-00b1@gregkh/
> >
> > If we go this route, shouldn't the platform device above be created only
> > if !SMCCC_CONDUIT_NONE?
> >
>
> register_rsi_device() does check for
>
> if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)
> return;
Yes but I meant for the "arm-smccc" platform device, not the rsi one.
You don't want it create if SMCCC_CONDUIT_NONE.
--
Catalin
^ permalink raw reply
* Re: [PATCH] drivers: altera_edac: Guard SDRAM irq2 retrieval for Arria10 only
From: Dinh Nguyen @ 2026-05-13 10:45 UTC (permalink / raw)
To: Nazle Asmade, Muhammad Nazim Amirul, bp@alien8.de,
tony.luck@intel.com
Cc: linux-edac@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <4f80ef77-a38b-4652-a1f1-1bea3e88de74@altera.com>
On 5/12/26 06:51, Nazle Asmade, Muhammad Nazim Amirul wrote:
> On 12/5/2026 7:25 pm, Dinh Nguyen wrote:
>>
>>
>> On 5/11/26 20:37, Nazle Asmade, Muhammad Nazim Amirul wrote:
>>> On 11/5/2026 7:54 pm, Dinh Nguyen wrote:
>>>>
>>>>
>>>> On 5/8/26 02:52, muhammad.nazim.amirul.nazle.asmade@altera.com wrote:
>>>>> From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
>>>>>
>>>>> Guard the irq2 retrieval with an of_machine_is_compatible() check so
>>>>> that platform_get_irq(pdev, 1) is only called on Arria10 platforms.
>>>>>
>>>>> Signed-off-by: Nazim Amirul
>>>>> <muhammad.nazim.amirul.nazle.asmade@altera.com>
>>>>> Signed-off-by: Niravkumar L Rabara <nirav.rabara@altera.com>
>>>>> ---
>>>>> drivers/edac/altera_edac.c | 3 ++-
>>>>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
>>>>> index 4edd2088c2db..b30302198cd4 100644
>>>>> --- a/drivers/edac/altera_edac.c
>>>>> +++ b/drivers/edac/altera_edac.c
>>>>> @@ -348,7 +348,8 @@ static int altr_sdram_probe(struct platform_device
>>>>> *pdev)
>>>>> }
>>>>> /* Arria10 has a 2nd IRQ */
>>>>> - irq2 = platform_get_irq(pdev, 1);
>>>>> + if (of_machine_is_compatible("altr,socfpga-arria10"))
>>>>> + irq2 = platform_get_irq(pdev, 1);
>>>>> layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
>>>>> layers[0].size = 1;
>>>>
>>>> Why? We already switch on arria10 later in the same function.
>>>>
>>>> Sorry, but NAK.
>>>>
>>>> Dinh
>>> This driver were used by cyclone5 and arria10. Cyclone5 only has one
>>> interrupt whereby arria10 has 2 interrupt. That is the reason why the
>>> interrupt was guard by (of_machine_is_compatible("altr,socfpga-arria10"))
>>>
>>
>> Yes, but look at line 397,
>>
>> /* Only the Arria10 has separate IRQs */
>> if (of_machine_is_compatible("altr,socfpga-arria10")) {
>> /* Arria10 specific initialization */
>>
>> Dinh
>>
>>
> Hi Dinh, That is true, but the one that we looking at now is at line 352
> which enabling the second interrupt and it is not required by cyclone5.
> Perhaps are you saying we should move the irq2 at line 352 under this
> line 397?
Yes, that would be fine.
Dinh
^ permalink raw reply
* [PATCH v2 3/3] arm64: dts: amlogic: t7: khadas-vim4: add PWM-driven status LED
From: Ronald Claveau via B4 Relay @ 2026-05-13 10:43 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
Ronald Claveau
In-Reply-To: <20260513-add-kvim4-sysled-v2-0-3ec9779e8875@aliel.fr>
From: Ronald Claveau <linux-kernel-dev@aliel.fr>
The VIM4 board exposes a status LED wired to the PWM_AO_C_D output.
Enable the pwm_ao_cd controller with its pinmux, and declare a
pwm-leds node with a heartbeat trigger.
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
.../boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
index fd1b983354a01..c41525a34b721 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
@@ -53,6 +53,16 @@ dc_in: regulator-dc-in {
regulator-always-on;
};
+ pwm-leds {
+ compatible = "pwm-leds";
+
+ status {
+ linux,default-trigger="heartbeat";
+ max-brightness = <255>;
+ pwms = <&pwm_ao_cd 0 30040 0>;
+ };
+ };
+
sd_3v3: regulator-sdcard-3v3 {
compatible = "regulator-fixed";
regulator-name = "SD_3V3";
@@ -163,6 +173,12 @@ &pwm_ab {
pinctrl-names = "default";
};
+&pwm_ao_cd {
+ status = "okay";
+ pinctrl-0 = <&pwm_ao_c_d_pins>;
+ pinctrl-names = "default";
+};
+
/* SDIO */
&sd_emmc_a {
status = "okay";
--
2.49.0
^ permalink raw reply related
* [PATCH v2 1/3] arm64: dts: amlogic: t7: Fix pwm_ao_c pinmux definitions
From: Ronald Claveau via B4 Relay @ 2026-05-13 10:43 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
Ronald Claveau
In-Reply-To: <20260513-add-kvim4-sysled-v2-0-3ec9779e8875@aliel.fr>
From: Ronald Claveau <linux-kernel-dev@aliel.fr>
The pwm_ao_c pin node was incomplete: it was missing the group name
suffix, conflating two distinct pin groups (pwm_ao_c_d and pwm_ao_c_e)
into a single, ambiguous entry.
Split the node into two separate pinmux entries:
- pwm_ao_c_d_pins: uses group "pwm_ao_c_d"
- pwm_ao_c_e_pins: uses group "pwm_ao_c_e"
Both alternate pins are not yet referenced by any peripheral node,
so this has no functional impact on existing boards. No backport needed.
Fixes: ee6e05a49b93 ("arm64: dts: amlogic: t7: Add PWM pinctrl nodes")
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index 7fe72c94ed623..62f6b9baad28b 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -400,9 +400,17 @@ mux {
};
};
- pwm_ao_c_pins: pwm-ao-c {
+ pwm_ao_c_d_pins: pwm-ao-c-d {
mux {
- groups = "pwm_ao_c";
+ groups = "pwm_ao_c_d";
+ function = "pwm_ao_c";
+ bias-disable;
+ };
+ };
+
+ pwm_ao_c_e_pins: pwm-ao-c-e {
+ mux {
+ groups = "pwm_ao_c_e";
function = "pwm_ao_c";
bias-disable;
};
--
2.49.0
^ permalink raw reply related
* [PATCH v2 2/3] arm64: dts: amlogic: t7: khadas-vim4: reorder root node
From: Ronald Claveau via B4 Relay @ 2026-05-13 10:43 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
Ronald Claveau
In-Reply-To: <20260513-add-kvim4-sysled-v2-0-3ec9779e8875@aliel.fr>
From: Ronald Claveau <linux-kernel-dev@aliel.fr>
Move the xtal-clk node to restore alphabetical ordering.
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
.../boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
index 69d6118ba57e7..fd1b983354a01 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
@@ -45,13 +45,6 @@ secmon_reserved_bl32: secmon@5300000 {
};
};
- xtal: xtal-clk {
- compatible = "fixed-clock";
- clock-frequency = <24000000>;
- clock-output-names = "xtal";
- #clock-cells = <0>;
- };
-
dc_in: regulator-dc-in {
compatible = "regulator-fixed";
regulator-name = "DC_IN";
@@ -155,6 +148,13 @@ wifi32k: wifi32k {
clock-frequency = <32768>;
pwms = <&pwm_ab 0 30518 0>;
};
+
+ xtal: xtal-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xtal";
+ #clock-cells = <0>;
+ };
};
&pwm_ab {
--
2.49.0
^ permalink raw reply related
* [PATCH v2 0/3] Khadas VIM4 PWM status LED support
From: Ronald Claveau via B4 Relay @ 2026-05-13 10:43 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
Ronald Claveau
This series adds support for the PWM-driven status LED on the Khadas
VIM4 board (Amlogic T7).
The VIM4 exposes a heartbeat LED wired to the PWM_AO_C output, routed
through pin group pwm_ao_c_d. Before wiring it up in the board DTS,
the SoC pinmux definitions had to be corrected: the original
pwm_ao_c node was conflating two distinct pin groups (pwm_ao_c_d and
pwm_ao_c_e) into a single ambiguous entry.
Patch 1 fixes the pwm_ao_c pinmux entries in the T7 DTSI by splitting
them into two properly named nodes. Neither alternate is in use yet,
so there is no functional impact on existing boards.
Patch 2 moves the xtal-clk node to restore alphabetical ordering among
root node children.
Patch 3 enables the pwm_ao_cd controller on the VIM4 and adds a
pwm-leds node with a heartbeat trigger.
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
Changes in v2:
- PATCH 2-3: Create a new patch specific to the reordering action.
According to Neil's review.
- Link to v1: https://lore.kernel.org/r/20260512-add-kvim4-sysled-v1-0-7178719a43e7@aliel.fr
---
Ronald Claveau (3):
arm64: dts: amlogic: t7: Fix pwm_ao_c pinmux definitions
arm64: dts: amlogic: t7: khadas-vim4: reorder root node
arm64: dts: amlogic: t7: khadas-vim4: add PWM-driven status LED
.../dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 30 +++++++++++++++++-----
arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 12 +++++++--
2 files changed, 33 insertions(+), 9 deletions(-)
---
base-commit: 31f32e8cdf59291e467250dfc57d1a8c718f63d2
change-id: 20260512-add-kvim4-sysled-8cc159524561
Best regards,
--
Ronald Claveau <linux-kernel-dev@aliel.fr>
^ permalink raw reply
* [PATCH 4/4] ASoC: stm: stm32_spdifrx: Use guard() for spin locks
From: phucduc.bui @ 2026-05-13 10:43 UTC (permalink / raw)
To: Olivier Moysan, Arnaud Pouliquen, Mark Brown
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Maxime Coquelin,
Alexandre Torgue, linux-sound, linux-stm32, linux-arm-kernel,
linux-kernel, bui duc phuc
In-Reply-To: <20260513104329.81592-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Clean up the code using guard() for spin locks.
Merely code refactoring, and no behavior change.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/stm/stm32_spdifrx.c | 44 +++++++++++++----------------------
1 file changed, 16 insertions(+), 28 deletions(-)
diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
index 57b711c44278..2f83ca989e68 100644
--- a/sound/soc/stm/stm32_spdifrx.c
+++ b/sound/soc/stm/stm32_spdifrx.c
@@ -322,7 +322,6 @@ static void stm32_spdifrx_dma_ctrl_stop(struct stm32_spdifrx_data *spdifrx)
static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
{
int cr, cr_mask, imr, ret;
- unsigned long flags;
/* Enable IRQs */
imr = SPDIFRX_IMR_IFEIE | SPDIFRX_IMR_SYNCDIE | SPDIFRX_IMR_PERRIE;
@@ -330,7 +329,7 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
if (ret)
return ret;
- spin_lock_irqsave(&spdifrx->lock, flags);
+ guard(spinlock_irqsave)(&spdifrx->lock);
spdifrx->refcount++;
@@ -365,22 +364,17 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
"Failed to start synchronization\n");
}
- spin_unlock_irqrestore(&spdifrx->lock, flags);
-
return ret;
}
static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
{
int cr, cr_mask, reg;
- unsigned long flags;
- spin_lock_irqsave(&spdifrx->lock, flags);
+ guard(spinlock_irqsave)(&spdifrx->lock);
- if (--spdifrx->refcount) {
- spin_unlock_irqrestore(&spdifrx->lock, flags);
+ if (--spdifrx->refcount)
return;
- }
cr = SPDIFRX_CR_SPDIFENSET(SPDIFRX_SPDIFEN_DISABLE);
cr_mask = SPDIFRX_CR_SPDIFEN_MASK | SPDIFRX_CR_RXDMAEN;
@@ -396,8 +390,6 @@ static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
/* dummy read to clear CSRNE and RXNE in status register */
regmap_read(spdifrx->regmap, STM32_SPDIFRX_DR, ®);
regmap_read(spdifrx->regmap, STM32_SPDIFRX_CSR, ®);
-
- spin_unlock_irqrestore(&spdifrx->lock, flags);
}
static int stm32_spdifrx_dma_ctrl_register(struct device *dev,
@@ -744,19 +736,19 @@ static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
return IRQ_HANDLED;
}
- spin_lock(&spdifrx->irq_lock);
- if (spdifrx->substream)
- snd_pcm_stop(spdifrx->substream,
- SNDRV_PCM_STATE_DISCONNECTED);
- spin_unlock(&spdifrx->irq_lock);
+ scoped_guard(spinlock, &spdifrx->irq_lock) {
+ if (spdifrx->substream)
+ snd_pcm_stop(spdifrx->substream,
+ SNDRV_PCM_STATE_DISCONNECTED);
+ }
return IRQ_HANDLED;
}
- spin_lock(&spdifrx->irq_lock);
- if (err_xrun && spdifrx->substream)
- snd_pcm_stop_xrun(spdifrx->substream);
- spin_unlock(&spdifrx->irq_lock);
+ scoped_guard(spinlock, &spdifrx->irq_lock) {
+ if (err_xrun && spdifrx->substream)
+ snd_pcm_stop_xrun(spdifrx->substream);
+ }
return IRQ_HANDLED;
}
@@ -765,12 +757,10 @@ static int stm32_spdifrx_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long flags;
int ret;
- spin_lock_irqsave(&spdifrx->irq_lock, flags);
- spdifrx->substream = substream;
- spin_unlock_irqrestore(&spdifrx->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &spdifrx->irq_lock)
+ spdifrx->substream = substream;
ret = clk_prepare_enable(spdifrx->kclk);
if (ret)
@@ -846,11 +836,9 @@ static void stm32_spdifrx_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long flags;
- spin_lock_irqsave(&spdifrx->irq_lock, flags);
- spdifrx->substream = NULL;
- spin_unlock_irqrestore(&spdifrx->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &spdifrx->irq_lock)
+ spdifrx->substream = NULL;
clk_disable_unprepare(spdifrx->kclk);
}
--
2.43.0
^ permalink raw reply related
* [PATCH 3/4] ASoC: stm: stm32_sai_sub: Use guard() for mutex & spin locks
From: phucduc.bui @ 2026-05-13 10:43 UTC (permalink / raw)
To: Olivier Moysan, Arnaud Pouliquen, Mark Brown
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Maxime Coquelin,
Alexandre Torgue, linux-sound, linux-stm32, linux-arm-kernel,
linux-kernel, bui duc phuc
In-Reply-To: <20260513104329.81592-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Clean up the code using guard() for mutex & spin locks.
Merely code refactoring, and no behavior change.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/stm/stm32_sai_sub.c | 29 +++++++++++------------------
1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 3e82fa90e719..ea9e8bddd63f 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -280,9 +280,8 @@ static int snd_pcm_iec958_get(struct snd_kcontrol *kcontrol,
{
struct stm32_sai_sub_data *sai = snd_kcontrol_chip(kcontrol);
- mutex_lock(&sai->ctrl_lock);
+ guard(mutex)(&sai->ctrl_lock);
memcpy(uctl->value.iec958.status, sai->iec958.status, 4);
- mutex_unlock(&sai->ctrl_lock);
return 0;
}
@@ -292,9 +291,8 @@ static int snd_pcm_iec958_put(struct snd_kcontrol *kcontrol,
{
struct stm32_sai_sub_data *sai = snd_kcontrol_chip(kcontrol);
- mutex_lock(&sai->ctrl_lock);
+ guard(mutex)(&sai->ctrl_lock);
memcpy(sai->iec958.status, uctl->value.iec958.status, 4);
- mutex_unlock(&sai->ctrl_lock);
return 0;
}
@@ -658,10 +656,10 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
status = SNDRV_PCM_STATE_XRUN;
}
- spin_lock(&sai->irq_lock);
- if (status != SNDRV_PCM_STATE_RUNNING && sai->substream)
- snd_pcm_stop_xrun(sai->substream);
- spin_unlock(&sai->irq_lock);
+ scoped_guard(spinlock, &sai->irq_lock) {
+ if (status != SNDRV_PCM_STATE_RUNNING && sai->substream)
+ snd_pcm_stop_xrun(sai->substream);
+ }
return IRQ_HANDLED;
}
@@ -894,11 +892,9 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream,
{
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
int imr, cr2, ret;
- unsigned long flags;
- spin_lock_irqsave(&sai->irq_lock, flags);
- sai->substream = substream;
- spin_unlock_irqrestore(&sai->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &sai->irq_lock)
+ sai->substream = substream;
if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
snd_pcm_hw_constraint_mask64(substream->runtime,
@@ -1083,7 +1079,7 @@ static void stm32_sai_set_iec958_status(struct stm32_sai_sub_data *sai,
return;
/* Force the sample rate according to runtime rate */
- mutex_lock(&sai->ctrl_lock);
+ guard(mutex)(&sai->ctrl_lock);
switch (runtime->rate) {
case 22050:
sai->iec958.status[3] = IEC958_AES3_CON_FS_22050;
@@ -1116,7 +1112,6 @@ static void stm32_sai_set_iec958_status(struct stm32_sai_sub_data *sai,
sai->iec958.status[3] = IEC958_AES3_CON_FS_NOTID;
break;
}
- mutex_unlock(&sai->ctrl_lock);
}
static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
@@ -1284,7 +1279,6 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long flags;
stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0);
@@ -1298,9 +1292,8 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
if (!sai->sai_mclk && sai->put_sai_ck_rate)
sai->put_sai_ck_rate(sai);
- spin_lock_irqsave(&sai->irq_lock, flags);
- sai->substream = NULL;
- spin_unlock_irqrestore(&sai->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &sai->irq_lock)
+ sai->substream = NULL;
}
static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd,
--
2.43.0
^ permalink raw reply related
* [PATCH 2/4] ASoC: stm: stm32_i2s: Use guard() for spin locks
From: phucduc.bui @ 2026-05-13 10:43 UTC (permalink / raw)
To: Olivier Moysan, Arnaud Pouliquen, Mark Brown
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Maxime Coquelin,
Alexandre Torgue, linux-sound, linux-stm32, linux-arm-kernel,
linux-kernel, bui duc phuc
In-Reply-To: <20260513104329.81592-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Clean up the code using guard() for spin locks.
Merely code refactoring, and no behavior change.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/stm/stm32_i2s.c | 67 ++++++++++++++++++---------------------
1 file changed, 30 insertions(+), 37 deletions(-)
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
index 6ca21780f21d..4fddb7ecd7fd 100644
--- a/sound/soc/stm/stm32_i2s.c
+++ b/sound/soc/stm/stm32_i2s.c
@@ -615,10 +615,10 @@ static irqreturn_t stm32_i2s_isr(int irq, void *devid)
if (flags & I2S_SR_TIFRE)
dev_dbg(&pdev->dev, "Frame error\n");
- spin_lock(&i2s->irq_lock);
- if (err && i2s->substream)
- snd_pcm_stop_xrun(i2s->substream);
- spin_unlock(&i2s->irq_lock);
+ scoped_guard(spinlock, &i2s->irq_lock) {
+ if (err && i2s->substream)
+ snd_pcm_stop_xrun(i2s->substream);
+ }
return IRQ_HANDLED;
}
@@ -905,12 +905,10 @@ static int stm32_i2s_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long flags;
int ret;
- spin_lock_irqsave(&i2s->irq_lock, flags);
- i2s->substream = substream;
- spin_unlock_irqrestore(&i2s->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &i2s->irq_lock)
+ i2s->substream = substream;
if ((i2s->fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_DSP_A)
snd_pcm_hw_constraint_single(substream->runtime,
@@ -982,19 +980,19 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
regmap_write_bits(i2s->regmap, STM32_I2S_IFCR_REG,
I2S_IFCR_MASK, I2S_IFCR_MASK);
- spin_lock(&i2s->lock_fd);
- i2s->refcount++;
- if (playback_flg) {
- ier = I2S_IER_UDRIE;
- } else {
- ier = I2S_IER_OVRIE;
-
- if (STM32_I2S_IS_MASTER(i2s) && i2s->refcount == 1)
- /* dummy write to gate bus clocks */
- regmap_write(i2s->regmap,
- STM32_I2S_TXDR_REG, 0);
+ scoped_guard(spinlock, &i2s->lock_fd) {
+ i2s->refcount++;
+ if (playback_flg) {
+ ier = I2S_IER_UDRIE;
+ } else {
+ ier = I2S_IER_OVRIE;
+
+ if (STM32_I2S_IS_MASTER(i2s) && i2s->refcount == 1)
+ /* dummy write to gate bus clocks */
+ regmap_write(i2s->regmap,
+ STM32_I2S_TXDR_REG, 0);
+ }
}
- spin_unlock(&i2s->lock_fd);
if (STM32_I2S_IS_SLAVE(i2s))
ier |= I2S_IER_TIFREIE;
@@ -1016,21 +1014,18 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
I2S_IER_OVRIE,
(unsigned int)~I2S_IER_OVRIE);
- spin_lock(&i2s->lock_fd);
- i2s->refcount--;
- if (i2s->refcount) {
- spin_unlock(&i2s->lock_fd);
- break;
- }
+ scoped_guard(spinlock, &i2s->lock_fd) {
+ i2s->refcount--;
+ if (i2s->refcount)
+ break;
- ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG,
- I2S_CR1_SPE, 0);
- if (ret < 0) {
- dev_err(cpu_dai->dev, "Error %d disabling I2S\n", ret);
- spin_unlock(&i2s->lock_fd);
- return ret;
+ ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG,
+ I2S_CR1_SPE, 0);
+ if (ret < 0) {
+ dev_err(cpu_dai->dev, "Error %d disabling I2S\n", ret);
+ return ret;
+ }
}
- spin_unlock(&i2s->lock_fd);
cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN;
regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG,
@@ -1047,7 +1042,6 @@ static void stm32_i2s_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long flags;
clk_disable_unprepare(i2s->i2sclk);
@@ -1059,9 +1053,8 @@ static void stm32_i2s_shutdown(struct snd_pcm_substream *substream,
if (!i2s->i2smclk && i2s->put_i2s_clk_rate)
i2s->put_i2s_clk_rate(i2s);
- spin_lock_irqsave(&i2s->irq_lock, flags);
- i2s->substream = NULL;
- spin_unlock_irqrestore(&i2s->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &i2s->irq_lock)
+ i2s->substream = NULL;
}
static int stm32_i2s_dai_probe(struct snd_soc_dai *cpu_dai)
--
2.43.0
^ permalink raw reply related
* [PATCH 1/4] ASoC: stm: stm32_adfsdm: Use guard() for mutex locks
From: phucduc.bui @ 2026-05-13 10:43 UTC (permalink / raw)
To: Olivier Moysan, Arnaud Pouliquen, Mark Brown
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Maxime Coquelin,
Alexandre Torgue, linux-sound, linux-stm32, linux-arm-kernel,
linux-kernel, bui duc phuc
In-Reply-To: <20260513104329.81592-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Clean up the code using guard() for mutex locks.
Merely code refactoring, and no behavior change.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/stm/stm32_adfsdm.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
index 0f6d32814c22..a585cb9fc011 100644
--- a/sound/soc/stm/stm32_adfsdm.c
+++ b/sound/soc/stm/stm32_adfsdm.c
@@ -62,12 +62,11 @@ static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream,
{
struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
- mutex_lock(&priv->lock);
+ guard(mutex)(&priv->lock);
if (priv->iio_active) {
iio_channel_stop_all_cb(priv->iio_cb);
priv->iio_active = false;
}
- mutex_unlock(&priv->lock);
}
static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
@@ -76,7 +75,7 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
int ret;
- mutex_lock(&priv->lock);
+ guard(mutex)(&priv->lock);
if (priv->iio_active) {
iio_channel_stop_all_cb(priv->iio_cb);
priv->iio_active = false;
@@ -88,7 +87,7 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
if (ret < 0) {
dev_err(dai->dev, "%s: Failed to set %d sampling rate\n",
__func__, substream->runtime->rate);
- goto out;
+ return ret;
}
if (!priv->iio_active) {
@@ -100,9 +99,6 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
__func__, ret);
}
-out:
- mutex_unlock(&priv->lock);
-
return ret;
}
--
2.43.0
^ permalink raw reply related
* [PATCH 0/4] ASoC: stm: Use guard() for mutex & spin locks
From: phucduc.bui @ 2026-05-13 10:43 UTC (permalink / raw)
To: Olivier Moysan, Arnaud Pouliquen, Mark Brown
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Maxime Coquelin,
Alexandre Torgue, linux-sound, linux-stm32, linux-arm-kernel,
linux-kernel, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Hi all,
This series converts mutex and spinlock handling in the STM drivers
to use guard() helpers.
The changes are code cleanup only and should have no functional impact.
Best regards,
Phuc
bui duc phuc (4):
ASoC: stm: stm32_adfsdm: Use guard() for mutex locks
ASoC: stm: stm32_i2s: Use guard() for spin locks
ASoC: stm: stm32_sai_sub: Use guard() for mutex & spin locks
ASoC: stm: stm32_spdifrx: Use guard() for spin locks
sound/soc/stm/stm32_adfsdm.c | 10 ++----
sound/soc/stm/stm32_i2s.c | 67 ++++++++++++++++-------------------
sound/soc/stm/stm32_sai_sub.c | 29 ++++++---------
sound/soc/stm/stm32_spdifrx.c | 44 +++++++++--------------
4 files changed, 60 insertions(+), 90 deletions(-)
--
2.43.0
^ permalink raw reply
* Re: [PATCH] clk: rockchip: allow COMPILE_TEST builds
From: Heiko Stuebner @ 2026-05-13 10:37 UTC (permalink / raw)
To: linux-rockchip, Rosen Penev
Cc: Heiko Stuebner, Michael Turquette, Stephen Boyd, Brian Masney,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linux-clk, linux-kernel, linux-arm-kernel, llvm
In-Reply-To: <20260509003602.956186-1-rosenp@gmail.com>
On Fri, 08 May 2026 17:36:02 -0700, Rosen Penev wrote:
> COMMON_CLK_ROCKCHIP already gates the Rockchip clock objects inside the
> Rockchip clock Makefile. Allow selecting it for COMPILE_TEST and use it
> for the parent Makefile descent instead of ARCH_ROCKCHIP.
>
> The per-SoC Rockchip clock symbols already have COMPILE_TEST dependencies,
> so this exposes the existing build coverage to other architectures without
> selecting the Rockchip platform.
>
> [...]
Applied, thanks!
[1/1] clk: rockchip: allow COMPILE_TEST builds
commit: 7edfb7fb58ee058298e18fde76a6077ef17d19d8
Best regards,
--
Heiko Stuebner <heiko@sntech.de>
^ permalink raw reply
* Re: [PATCH v4 2/2] coco: guest: arm64: Drop dummy RSI platform device stub
From: Greg KH @ 2026-05-13 9:59 UTC (permalink / raw)
To: Aneesh Kumar K.V
Cc: Catalin Marinas, linux-kernel, linux-arm-kernel, Jeremy Linton,
Jonathan Cameron, Lorenzo Pieralisi, Mark Rutland, Sudeep Holla,
Will Deacon, Jonathan Cameron, Suzuki K Poulose
In-Reply-To: <yq5a4ikbu1w2.fsf@kernel.org>
On Wed, May 13, 2026 at 02:23:01PM +0530, Aneesh Kumar K.V wrote:
> Greg KH <gregkh@linuxfoundation.org> writes:
>
> > On Wed, May 13, 2026 at 12:28:12PM +0530, Aneesh Kumar K.V wrote:
> >> Catalin Marinas <catalin.marinas@arm.com> writes:
> >>
> >> > + Suzuki again
> >> >
> >> > On Mon, Apr 27, 2026 at 11:46:15AM +0530, Aneesh Kumar K.V (Arm) wrote:
> >> >> The SMCCC firmware driver now creates the `arm-smccc` platform device
> >> >> and also creates the CCA auxiliary devices once the RSI ABI is
> >> >> discovered. This makes the arch-specific arm64_create_dummy_rsi_dev()
> >> >> helper redundant. Remove the arm-cca-dev platform device registration
> >> >> and let the SMCCC probe manage the RSI device.
> >> >>
> >> >> systemd match on platform:arm-cca-dev for confidential vm detection [1].
> >> >> Losing the platform device registration can break that. Keeping this
> >> >> removal in its own change makes it easy to revert if that regression
> >> >> blocks the rollout.
> >> >>
> >> >> [1] https://lore.kernel.org/all/4a7d84b2-2ec4-4773-a2d5-7b63d5c683cf@arm.com
> >> >
> >> > I wouldn't merge this now given that systemd checks this file. Could we
> >> > have a symbolic link instead for some time until systemd eventually gets
> >> > updated (years?).
> >> >
> >>
> >> I’ll add this in the next revision.
> >>
> >> static int create_rsi_compat_link(struct device *target_dev)
> >> {
> >> struct kobject *platform_kobj;
> >> /*
> >> * target_dev is:
> >> * /sys/devices/platform/arm-smccc/arm_cca_guest.arm-rsi-dev.0
> >> * Create compat link /sys/devices/platform/arm-cca-dev
> >> */
> >> platform_kobj = target_dev->kobj.parent->parent;
> >
> > What? That is crazy, you don't know that is always going to be ok.
> >
> >> return sysfs_create_link(platform_kobj,
> >> &target_dev->kobj,
> >> "arm-cca-dev");
> >
> > No, don't do that, if a driver calls a sysfs* function, something is
> > almost always wrong. Don't be making random sysfs symlinks please.
> >
>
> Sure, but could you explain why this is wrong? Below is the full version
> of the updated patch.
>
> coco: guest: arm64 Replace RSI platform device with compat symlink
>
> The SMCCC firmware driver now creates the arm-smccc platform device and
> registers the RSI device as an auxiliary device once the RSI ABI has been
> discovered. This makes the arch-specific arm64 arm-cca-dev platform device
> redundant.
>
> Remove the arm64 platform device stub and let the SMCCC core manage RSI
> device creation.
>
> This changes the real device location from the old platform device path to:
>
> /sys/devices/platform/arm-smccc/arm_cca_guest.arm-rsi-dev.0
>
> Keep userspace compatibility by creating a sysfs symlink at the old path:
>
> /sys/devices/platform/arm-cca-dev
>
> A Debian Code Search check found systemd matching on the old
> platform:arm-cca-dev device path for confidential VM detection. No other
> userspace dependency on the old platform device path was found, but keeping
> the compatibility symlink avoids breaking existing systemd-based detection
> [1].
>
> [1] https://lore.kernel.org/all/4a7d84b2-2ec4-4773-a2d5-7b63d5c683cf@arm.com
Don't attempt to put symlinks between random devices in sysfs, that way
lies madness and you will never get anything fixed.
Just fix userspace, it shouldn't have hard-coded a device path in the
first place, and you are thinking it would now use a different
hard-coded device path? Please do this properly.
Again, there should never be any hard-coded device paths, they are free
to move around and be renamed at any time. Use the correct apis instead
(walking all bus devices, looking at userspace attributes of classes,
etc.)
So your patch is ok, if you remove the symlink stuff.
thanks,
greg k-h
^ permalink raw reply
* [PATCH v5 0/2] arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
From: Josua Mayer @ 2026-05-13 10:32 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: Yazan Shhady, Mikhail Anikin, Alexander Dahl, devicetree,
linux-kernel, imx, linux-arm-kernel, Vladimir Oltean,
Conor Dooley, Krzysztof Kozlowski, netdev, Josua Mayer,
Krzysztof Kozlowski
Add bindings and description for SolidRUn i.MX8DXL based SoM and
HummingBoard Telematics.
Modify SJA1110 Ethernet Switch bindings to allow SPI Mode 0.
This patch-set is based on v7.0-rc2, because rc1 was experiencing
deadlocks with imx8qxp clock driver.
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
Changes in v5:
- Change cpu port phy-mode to rgmii-id, and set zero delays. Delays are
added by connected ethernet switch port.
- Added ethernet aliases for all switch ports.
- Removed undocumented reset-duration-us property from usb modem node.
- Fix T1 interface count in commit message.
- Change USB-A Port dr_mode to host.
- Add cap-sdio-irq for wifi.
- Link to v4: https://lore.kernel.org/r/20260511-imx8dxl-sr-som-v4-0-64381b3bf80d@solid-run.com
Changes in v4:
- picked up acked-by adnrew lunn
- Link to v3: https://lore.kernel.org/r/20260430-imx8dxl-sr-som-v3-0-ce2b86cf75bc@solid-run.com
Changes in v3:
- rebased on v7.1-rc1.
- dropped dsa swtch port labels, should be handled by udev rules if
required.
- Fixed spelling error in alias comment.
- Dropped superfluous status okay properties from switch sub-nodes.
- Link to v2: https://lore.kernel.org/r/20260409-imx8dxl-sr-som-v2-0-83ff20629ba0@solid-run.com
Changes in v2:
- Dropped accidental change to unrelated imx8mp-sr-som.dtsi file.
- Fixed phy-mode on fixed link between cpu and ethernet switch.
(Reported-by: Andrew Lunn <andrew@lunn.ch>)
- Removed spi-cpol property from ethernet-switch on spi bus, fixing
sja1110a driver probe.
- Changed SJA1110 bindings to allow removing spi-cpol property.
- Aligned comments on all ethernet switch port nodes to be consistent.
- Dropped regulator-always-on from dsrc radio power-supplies.
- Link to v1: https://lore.kernel.org/r/20260408-imx8dxl-sr-som-v1-0-ce5a39acd713@solid-run.com
---
Josua Mayer (2):
dt-bindings: arm: fsl: Add SolidRun i.MX8DXL SoM and HummingBoard
arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
Documentation/devicetree/bindings/arm/fsl.yaml | 7 +
arch/arm64/boot/dts/freescale/Makefile | 2 +
.../freescale/imx8dxl-hummingboard-telematics.dts | 536 +++++++++++++++++++++
arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi | 458 ++++++++++++++++++
4 files changed, 1003 insertions(+)
---
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
change-id: 20260408-imx8dxl-sr-som-f141ec343173
Best regards,
--
Josua Mayer <josua@solid-run.com>
^ permalink raw reply
* [PATCH v5 2/2] arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
From: Josua Mayer @ 2026-05-13 10:32 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: Yazan Shhady, Mikhail Anikin, Alexander Dahl, devicetree,
linux-kernel, imx, linux-arm-kernel, Vladimir Oltean,
Conor Dooley, Krzysztof Kozlowski, netdev, Josua Mayer
In-Reply-To: <20260513-imx8dxl-sr-som-v5-0-d0899b371c38@solid-run.com>
Add support for the SolidRun i.MX8DXL System-on-Module (revision 2.1)
and its corresponding evaluation carrier board, the HummingBoard
Telematics (revision 2.0).
The SoM features:
- eMMC
- GNSS with 1PPS
- V2X DSRC Radio
- Secure Element for V2X Applications
- Inertial Sensor
- Pressure Sensor
- Compass
The HummingBoard Telematics carrier board features:
- Cellular Modem
- WiFi & Bluetooth
- RTC with backup battery
- CAN
- 100Base-TX Ethernet
- 100Base-T1 Ethernet
- Multi-interface I/O connector
- Multi-interface add-on board connector
The multi-interface I/O connector supplies power and provides basic I/O
(Console UART, 100Base-TX, 100Base-T1, CAN, and power-supply logic level
GPIOs). The SolidRun Evaluation Kit includes a suitable cable and
adapter board that breaks these out into RJ45, USB Type-A, microUSB
Console, and Terminal Block connectors.
The multi-interface add-on board connector provides additional
interfaces (5x 100Base-T1, 2x SGMII, USB 2.0 shared with the cellular
modem, CAN, MDIO, SPI, UART, PCIe, I2C, and GPIO). These add-on
interfaces are disabled by default in the base device tree and are
intended to be enabled and extended via device tree overlays.
Note that a few components physically present on the SoM were omitted
from this description due to a lack of upstream bindings and drivers:
- Pressure Sensor
- V2X DSRC Radio
- Secure Element
Acked-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
arch/arm64/boot/dts/freescale/Makefile | 2 +
.../freescale/imx8dxl-hummingboard-telematics.dts | 536 +++++++++++++++++++++
arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi | 458 ++++++++++++++++++
3 files changed, 996 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 711e36cc2c990..7db459f666610 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -111,6 +111,8 @@ dtb-$(CONFIG_ARCH_MXC) += imx8dxl-evk.dtb
imx8dxl-evk-pcie-ep-dtbs += imx8dxl-evk.dtb imx-pcie0-ep.dtbo
dtb-$(CONFIG_ARCH_MXC) += imx8dxl-evk-pcie-ep.dtb
+DTC_FLAGS_imx8dxl-hummingboard-telematics := -@
+dtb-$(CONFIG_ARCH_MXC) += imx8dxl-hummingboard-telematics.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8dxp-tqma8xdp-mba8xx.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8dxp-tqma8xdps-mb-smarc-2.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-hummingboard-telematics.dts b/arch/arm64/boot/dts/freescale/imx8dxl-hummingboard-telematics.dts
new file mode 100644
index 0000000000000..5f42c4f2e3be9
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-hummingboard-telematics.dts
@@ -0,0 +1,536 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022-2026 Josua Mayer <josua@solid-run.com>
+ */
+
+/dts-v1/;
+
+#include "imx8dxl-sr-som.dtsi"
+
+/ {
+ compatible = "solidrun,imx8dxl-hummingboard-telematics",
+ "solidrun,imx8dxl-sr-som", "fsl,imx8dxl";
+ model = "SolidRun i.MX8DXL HummingBoard Telematics";
+
+ aliases {
+ /* override ethernet aliases from imx8dxl.dtsi */
+ ethernet0 = &eqos;
+ ethernet1 = &switch_port1;
+ ethernet2 = &switch_port2;
+ ethernet3 = &switch_port3;
+ ethernet4 = &switch_port4;
+ ethernet5 = &switch_port5;
+ ethernet6 = &switch_port6;
+ ethernet7 = &switch_port7;
+ ethernet8 = &switch_port8;
+ ethernet9 = &switch_port9;
+ ethernet10 = &switch_port10;
+ /delete-property/ ethernet1;
+ gpio8 = &tca6408_u2;
+ mmc2 = &usdhc3;
+ rtc0 = &carrier_rtc;
+ rtc1 = &rtc;
+ serial1 = &lpuart1;
+ };
+
+ v_1_1: regulator-1-1 {
+ compatible = "regulator-fixed";
+ regulator-name = "1v1";
+ pinctrl-0 = <®ulator_1v1_pins>;
+ pinctrl-names = "default";
+ regulator-always-on;
+ regulator-max-microvolt = <1100000>;
+ regulator-min-microvolt = <1100000>;
+ vin-supply = <&v_5_0>;
+ gpio = <&lsio_gpio4 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ v_5_0: regulator-5-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5v0";
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ };
+
+ /* can transceiver builtin regulator (STBN1 pin) */
+ reg_flexcan1_stby: regulator-flexcan1-standby {
+ compatible = "regulator-fixed";
+ regulator-name = "flexcan1-standby";
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ gpio = <&tca6408_u2 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ /* can transceiver builtin regulator (STBN2 pin) */
+ reg_flexcan2_stby: regulator-flexcan2-standby {
+ compatible = "regulator-fixed";
+ regulator-name = "flexcan2-standby";
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ gpio = <&tca6408_u2 3 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ modem_vbat: regulator-modem-vbat {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat";
+ pinctrl-0 = <®ulator_modem_vbat_pins>;
+ pinctrl-names = "default";
+ regulator-max-microvolt = <3600000>;
+ regulator-min-microvolt = <3600000>;
+ vin-supply = <&v_5_0>;
+ gpio = <&lsio_gpio0 14 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vbus1: regulator-vbus-1 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbus1";
+ pinctrl-0 = <®ulator_usb1_vbus_pins>;
+ pinctrl-names = "default";
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ gpio = <&lsio_gpio0 16 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ usdhc3_pwrseq: usdhc3-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&lsio_gpio0 15 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&dma_apbh {
+ status = "disabled";
+};
+
+&eqos {
+ /* delays are added by connected ethernet-switch cpu port */
+ phy-mode = "rgmii-id";
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <0>;
+ pinctrl-0 = <&eqos_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ fixed-link {
+ full-duplex;
+ speed = <1000>;
+ };
+};
+
+&flexcan1 {
+ pinctrl-0 = <&flexcan1_pins>;
+ pinctrl-names = "default";
+ xceiver-supply = <®_flexcan1_stby>;
+ status = "okay";
+
+ can-transceiver {
+ max-bitrate = <5000000>;
+ };
+};
+
+&flexcan2 {
+ pinctrl-0 = <&flexcan2_pins>;
+ pinctrl-names = "default";
+ xceiver-supply = <®_flexcan2_stby>;
+ status = "okay";
+
+ can-transceiver {
+ max-bitrate = <5000000>;
+ };
+};
+
+&i2c2 {
+ /* routed to J14: SDA(51), SCL(53) */
+
+ /* regulator@18 */
+
+ tca6408_u2: gpio@20 {
+ compatible = "ti,tca6408";
+ reg = <0x20>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-line-names = "DIG_IN1", "DIG_IN2", "CAN_STNB1", "CAN_STNB2",
+ "DIG_OUT1", "DIG_OUT2", "", "";
+ interrupts-extended = <&lsio_gpio0 20 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-0 = <&tca6408_u2_int_pins>;
+ pinctrl-names = "default";
+ };
+
+ carrier_rtc: rtc@32 {
+ compatible = "epson,rx8111";
+ reg = <0x32>;
+ };
+};
+
+&iomuxc {
+ bluetooth_pins: pinctrl-bluetooth-grp {
+ fsl,pins = <
+ /* BT_REG_ON: io without pull (module integrates pd) */
+ IMX8DXL_SPI3_SCK_LSIO_GPIO0_IO13 0x0000061
+ >;
+ };
+
+ eqos_pins: pinctrl-eqos-grp {
+ fsl,pins = <
+ /* MDIO to Switch */
+ /* enet0 mdio pads supplied with 3.3v */
+ /* IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOCT */
+ IMX8DXL_ENET0_MDC_CONN_EQOS_MDC 0x06000020
+ IMX8DXL_ENET0_MDIO_CONN_EQOS_MDIO 0x06000020
+ /* RGMII to Switch */
+ IMX8DXL_ENET1_RGMII_TX_CTL_CONN_EQOS_RGMII_TX_CTL 0x06000020
+ IMX8DXL_ENET1_RGMII_TXC_CONN_EQOS_RGMII_TXC 0x06000020
+ IMX8DXL_ENET1_RGMII_TXD0_CONN_EQOS_RGMII_TXD0 0x06000020
+ IMX8DXL_ENET1_RGMII_TXD1_CONN_EQOS_RGMII_TXD1 0x06000020
+ IMX8DXL_ENET1_RGMII_TXD2_CONN_EQOS_RGMII_TXD2 0x06000020
+ IMX8DXL_ENET1_RGMII_TXD3_CONN_EQOS_RGMII_TXD3 0x06000020
+ IMX8DXL_ENET1_RGMII_RXC_CONN_EQOS_RGMII_RXC 0x06000020
+ IMX8DXL_ENET1_RGMII_RX_CTL_CONN_EQOS_RGMII_RX_CTL 0x06000020
+ IMX8DXL_ENET1_RGMII_RXD0_CONN_EQOS_RGMII_RXD0 0x06000020
+ IMX8DXL_ENET1_RGMII_RXD1_CONN_EQOS_RGMII_RXD1 0x06000020
+ IMX8DXL_ENET1_RGMII_RXD2_CONN_EQOS_RGMII_RXD2 0x06000020
+ IMX8DXL_ENET1_RGMII_RXD3_CONN_EQOS_RGMII_RXD3 0x06000020
+ >;
+ };
+
+ flexcan1_pins: pinctrl-flexcan1-grp {
+ fsl,pins = <
+ IMX8DXL_FLEXCAN0_TX_ADMA_FLEXCAN0_TX 0x00000021
+ IMX8DXL_FLEXCAN0_RX_ADMA_FLEXCAN0_RX 0x00000021
+ >;
+ };
+
+ flexcan2_pins: pinctrl-flexcan2-grp {
+ fsl,pins = <
+ IMX8DXL_FLEXCAN1_TX_ADMA_FLEXCAN1_TX 0x00000021
+ IMX8DXL_FLEXCAN1_RX_ADMA_FLEXCAN1_RX 0x00000021
+ >;
+ };
+
+ lpspi0_pins: pinctrl-lpspi0-grp {
+ fsl,pins = <
+ IMX8DXL_SPI0_SCK_ADMA_SPI0_SCK 0x600004c
+ IMX8DXL_SPI0_SDO_ADMA_SPI0_SDO 0x600004c
+ IMX8DXL_SPI0_SDI_ADMA_SPI0_SDI 0x600004c
+ IMX8DXL_SPI0_CS0_LSIO_GPIO1_IO08 0x0000021
+ IMX8DXL_SPI0_CS1_LSIO_GPIO1_IO07 0x0000021
+ >;
+ };
+
+ lpuart1_pins: pinctrl-lpuart1-grp {
+ fsl,pins = <
+ IMX8DXL_UART1_RX_ADMA_UART1_RX 0x06000020
+ IMX8DXL_UART1_TX_ADMA_UART1_TX 0x06000020
+ IMX8DXL_UART1_CTS_B_ADMA_UART1_CTS_B 0x06000020
+ IMX8DXL_UART1_RTS_B_ADMA_UART1_RTS_B 0x06000020
+ >;
+ };
+
+ modem_pins: pinctrl-lte-grp {
+ fsl,pins = <
+ /* modem RESET_N: io open drain drive 2mA */
+ IMX8DXL_ADC_IN3_LSIO_GPIO1_IO11 0x2000061
+
+ /* modem PWRKEY: io open drain with pull-up, drive 2mA */
+ IMX8DXL_ADC_IN2_LSIO_GPIO1_IO12 0x2000021
+ >;
+ };
+
+ regulator_1v1_pins: pinctrl-regulator-1-1-grp {
+ fsl,pins = <
+ /* SW_PE: io without pull-up */
+ IMX8DXL_USB_SS3_TC2_LSIO_GPIO4_IO05 0x0000061
+ >;
+ };
+
+ regulator_modem_vbat_pins: pinctrl-regulator-modem-vbat-grp {
+ fsl,pins = <
+ /*
+ * RF_PWR: io without pull-up,
+ * has either external pull-up (R1117) or pull-down (R1118).
+ * With pull-up Modem will boot at system power-up,
+ * with pull-down modem will enter power-down mode once
+ * vbat is enabled -> toggle pwrkey to boot modem.
+ * Hence pull-up (R1117) is preferred.
+ */
+ IMX8DXL_SPI3_SDO_LSIO_GPIO0_IO14 0x0000061
+ >;
+ };
+
+ regulator_usb1_vbus_pins: pinctrl-regulator-usb1-vbus-grp {
+ fsl,pins = <
+ /* regulator enable: open-drain with pull-up & low drive strength */
+ IMX8DXL_SPI3_CS0_LSIO_GPIO0_IO16 0x2000021
+ >;
+ };
+
+ switch_pins: pinctrl-switch-grp {
+ fsl,pins = <
+ /* SW_RSTn: io without pull-up */
+ IMX8DXL_USB_SS3_TC0_LSIO_GPIO4_IO03 0x0000021
+
+ /* SW_CORE_RSTn: io without pull-up */
+ IMX8DXL_USB_SS3_TC1_LSIO_GPIO4_IO04 0x0000021
+
+ /* INT_N: io without pull-up */
+ IMX8DXL_USB_SS3_TC3_LSIO_GPIO4_IO06 0x0000021
+ >;
+ };
+
+ tca6408_u2_int_pins: pinctrl-tca6408-u2-int-grp {
+ fsl,pins = <
+ /* gpio-expander interrupt: io with pull-up */
+ IMX8DXL_MCLK_OUT0_LSIO_GPIO0_IO20 0x0000021
+ >;
+ };
+
+ usdhc3_pins: pinctrl-usdhc3-grp {
+ fsl,pins = <
+ IMX8DXL_ENET0_RGMII_TXC_CONN_USDHC2_CLK 0x06000040
+ IMX8DXL_ENET0_RGMII_TX_CTL_CONN_USDHC2_CMD 0x00000021
+ IMX8DXL_ENET0_RGMII_TXD0_CONN_USDHC2_DATA0 0x00000021
+ IMX8DXL_ENET0_RGMII_TXD1_CONN_USDHC2_DATA1 0x00000021
+ IMX8DXL_ENET0_RGMII_TXD2_CONN_USDHC2_DATA2 0x00000021
+ IMX8DXL_ENET0_RGMII_TXD3_CONN_USDHC2_DATA3 0x00000021
+ >;
+ };
+
+ wifi_pins: pinctrl-wifi-grp {
+ fsl,pins = <
+ /* WL_REG_ON: io without pull (module integrates pd) */
+ IMX8DXL_SPI3_SDI_LSIO_GPIO0_IO15 0x0000061
+ >;
+ };
+};
+
+&lpspi0 {
+ cs-gpios = <&lsio_gpio1 8 GPIO_ACTIVE_LOW>, <&lsio_gpio1 7 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&lpspi0_pins>, <&switch_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ ethernet-switch@0 {
+ compatible = "nxp,sja1110a";
+ reg = <0>;
+ reset-gpios = <&lsio_gpio4 3 GPIO_ACTIVE_LOW>;
+ spi-max-frequency = <4000000>;
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* 100Base-TX on connector J26 */
+ switch_port1: port@1 {
+ reg = <0x1>;
+ phy-handle = <&switch_port1_base_tx_phy>;
+ phy-mode = "internal";
+ };
+
+ /* CPU */
+ switch_port2: port@2 {
+ reg = <0x2>;
+ ethernet = <&eqos>;
+ phy-mode = "rgmii-id";
+ rx-internal-delay-ps = <2000>;
+ tx-internal-delay-ps = <2000>;
+
+ fixed-link {
+ full-duplex;
+ speed = <1000>;
+ };
+ };
+
+ /* sgmii on addon board connector J21 */
+ switch_port3: port@3 {
+ reg = <0x3>;
+ status = "disabled";
+ };
+
+ /* sgmii on addon board connector J21 */
+ switch_port4: port@4 {
+ reg = <0x4>;
+ status = "disabled";
+ };
+
+ /* 100base-t1 on addon board connector J21 */
+ switch_port5: port@5 {
+ reg = <0x5>;
+ phy-handle = <&switch_port5_base_t1_phy>;
+ phy-mode = "internal";
+ status = "disabled";
+ };
+
+ /* 100base-t1 on addon board connector J21 */
+ switch_port6: port@6 {
+ reg = <0x6>;
+ phy-handle = <&switch_port6_base_t1_phy>;
+ phy-mode = "internal";
+ status = "disabled";
+ };
+
+ /* 100base-t1 on addon board connector J21 */
+ switch_port7: port@7 {
+ reg = <0x7>;
+ phy-handle = <&switch_port7_base_t1_phy>;
+ phy-mode = "internal";
+ status = "disabled";
+ };
+
+ /* 100base-t1 on addon board connector J21 */
+ switch_port8: port@8 {
+ reg = <0x8>;
+ phy-handle = <&switch_port8_base_t1_phy>;
+ phy-mode = "internal";
+ status = "disabled";
+ };
+
+ /* 100base-t1 on addon board connector J21 */
+ switch_port9: port@9 {
+ reg = <0x9>;
+ phy-handle = <&switch_port9_base_t1_phy>;
+ phy-mode = "internal";
+ status = "disabled";
+ };
+
+ /* 100Base-T1 on connector J26 */
+ switch_port10: port@a {
+ reg = <0xa>;
+ phy-handle = <&switch_port10_base_t1_phy>;
+ phy-mode = "internal";
+ };
+ };
+
+ mdios {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mdio@0 {
+ compatible = "nxp,sja1110-base-t1-mdio";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* 100base-t1 on addon board connector J21 */
+ switch_port5_base_t1_phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x1>;
+ status = "disabled";
+ };
+
+ /* 100base-t1 on addon board connector J21 */
+ switch_port6_base_t1_phy: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x2>;
+ status = "disabled";
+ };
+
+ /* 100base-t1 on addon board connector J21 */
+ switch_port7_base_t1_phy: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x3>;
+ status = "disabled";
+ };
+
+ /* 100base-t1 on addon board connector J21 */
+ switch_port8_base_t1_phy: ethernet-phy@4 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x4>;
+ status = "disabled";
+ };
+
+ /* 100base-t1 on addon board connector J21 */
+ switch_port9_base_t1_phy: ethernet-phy@5 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x5>;
+ status = "disabled";
+ };
+
+ /* 100Base-T1 on connector J26 */
+ switch_port10_base_t1_phy: ethernet-phy@6 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x6>;
+ };
+ };
+
+ mdio@1 {
+ compatible = "nxp,sja1110-base-tx-mdio";
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* 100Base-TX on connector J26 */
+ switch_port1_base_tx_phy: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+ };
+ };
+};
+
+/* bluetooth */
+&lpuart1 {
+ pinctrl-0 = <&lpuart1_pins>, <&bluetooth_pins>;
+ pinctrl-names = "default";
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "brcm,bcm4345c5";
+ /* Murata 1MW module supports max. 3M baud */
+ max-speed = <3000000>;
+ shutdown-gpios = <&lsio_gpio0 13 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&usbotg1 {
+ dr_mode = "host";
+ vbus-supply = <&vbus1>;
+};
+
+/* cellular modem */
+&usbotg2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ adp-disable;
+ disable-over-current;
+ dr_mode = "host";
+ hnp-disable;
+ pinctrl-0 = <&modem_pins>;
+ pinctrl-names = "default";
+ power-active-high;
+ srp-disable;
+ vbus-supply = <&v_5_0>;
+ status = "okay";
+
+ usb-device@1 {
+ compatible = "usb2c7c,125";
+ reg = <1>;
+ reset-gpios = <&lsio_gpio1 11 GPIO_ACTIVE_LOW>;
+ vbus-supply = <&v_3_3>;
+ vdd-supply = <&modem_vbat>;
+ };
+};
+
+&usbphy2 {
+ status = "okay";
+};
+
+/* WiFi */
+&usdhc3 {
+ bus-width = <4>;
+ cap-sdio-irq;
+ mmc-pwrseq = <&usdhc3_pwrseq>;
+ non-removable;
+ no-sd;
+ pinctrl-0 = <&usdhc3_pins>, <&wifi_pins>;
+ pinctrl-names = "default";
+ vmmc-supply = <&v_3_3>;
+ vqmmc-supply = <&v_1_8>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi
new file mode 100644
index 0000000000000..93a0eb4d7f770
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi
@@ -0,0 +1,458 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022-2026 Josua Mayer <josua@solid-run.com>
+ */
+
+#include "imx8dxl.dtsi"
+/ {
+ compatible = "solidrun,imx8dxl-sr-som", "fsl,imx8dxl";
+ model = "SolidRun i.MX8DXL SoM";
+
+ aliases {
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ serial0 = &lpuart0;
+ serial2 = &lpuart2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ imx8dxl-cm4 {
+ compatible = "fsl,imx8qxp-cm4";
+ clocks = <&clk_dummy>;
+ mboxes = <&lsio_mu5 0 1 &lsio_mu5 1 1 &lsio_mu5 3 1>;
+ mbox-names = "tx", "rx", "rxdb";
+ memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
+ <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>;
+ power-domains = <&pd IMX_SC_R_M4_0_PID0>, <&pd IMX_SC_R_M4_0_MU_1A>;
+ fsl,entry-address = <0x34fe0000>;
+ fsl,resource-id = <IMX_SC_R_M4_0_PID0>;
+ };
+
+ pps {
+ compatible = "pps-gpio";
+ gpios = <&lsio_gpio2 6 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&gnss_pps_pins>;
+ pinctrl-names = "default";
+ };
+
+ v_1_2: regulator-1-2 {
+ compatible = "regulator-fixed";
+ regulator-name = "1v2";
+ pinctrl-0 = <®ulator_1_2_pins>;
+ pinctrl-names = "default";
+ regulator-max-microvolt = <1200000>;
+ regulator-min-microvolt = <1200000>;
+ gpio = <&lsio_gpio1 13 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ v_1_6: regulator-1-6 {
+ compatible = "regulator-fixed";
+ regulator-name = "1v6";
+ pinctrl-0 = <®ulator_1_6_pins>;
+ pinctrl-names = "default";
+ regulator-max-microvolt = <1600000>;
+ regulator-min-microvolt = <1600000>;
+ vin-supply = <&v_1_8>;
+ gpio = <&lsio_gpio1 14 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ v_1_8: regulator-1-8 {
+ compatible = "regulator-fixed";
+ regulator-name = "1v8";
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ };
+
+ v_1_8_se: regulator-1-8-secure-element {
+ compatible = "regulator-fixed";
+ regulator-name = "1v8-se";
+ pinctrl-0 = <®ulator_1_8_se_pins>;
+ pinctrl-names = "default";
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ vin-supply = <&v_1_8>;
+ gpio = <&lsio_gpio3 18 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ v_3_3: regulator-3-3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3v3";
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ };
+
+ reserved-memory {
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x98000000 0 0x14000000>;
+ reusable;
+ size = <0 0x14000000>;
+ linux,cma-default;
+ };
+
+ vdev0vring0: memory0@90000000 {
+ reg = <0 0x90000000 0 0x8000>;
+ no-map;
+ };
+
+ vdev0vring1: memory@90008000 {
+ reg = <0 0x90008000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring0: memory@90010000 {
+ reg = <0 0x90010000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring1: memory@90018000 {
+ reg = <0 0x90018000 0 0x8000>;
+ no-map;
+ };
+
+ rsc_table: memory-rsc-table@900ff000 {
+ reg = <0 0x900ff000 0 0x1000>;
+ no-map;
+ };
+
+ vdevbuffer: memory-vdevbuffer@90400000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x90400000 0 0x100000>;
+ no-map;
+ };
+
+ /*
+ * Memory reserved for optee usage. Please do not use.
+ * This will be automatically added to dtb if OP-TEE is installed.
+ * optee@96000000 {
+ * reg = <0 0x96000000 0 0x2000000>;
+ * no-map;
+ * };
+ */
+ };
+
+ memory@80000000 {
+ reg = <0x00000000 0x80000000 0 0x40000000>;
+ device_type = "memory";
+ };
+};
+
+&i2c2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-1 = <&i2c2_gpio_pins>;
+ pinctrl-names = "default", "gpio";
+ scl-gpios = <&lsio_gpio3 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&lsio_gpio3 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+};
+
+&i2c3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-0 = <&i2c3_pins>;
+ pinctrl-1 = <&i2c3_gpio_pins>;
+ pinctrl-names = "default", "gpio";
+ scl-gpios = <&lsio_gpio3 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&lsio_gpio3 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ magnetometer@1e {
+ compatible = "st,iis2mdc";
+ reg = <0x1e>;
+ interrupt-parent = <&lsio_gpio2>;
+ interrupts = <10 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-0 = <&magnetometer_pins>;
+ pinctrl-names = "default";
+ st,drdy-int-pin = <1>;
+ };
+
+ /* pressure-sensor@5c */
+
+ inertial-sensor@6b {
+ compatible = "st,ism330dhcx";
+ reg = <0x6b>;
+ interrupt-parent = <&lsio_gpio2>;
+ interrupts = <11 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-0 = <&imu_pins>;
+ pinctrl-names = "default";
+ st,drdy-int-pin = <1>;
+ };
+};
+
+&iomuxc {
+ pinctrl-0 = <&pinctrl_hog>;
+ pinctrl-names = "default";
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD 0x000514a0
+ IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHK_PAD 0x000014a0
+ >;
+ };
+
+ dsrc_pins: pinctrl-dsrc-grp {
+ fsl,pins = <
+ /* reset: io without pull */
+ IMX8DXL_ADC_IN0_LSIO_GPIO1_IO10 0x0000060
+
+ /*
+ * boot0: io without pull
+ * After reset, this pin selects radio boot media:
+ * - 0: flash spi
+ * - 1: slave sdio
+ * Once the firmware boots however, the radio controls
+ * this pin for flow-control to signal readiness.
+ */
+ IMX8DXL_ADC_IN1_LSIO_GPIO1_IO09 0x0000060
+ >;
+ };
+
+ gnss_pins: pinctrl-gnss-grp {
+ fsl,pins = <
+ /* gps reset: input with pull-up */
+ IMX8DXL_SNVS_TAMPER_OUT4_LSIO_GPIO2_IO08_IN 0x0000021
+ /* gps interrupt: io without pull-up */
+ IMX8DXL_SNVS_TAMPER_IN0_LSIO_GPIO2_IO09_IN 0x0000061
+ >;
+ };
+
+ gnss_pps_pins: pinctrl-gnss-pps-grp {
+ fsl,pins = <
+ /* gps timepulse: input without pull-up */
+ IMX8DXL_SNVS_TAMPER_OUT2_LSIO_GPIO2_IO06_IN 0x0000061
+ >;
+ };
+
+ i2c2_gpio_pins: pinctrl-i2c2-gpio-grp {
+ fsl,pins = <
+ /* io with pull-up and weak drive */
+ IMX8DXL_SPI1_SCK_LSIO_GPIO3_IO00 0x00000021
+ /* io with pull-up, weak drive, open-drain */
+ IMX8DXL_SPI1_SDO_LSIO_GPIO3_IO01 0x02000021
+ >;
+ };
+
+ i2c2_pins: pinctrl-i2c2-grp {
+ fsl,pins = <
+ /* io with pull-up and weak drive */
+ IMX8DXL_SPI1_SCK_ADMA_I2C2_SDA 0x06000021
+ IMX8DXL_SPI1_SDO_ADMA_I2C2_SCL 0x06000021
+ >;
+ };
+
+ i2c3_gpio_pins: pinctrl-i2c3-gpio-grp {
+ fsl,pins = <
+ /* io with pull-up and weak drive */
+ IMX8DXL_SPI1_CS0_LSIO_GPIO3_IO03 0x00000021
+ /* io with pull-up, weak drive, open-drain */
+ IMX8DXL_SPI1_SDI_LSIO_GPIO3_IO02 0x02000021
+ >;
+ };
+
+ i2c3_pins: pinctrl-i2c3-grp {
+ fsl,pins = <
+ /* io with pull-up and weak drive */
+ IMX8DXL_SPI1_CS0_ADMA_I2C3_SDA 0x06000021
+ IMX8DXL_SPI1_SDI_ADMA_I2C3_SCL 0x06000021
+ >;
+ };
+
+ imu_pins: pinctrl-imu-grp {
+ fsl,pins = <
+ /* interrupt: io with pull-down */
+ IMX8DXL_SNVS_TAMPER_IN2_LSIO_GPIO2_IO11_IN 0x0000041
+ >;
+ };
+
+ lpspi2_pins: pinctrl-lpspi2-grp {
+ fsl,pins = <
+ IMX8DXL_USDHC1_RESET_B_ADMA_SPI2_SCK 0x600004c
+ IMX8DXL_USDHC1_VSELECT_ADMA_SPI2_SDO 0x600004c
+ IMX8DXL_USDHC1_WP_ADMA_SPI2_SDI 0x600004c
+ IMX8DXL_USDHC1_CD_B_LSIO_GPIO4_IO22 0x6000021
+ >;
+ };
+
+ lpuart0_pins: pinctrl-lpuart0-grp {
+ fsl,pins = <
+ IMX8DXL_UART0_RX_ADMA_UART0_RX 0x06000020
+ IMX8DXL_UART0_TX_ADMA_UART0_TX 0x06000020
+ >;
+ };
+
+ lpuart2_pins: pinctrl-lpuart2-grp {
+ fsl,pins = <
+ IMX8DXL_UART2_TX_ADMA_UART2_TX 0x06000020
+ IMX8DXL_UART2_RX_ADMA_UART2_RX 0x06000020
+ >;
+ };
+
+ magnetometer_pins: pinctrl-magnetometer-grp {
+ fsl,pins = <
+ /* interrupt: io with pull-down */
+ IMX8DXL_SNVS_TAMPER_IN1_LSIO_GPIO2_IO10_IN 0x0000041
+ >;
+ };
+
+ regulator_1_2_pins: pinctrl-regulator-1-2-grp {
+ fsl,pins = <
+ /* io without pull-up */
+ /* has etxernal pull-down */
+ IMX8DXL_ADC_IN5_LSIO_GPIO1_IO13 0x0000061
+ >;
+ };
+
+ regulator_1_6_pins: pinctrl-regulator-1-6-grp {
+ fsl,pins = <
+ /* io without pull-up */
+ /* has etxernal pull-down */
+ IMX8DXL_ADC_IN4_LSIO_GPIO1_IO14 0x0000061
+ >;
+ };
+
+ regulator_1_8_se_pins: pinctrl-regulator-1-8-secure-element-grp {
+ fsl,pins = <
+ /* v2x-secure-element power switch: io with pull-down */
+ IMX8DXL_QSPI0B_DATA0_LSIO_GPIO3_IO18 0x0000041
+ >;
+ };
+
+ se_pins: pinctrl-secure-element-grp {
+ fsl,pins = <
+ /* v2x-secure-element reset: io with pull-up */
+ IMX8DXL_QSPI0B_DATA1_LSIO_GPIO3_IO19 0x0000021
+
+ /*
+ * v2x-secure-element gpio0: io with pull-up
+ * pulled low by sxf after boot indicating ready for commands
+ */
+ IMX8DXL_QSPI0B_DATA2_LSIO_GPIO3_IO20 0x0000021
+
+ /* v2x-secure-element gpio1: io with pull-up */
+ IMX8DXL_QSPI0B_DATA3_LSIO_GPIO3_IO21 0x0000021
+ >;
+ };
+
+ usdhc1_pins: pinctrl-usdhc1-grp {
+ fsl,pins = <
+ IMX8DXL_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ IMX8DXL_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ IMX8DXL_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ IMX8DXL_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ IMX8DXL_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ IMX8DXL_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ IMX8DXL_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ IMX8DXL_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ IMX8DXL_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ IMX8DXL_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ IMX8DXL_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041
+ IMX8DXL_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000061
+ >;
+ };
+
+ usdhc2_pins: pinctrl-usdhc2-grp {
+ fsl,pins = <
+ IMX8DXL_ENET0_RGMII_RXC_CONN_USDHC1_CLK 0x06000040
+ IMX8DXL_ENET0_RGMII_RX_CTL_CONN_USDHC1_CMD 0x00000021
+ IMX8DXL_ENET0_RGMII_RXD0_CONN_USDHC1_DATA0 0x00000021
+ IMX8DXL_ENET0_RGMII_RXD1_CONN_USDHC1_DATA1 0x00000021
+ IMX8DXL_ENET0_RGMII_RXD2_CONN_USDHC1_DATA2 0x00000021
+ IMX8DXL_ENET0_RGMII_RXD3_CONN_USDHC1_DATA3 0x00000021
+ >;
+ };
+};
+
+&lpspi2 {
+ cs-gpios = <&lsio_gpio4 22 GPIO_ACTIVE_LOW>;
+ num-cs = <1>;
+ pinctrl-0 = <&lpspi2_pins>, <&se_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+/* console */
+&lpuart0 {
+ pinctrl-0 = <&lpuart0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+/* gnss */
+&lpuart2 {
+ pinctrl-0 = <&lpuart2_pins>, <&gnss_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&lsio_gpio3 {
+ gpio-line-names = "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "SXF_RST", "SXF_GPIO0", "SXF_GPIO1", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&lsio_mu5 {
+ status = "okay";
+};
+
+/* OTG port for boot */
+&usbotg1 {
+ adp-disable;
+ disable-over-current;
+ dr_mode = "peripheral";
+ hnp-disable;
+ power-active-high;
+ srp-disable;
+ status = "okay";
+};
+
+&usbphy1 {
+ status = "okay";
+};
+
+/* eMMC */
+&usdhc1 {
+ bus-width = <8>;
+ cap-mmc-hw-reset;
+ non-removable;
+ no-sd;
+ no-sdio;
+ pinctrl-0 = <&usdhc1_pins>;
+ pinctrl-1 = <&usdhc1_pins>;
+ pinctrl-2 = <&usdhc1_pins>;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ vmmc-supply = <&v_3_3>;
+ vqmmc-supply = <&v_1_8>;
+ status = "okay";
+};
+
+/* DSRC Radio */
+&usdhc2 {
+ bus-width = <4>;
+ keep-power-in-suspend;
+ max-frequency = <40000000>;
+ non-removable;
+ no-sd;
+ pinctrl-0 = <&usdhc2_pins>, <&dsrc_pins>;
+ pinctrl-names = "default";
+ vmmc-supply = <&v_3_3>;
+ vqmmc-supply = <&v_1_8>;
+ status = "okay";
+};
--
2.51.0
^ permalink raw reply related
* [PATCH v5 1/2] dt-bindings: arm: fsl: Add SolidRun i.MX8DXL SoM and HummingBoard
From: Josua Mayer @ 2026-05-13 10:32 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: Yazan Shhady, Mikhail Anikin, Alexander Dahl, devicetree,
linux-kernel, imx, linux-arm-kernel, Vladimir Oltean,
Conor Dooley, Krzysztof Kozlowski, netdev, Josua Mayer,
Krzysztof Kozlowski
In-Reply-To: <20260513-imx8dxl-sr-som-v5-0-d0899b371c38@solid-run.com>
Add binding for the SolidRun i.MX8DXL based System on Module, and the
reference HummingBoard Telematics.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
Documentation/devicetree/bindings/arm/fsl.yaml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 0023cd1268075..17cd47e8efce8 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -1394,6 +1394,13 @@ properties:
- fsl,imx8dxl-evk # i.MX8DXL EVK Board
- const: fsl,imx8dxl
+ - description: SolidRun i.MX8DXL SoM based boards
+ items:
+ - enum:
+ - solidrun,imx8dxl-hummingboard-telematics # SolidRun i.MX8DXL SoM EVK Board
+ - const: solidrun,imx8dxl-sr-som
+ - const: fsl,imx8dxl
+
- description: i.MX8QXP/i.MX8DX Boards with Toradex Colibri iMX8X Modules
items:
- enum:
--
2.51.0
^ permalink raw reply related
* Re: [PATCH 1/3] dt-bindings: soc: imx: fsl,imx93-media-blk-ctrl: Allow LVDS Display Bridge child node
From: Marco Felsch @ 2026-05-13 10:29 UTC (permalink / raw)
To: Liu Ying
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Peng Fan,
devicetree, linux-kernel, linux-arm-kernel, imx
In-Reply-To: <20260513-imx93-ldb-v1-1-d11c5c3cc197@nxp.com>
Hi Liu,
can we please wait for the outcome of this dicussion:
https://lore.kernel.org/all/uyh5s6g7bvuufnhfjrmungp5dbyllxfrgfzaxno22knpxxojmj@qqvh75ezblpp/
before we're going further?
Regards,
Marco
On 26-05-13, Liu Ying wrote:
> i.MX93 SoC mediamix blk-ctrl contains one LDB_CTRL register and one LVDS
> register which control video output through a LVDS interface. Allow the
> LVDS Display Bridge(LDB) child node and add the child node to example.
>
> Signed-off-by: Liu Ying <victor.liu@nxp.com>
> ---
> .../bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml | 38 ++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml
> index d828c2e82965..ab563b457e07 100644
> --- a/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml
> +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml
> @@ -26,6 +26,12 @@ properties:
> reg:
> maxItems: 1
>
> + '#address-cells':
> + const: 1
> +
> + '#size-cells':
> + const: 1
> +
> '#power-domain-cells':
> const: 1
>
> @@ -92,6 +98,11 @@ properties:
> - compatible
> - ports
>
> + bridge@20:
> + type: object
> + $ref: /schemas/display/bridge/fsl,ldb.yaml#
> + unevaluatedProperties: false
> +
> allOf:
> - if:
> properties:
> @@ -163,6 +174,8 @@ examples:
> <&clk IMX93_CLK_MIPI_DSI_GATE>;
> clock-names = "apb", "axi", "nic", "disp", "cam",
> "pxp", "lcdif", "isi", "csi", "dsi";
> + #address-cells = <1>;
> + #size-cells = <1>;
> #power-domain-cells = <1>;
>
> dpi-bridge {
> @@ -190,4 +203,29 @@ examples:
> };
> };
> };
> +
> + bridge@20 {
> + compatible = "fsl,imx93-ldb";
> + reg = <0x20 0x4>, <0x24 0x4>;
> + reg-names = "ldb", "lvds";
> + clocks = <&clk IMX93_CLK_LVDS_GATE>;
> + clock-names = "ldb";
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> +
> + endpoint {
> + remote-endpoint = <&lcdif_to_ldb>;
> + };
> + };
> +
> + port@1 {
> + reg = <1>;
> + };
> + };
> + };
> };
>
> --
> 2.43.0
>
>
>
--
#gernperDu
#CallMeByMyFirstName
Pengutronix e.K. | |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
^ permalink raw reply
* Re: [PATCH v4 02/15] mm: Make empty_zero_page __ro_after_init
From: Mike Rapoport @ 2026-05-13 10:28 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Jann Horn, Ard Biesheuvel, linux-arm-kernel, linux-kernel,
Will Deacon, Catalin Marinas, Mark Rutland, Ryan Roberts,
Anshuman Khandual, Liz Prucka, Seth Jenkins, Kees Cook,
David Hildenbrand, Andrew Morton, linux-mm, linux-hardening
In-Reply-To: <49d30ffe-b7e1-4b05-89e0-c3fe01348bb6@app.fastmail.com>
On Wed, May 13, 2026 at 10:53:08AM +0200, Ard Biesheuvel wrote:
>
> On Wed, 13 May 2026, at 10:50, Mike Rapoport wrote:
> > On Tue, May 12, 2026 at 02:56:16PM +0200, Ard Biesheuvel wrote:
> >> On Mon, 11 May 2026, at 16:40, Jann Horn wrote:
> >> > On Mon, May 11, 2026 at 10:59 AM Ard Biesheuvel <ardb@kernel.org> wrote:
> >> >> I think we should simply do something along the lines of the below,
> >> >> considering that the size of a data object tends to correlate with
> >> >> its minimum alignment.
> >> >>
> >> >> I do find it rather puzzling that the compiler emits empty_zero_page
> >> >> *after* zero_page_pfn - ideally, we'd combine the below with
> >> >> -fdata-sections so that the linker sees all individual objects, but
> >> >> I suspect that would create some problems elsewhere.
> >> >>
> >> >>
> >> >> --- a/include/asm-generic/vmlinux.lds.h
> >> >> +++ b/include/asm-generic/vmlinux.lds.h
> >> >> @@ -452,7 +452,7 @@
> >> >> #define RO_AFTER_INIT_DATA \
> >> >> . = ALIGN(8); \
> >> >> __start_ro_after_init = .; \
> >> >> - *(.data..ro_after_init) \
> >> >> + *(SORT_BY_ALIGNMENT(.data..ro_after_init)) \
> >> >
> >> > Oh, neat, I didn't realize that's possible. That seems like a nicer
> >> > approach...
> >>
> >> Neat but rather ineffective, unfortunately. (I don't see a size
> >> difference with the arm64 defconfig kernel)
> >>
> >> Given that empty_zero_page only ever gets its address taken, we
> >> might just move it into the linker script if that requires tweaking
> >> anyway. We can just place it at the start of .rodata, which is
> >> already page aligned on most architectures (and will become page
> >> aligned unless EMPTY_ZERO_PAGE is #define'd by the arch linker
> >> script to something else)
> >>
> >>
> >> --- a/include/asm-generic/vmlinux.lds.h
> >> +++ b/include/asm-generic/vmlinux.lds.h
> >> @@ -472,6 +472,17 @@
> >> #endif
> >> #endif
> >>
> >> +#ifndef EMPTY_ZERO_PAGE
> >> +#ifndef __HAVE_COLOR_ZERO_PAGE
> >
> > I don't think we want let architectures that don't use colored zero pages
> > redefine it.
> > If it will be really required we can add the ability to redefine
> > EMPTY_ZERO_PAGE later.
> >
>
> I was actually intending to add use this for arm64 in the next patch. It
> already has a reserved_pg_dir in .rodata which is page-sized (i.e., up
> to 64k in size) and guaranteed to remain all zeroes, so empty_zero_page
> could actually be an alias for that. This is what I had in a previous
> revision, before you turned the empty_zero_page definition into common
> code:
Works for me if from arm64 perspective that's ok :)
> https://lore.kernel.org/all/20260320145934.2349881-16-ardb+git@google.com/
--
Sincerely yours,
Mike.
^ permalink raw reply
* Re: [PATCH 2/4] Revert "dt-bindings: display: bridge: ldb: Fill in reg property"
From: Marco Felsch @ 2026-05-13 10:26 UTC (permalink / raw)
To: Rob Herring
Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter,
Krzysztof Kozlowski, Conor Dooley, Marek Vasut, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
laurentiu.palcu, victor.liu, dri-devel, devicetree, linux-kernel,
imx, linux-arm-kernel
In-Reply-To: <CAL_JsqJWyRPh_hmJW8p7+VvtcqpS0a_azjMO-PyQgkqQUfLAGA@mail.gmail.com>
On 26-05-07, Rob Herring wrote:
> On Thu, May 7, 2026 at 6:55 AM Marco Felsch <m.felsch@pengutronix.de> wrote:
...
> > > But nowhere have you said the LDB registers are mixed with other
> > > functions. If they aren't, then there is absolutely nothing to change
> > > in the binding. If they are, then yes, we shouldn't have 'reg'.
> >
> > No they aren't mixed with other functions (for now).
>
> For now? Is the h/w going to change or is the binding *still* incomplete.
Sorry for the confusion. By for now I mean that NXP tend to reuse IPs
but with minor changes. So no, the binding is not incomplete with our
current HW knowledge.
> > Can you please
> > confirm that mixing 'reg' based sub-device nodes with non 'reg' based
> > sub-device nodes is allowed? E.g. if the below example is allowed?
> >
> > system-controller@4ac10000 {
> > compatible = "fsl,imx93-media-blk-ctrl", "syscon";
> > reg = <0x4ac10000 0x10000>;
> > #address-cells = <1>;
> > #size-cells = <1>;
> >
> > ...
> >
> > bridge@5c {
> > compatible = "fsl,imx8mp-ldb";
> > reg = <0x5c 0x4>, <0x128 0x4>;
> > reg-names = "ldb", "lvds";
> >
> > ...
> > };
> >
> > dpi-bridge {
> > compatible = "nxp,imx93-pdfc";
> >
> > ...
>
> Depends what is in "...". If only a compatible, then no. If there are
> actual resources defined, then yes.
Please see the below full example, is this allowed?
system-controller@4ac10000 {
compatible = "fsl,imx93-media-blk-ctrl", "syscon";
reg = <0x4ac10000 0x10000>;
#address-cells = <1>;
#size-cells = <1>;
...
bridge@5c {
compatible = "fsl,imx8mp-ldb";
reg = <0x5c 0x4>, <0x128 0x4>;
reg-names = "ldb", "lvds";
clocks = <&clk IMX8MP_CLK_MEDIA_LDB_ROOT>;
clock-names = "ldb";
assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>;
assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>;
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
ldb_from_lcdif2: endpoint {
remote-endpoint = <&lcdif2_to_ldb>;
};
};
port@1 {
reg = <1>;
ldb_lvds_ch0: endpoint {
};
};
port@2 {
reg = <2>;
ldb_lvds_ch1: endpoint {
};
};
};
};
dpi-bridge {
compatible = "nxp,imx93-pdfc";
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dpi_from_lcdif: endpoint {
remote-endpoint = <&lcdif_to_dpi>;
};
};
port@1 {
reg = <1>;
dpi_to_panel: endpoint {
};
};
};
};
};
> > Furthermore I thought that for the MMIO bridge@5c device, the 'reg'
> > porperty would either require the full register address, e.g. 0x4ac1005c
> > or there needs to be a ranges property.
>
> There should be a ranges property no matter what.
Good point, something to fix too :/
Regards,
Marco
^ permalink raw reply
* Re: [PATCH 2/2] arm64: dts: amlogic: t7: khadas-vim4: add PWM-driven status LED
From: Ronald Claveau @ 2026-05-13 10:26 UTC (permalink / raw)
To: Neil Armstrong
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
In-Reply-To: <7ad282ae-fffa-4d0a-9cec-65d8f6b40544@linaro.org>
On 5/13/26 10:05 AM, Neil Armstrong wrote:
> On 5/12/26 19:47, Ronald Claveau via B4 Relay wrote:
>> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>>
>> The VIM4 board exposes a status LED wired to the PWM_AO_C_D output.
>> Enable the pwm_ao_cd controller with its pinmux, and declare a
>> pwm-leds node with a heartbeat trigger.
>>
>> Also, move the xtal-clk node to restore alphabetical ordering.
>
> Please send a separate patch for that
>
Thanks for your review, I will add a new patch.
>>
>> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
>> ---
>> .../dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 30 ++++++++++++
>> +++++-----
>> 1 file changed, 23 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-
>> vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
>> index 69d6118ba57e7..c41525a34b721 100644
>> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
>> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
>> @@ -45,13 +45,6 @@ secmon_reserved_bl32: secmon@5300000 {
>> };
>> };
>> - xtal: xtal-clk {
>> - compatible = "fixed-clock";
>> - clock-frequency = <24000000>;
>> - clock-output-names = "xtal";
>> - #clock-cells = <0>;
>> - };
>> -
>> dc_in: regulator-dc-in {
>> compatible = "regulator-fixed";
>> regulator-name = "DC_IN";
>> @@ -60,6 +53,16 @@ dc_in: regulator-dc-in {
>> regulator-always-on;
>> };
>> + pwm-leds {
>> + compatible = "pwm-leds";
>> +
>> + status {
>> + linux,default-trigger="heartbeat";
>> + max-brightness = <255>;
>> + pwms = <&pwm_ao_cd 0 30040 0>;
>> + };
>> + };
>> +
>> sd_3v3: regulator-sdcard-3v3 {
>> compatible = "regulator-fixed";
>> regulator-name = "SD_3V3";
>> @@ -155,6 +158,13 @@ wifi32k: wifi32k {
>> clock-frequency = <32768>;
>> pwms = <&pwm_ab 0 30518 0>;
>> };
>> +
>> + xtal: xtal-clk {
>> + compatible = "fixed-clock";
>> + clock-frequency = <24000000>;
>> + clock-output-names = "xtal";
>> + #clock-cells = <0>;
>> + };
>> };
>> &pwm_ab {
>> @@ -163,6 +173,12 @@ &pwm_ab {
>> pinctrl-names = "default";
>> };
>> +&pwm_ao_cd {
>> + status = "okay";
>> + pinctrl-0 = <&pwm_ao_c_d_pins>;
>> + pinctrl-names = "default";
>> +};
>> +
>> /* SDIO */
>> &sd_emmc_a {
>> status = "okay";
>>
>
--
Best regards,
Ronald
^ permalink raw reply
* Re: [PATCH] perf arm-spe: Don't warn about the discard bit if it doesn't exist
From: Leo Yan @ 2026-05-13 10:20 UTC (permalink / raw)
To: James Clark
Cc: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
linux-arm-kernel, linux-perf-users, linux-kernel
In-Reply-To: <20260410-james-spe-discard-warning-v1-1-985c02756ee4@linaro.org>
On Fri, Apr 10, 2026 at 12:05:12PM +0100, James Clark wrote:
> Opening an SPE event shows a warning that doesn't concern the user:
>
> $ perf record -e arm_spe
> Unknown/empty format name: discard
>
> Perf only wants to know if the discard bit is set for configuring the
> event, not in response to anything the user has done. Fix it by adding
> another helper that returns if a config bit exists without warning.
>
> We should probably keep the warning in evsel__get_config_val() to avoid
> having every caller having to do it, and most format bits should never
> be missing.
>
> Add a test for the new helper. Rename the parent test function to be
> more generic rather than adding a new one as it requires a lot of
> boilerplate.
>
> Signed-off-by: James Clark <james.clark@linaro.org>
Reviewed-by: Leo Yan <leo.yan@arm.com>
^ permalink raw reply
* Re: [RFC PATCH 0/4] arm64: realm: Support for probing RSI earlier
From: Suzuki K Poulose @ 2026-05-13 10:17 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will, ardb,
mark.rutland, steven.price, aneesh.kumar, sudeep.holla, robh, maz
In-Reply-To: <af3DiIibnKvu+Tpt@lpieralisi>
On 08/05/2026 12:05, Lorenzo Pieralisi wrote:
> On Fri, May 08, 2026 at 09:28:32AM +0100, Suzuki K Poulose wrote:
>> Hi Lorenzo,
>>
>>
>> On 08/05/2026 09:09, Lorenzo Pieralisi wrote:
>>> On Wed, Apr 29, 2026 at 11:35:31AM +0100, Suzuki K Poulose wrote:
>>>> The Realm Guest linux support is broken without rodata=full (fortunately default
>>>> for arm64), as we detect the RSI support after we have created the Linear map
>>>> with Block/Contiguous mappings. If the boot CPU doesn't support BBML2_NOABORT
>>>> (there are CPUs out there with FEAT_RME and no - useable - BBML2_NOABORT)
>>>> we are then not able to split the page tables down to PTE level if the system
>>>> as such doesn't support BBML2.
>>>>
>>>> See the following link for the discussion.
>>>>
>>>> https://lore.kernel.org/all/20260330161705.3349825-2-ryan.roberts@arm.com/
>>>>
>>>> The available options are :
>>>> 1. Start with PTE level mappings at paging_init() and then "FOLD" the page tables
>>>> to Block/Cont mappings after we have the full picture available. Looking at the
>>>> future (with BBML3), this might mean "additional work" for most of the systems
>>>> at boot. But not bad as splitting them ?
>>>> 2. Hold the secondary CPUs in busy loop with MMU disabled and split the mappings
>>>> by the boot CPU with MMU off (if Boot CPU can't support BBML2). This is tricky
>>>> with the page allocations required to add the page-tables.
>>>> 3. Move the detection of Realm support earlier to make a better decision for
>>>> paging_init(), with an added bonus of earlycon support for Realms without
>>>> the user having to work out the "top bit" for the Realm.
>>>>
>>>> This series is an attempt to implement (3) (without the earlycon support). We try
>>>> to probe the PSCI conduit early from the DT/ACPI. DT is not flattened at this time.
>>>
>>> Nit: you mean unflattened here.
>>
>> Yep, thats right.
>>
>>>
>>>> ACPI table is not mapped in full, so we have to map one table at a time and walk
>>>> from the Root of the table (RSDP) through to XSDT and find the FADT table from
>>>> the array of table pointers there. Minimal verification is performed on the
>>>> tables (e.g., revision checks, standard FADT sanity checks). Checksum is not
>>>> verified, but should be possible to do for the parts we consume.
>>>
>>> I went back to tracing acpi_boot_table_init() (joy :)) and it does what you
>>
>> Welcome back ;-)
>>
>>> describe here above (it has been a while since I touched that code) relying on
>>> early_memremap() mappings (as you re-do in this series) before acpi_permanent_mmap
>>> is set in acpi_early_init() (that happens later in the boot process).
>>>
>>> I am sure there are caveats in moving acpi_boot_table_init() before
>>> paging_init() but I thought I'd mention it in case (3) is what we are
>>> pursuing (I am most definitely in favour of alternatives if there are
>>> any).
>>
>> I believe we might have issues with acpi_table_upgrade(), which would
>> need access to initramfs for any tables. We may not have the initramfs
>> mapped by then ? Anyways, FADT cannot be upgraded from the initramfs,
>
> I think it can:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/tables.c?h=v7.1-rc2#n407
Oh! I misread the FACS as FADT :facepalm:
Thank you for correcting me.
>
> Obviously this is a debugging/bootstrapping tool but hey, here we go.
>
>> so if we can work out a way to do the necessary may be something
>> worth checking.
>
> I don't think we can init the tables before enabling the upgrade (which
> requires reading from initrd).
>
> I will try to think a bit more to see whether we can reuse some code
> (again - if that's what we eventually want to do).
I will continue to explore this too.
Much appreciated
Cheers
Suzuki
>
> Lorenzo
>
>>>
>>>> With arm64, during the normal boot, we could fallback to using DT if the ACPI
>>>> tables are not useable. So, during the early probe, we try to follow the similar
>>>> logic and probe the conduit from both DT and ACPI where available. If both of
>>>> them contain a conduit, we only proceed if they match. Otherwise, we skip the
>>>> early probe and do things the normal way. (Any sane system shouldn't have such
>>>> a mismatch, but..)
>>>>
>>>> Once we probe the PSCI conduit, PSCI is probed, along with the presence of SMCCC.
>>>> With that in place, we try to probe the RSI support after the early probe and
>>>> advertise the Realm World. If the early probe wasn't successful, we fall back
>>>> to the late mode, where we could end up with (on a possibly rare broken firmware).
>>>>
>>>> NOTE: This is an early RFC attempt to moving the PSCI detection earlier. The other
>>>> option(s) that may be worth exploring are:
>>>>
>>>> 1. On systems with EFI, parse this from EFI Stub and pass the data back in the
>>>> DT Stub, under chosen node. e.g., "linux,uefi-arm-psci-conduit".
>>>> Challenge: EFI stub doesn't seem to be ACPI aware. We could make that change,
>>>> we only need a few table walks.
>>>
>>> What would we gain compared to (3) above ?
>>
>> EFI stub has 1x1 map for the areas and we don't have to do the map/unmap
>> dancein the kernel and potentially end up crashing ourselves.
>>
>> Suzuki
>>
>>>
>>> Thanks,
>>> Lorenzo
>>>
>>>> 2. Have EFI firmware provide this information (with my limited knowledge on the
>>>> area, this looks like too much work, and bending the standards)
>>>> 3. Append arm64 boot protocol to have this information passed to the kernel.
>>>> (Firmware provided) - (Steven's idea)
>>>> 4. Any other options ?
>>>>
>>>>
>>>> This series is also available here :
>>>>
>>>> git@git.gitlab.arm.com:linux-arm/linux-cca.git cca-guest/early-rsi-detection/rfc-v1
>>>>
>>>> Thoughts ?
>>>>
>>>> Suzuki
>>>>
>>>>
>>>> Suzuki K Poulose (4):
>>>> arm64: acpi: Refactor FADT table verification
>>>> psci: Add support for Early detection and init
>>>> arm64: psci: Move detection and SMCCC probe earlier
>>>> arm64: realm: Move RSI detection earlier
>>>>
>>>> arch/arm64/include/asm/acpi.h | 1 +
>>>> arch/arm64/include/asm/rsi.h | 1 +
>>>> arch/arm64/kernel/acpi.c | 136 +++++++++++++++++++++++++++-------
>>>> arch/arm64/kernel/rsi.c | 23 +++++-
>>>> arch/arm64/kernel/setup.c | 69 +++++++++++++++++
>>>> drivers/firmware/psci/psci.c | 49 +++++++++++-
>>>> include/linux/psci.h | 2 +
>>>> 7 files changed, 252 insertions(+), 29 deletions(-)
>>>>
>>>> --
>>>> 2.43.0
>>>>
>>
^ permalink raw reply
* [PATCH v3 1/3] i2c: xiic: preserve PEC byte length in SMBus block read setup
From: Abdurrahman Hussain @ 2026-05-13 10:09 UTC (permalink / raw)
To: Michal Simek, Andi Shyti
Cc: linux-arm-kernel, linux-i2c, linux-kernel, Abdurrahman Hussain
In-Reply-To: <20260513-i2c-xiic-v3-0-ccb3cf70ba03@nexthop.ai>
xiic_smbus_block_read_setup() recalculates i2c->rx_msg->len based on the
length byte returned by the device, but historically clobbered the PEC
byte expectation the SMBus core had baked into msg->len. That dropped
the PEC byte from the caller's buffer on the normal and chunked
receive-fifo branches.
Compute pec_len up-front as (i2c->rx_msg->len - 1) and add it to the
new length in every branch:
- chunked (rxmsg_len + pec_len > IIC_RX_FIFO_DEPTH): set the drain
target to rxmsg_len + 1 + pec_len.
- deferred (small enough to drain in one fill but >= MIN_LEN total):
same.
- padded (1 + rxmsg_len + pec_len < SMBUS_BLOCK_READ_MIN_LEN): the
hardware needs at least 3 bytes on the bus to exit the read
cleanly (the second byte is already being clocked in by the time
the ISR reads the length byte and is too late to NACK), so we
still pad rx_msg->len up to SMBUS_BLOCK_READ_MIN_LEN. The dummy
trailing byte that gets drained must then be trimmed off before
handing the message back to the SMBus core; otherwise
i2c_smbus_check_pec() reads buf[len-1] (= dummy) instead of the
real PEC byte at buf[1] and rejects every clean zero-length block
read with -EBADMSG.
Record the true valid byte count in a new field
i2c->smbus_actual_len and have xiic_process()'s RX_FULL completion
site trim rx_msg->len down to it before clearing rx_msg.
Widen the branch condition from the old "(rxmsg_len == 1) ||
(rxmsg_len == 0)" to "(1 + rxmsg_len + pec_len) < MIN_LEN" so that
user requests with multi-byte trailing bytes (e.g. pec_len == 2 on
a zero-length block) flow through the deferred branch instead of
getting truncated to MIN_LEN here.
Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
---
drivers/i2c/busses/i2c-xiic.c | 40 +++++++++++++++++++++++++++++++++-------
1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index 3e7735e1dae0..d4308716d461 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -73,6 +73,11 @@ enum i2c_scl_freq {
* @prev_msg_tx: Previous message is Tx
* @quirks: To hold platform specific bug info
* @smbus_block_read: Flag to handle block read
+ * @smbus_actual_len: For SMBus block reads padded to SMBUS_BLOCK_READ_MIN_LEN,
+ * the number of bytes that are actually valid (length byte + payload +
+ * optional PEC). msg->len gets trimmed to this on transfer completion so
+ * the SMBus core sees the real PEC byte and not the trailing dummy.
+ * Zero when no trimming is needed.
* @input_clk: Input clock to I2C controller
* @i2c_clk: I2C SCL frequency
* @atomic: Mode of transfer
@@ -98,6 +103,7 @@ struct xiic_i2c {
bool prev_msg_tx;
u32 quirks;
bool smbus_block_read;
+ unsigned int smbus_actual_len;
unsigned long input_clk;
unsigned int i2c_clk;
bool atomic;
@@ -539,6 +545,8 @@ static void xiic_smbus_block_read_setup(struct xiic_i2c *i2c)
/* Check if received length is valid */
if (rxmsg_len <= I2C_SMBUS_BLOCK_MAX) {
+ unsigned int pec_len = i2c->rx_msg->len - 1;
+
/* Set Receive fifo depth */
if (rxmsg_len > IIC_RX_FIFO_DEPTH) {
/*
@@ -546,23 +554,30 @@ static void xiic_smbus_block_read_setup(struct xiic_i2c *i2c)
* Receive fifo depth should set to Rx fifo capacity minus 1
*/
rfd_set = IIC_RX_FIFO_DEPTH - 1;
- i2c->rx_msg->len = rxmsg_len + 1;
- } else if ((rxmsg_len == 1) ||
- (rxmsg_len == 0)) {
+ i2c->rx_msg->len = rxmsg_len + 1 + pec_len;
+ } else if (1 + rxmsg_len + pec_len < SMBUS_BLOCK_READ_MIN_LEN) {
/*
- * Minimum of 3 bytes required to exit cleanly. 1 byte
- * already received, Second byte is being received. Have
- * to set NACK in read_rx before receiving the last byte
+ * Hardware requires at least SMBUS_BLOCK_READ_MIN_LEN
+ * bytes on the bus to exit the read cleanly: by the
+ * time the ISR pulls the length byte from the FIFO,
+ * the second byte is already being clocked in and
+ * cannot be NACKed in time. Pad the drain target so
+ * the HW reaches the minimum, but remember the true
+ * valid byte count and trim msg->len back on transfer
+ * completion -- otherwise the SMBus core's PEC check
+ * reads the trailing dummy byte instead of the real
+ * PEC byte and rejects clean transfers with -EBADMSG.
*/
rfd_set = 0;
i2c->rx_msg->len = SMBUS_BLOCK_READ_MIN_LEN;
+ i2c->smbus_actual_len = 1 + rxmsg_len + pec_len;
} else {
/*
* When Rx msg len less than Rx fifo capacity
* Receive fifo depth should set to Rx msg len minus 2
*/
rfd_set = rxmsg_len - 2;
- i2c->rx_msg->len = rxmsg_len + 1;
+ i2c->rx_msg->len = rxmsg_len + 1 + pec_len;
}
xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rfd_set);
@@ -797,6 +812,17 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
xiic_read_rx(i2c);
if (xiic_rx_space(i2c) == 0) {
+ /*
+ * If the setup path padded a short SMBus block read up
+ * to SMBUS_BLOCK_READ_MIN_LEN for the HW exit
+ * workaround, trim rx_msg->len back to the number of
+ * bytes that are actually valid so the SMBus core's
+ * PEC check reads the right index. Must happen before
+ * the rx_msg = NULL below.
+ */
+ if (i2c->rx_msg && i2c->smbus_actual_len)
+ i2c->rx_msg->len = i2c->smbus_actual_len;
+
/* this is the last part of the message */
i2c->rx_msg = NULL;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 2/3] i2c: xiic: defer RX_FULL until all trailing bytes are in FIFO
From: Abdurrahman Hussain @ 2026-05-13 10:09 UTC (permalink / raw)
To: Michal Simek, Andi Shyti
Cc: linux-arm-kernel, linux-i2c, linux-kernel, Abdurrahman Hussain
In-Reply-To: <20260513-i2c-xiic-v3-0-ccb3cf70ba03@nexthop.ai>
For the normal path of xiic_smbus_block_read_setup() (rxmsg_len less
than IIC_RX_FIFO_DEPTH), RFD was programmed to rxmsg_len - 2, which
fires the RX_FULL interrupt while the last payload byte is still in
flight. xiic_read_rx()'s bytes_rem == 1 branch then sets NACK on that
byte still on the wire, truncating the read in the PEC-enabled case.
Raise the threshold so RX_FULL fires only once every remaining byte
(payload plus optional PEC) is already buffered in the FIFO. That
routes the drain through xiic_read_rx()'s bytes_rem == 0 path, which
reads everything out and emits the stop cleanly. For the non-PEC path
the full payload is still read out through the same bytes_rem == 0
branch; the only user-visible change is that the controller waits one
extra byte-time before servicing the interrupt.
The deferred-fire formula is rxmsg_len + pec_len - 1, and the RFD
register at XIIC_RFD_REG_OFFSET is a 4-bit field. Widen the
chunk-vs-defer guard to (rxmsg_len + pec_len > IIC_RX_FIFO_DEPTH) so
the boundary case rxmsg_len == IIC_RX_FIFO_DEPTH with PEC enabled
cannot write 16 into that 4-bit register; it routes through the
chunked drain instead, which already caps RFD at IIC_RX_FIFO_DEPTH - 1.
Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
---
drivers/i2c/busses/i2c-xiic.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index d4308716d461..2bdba6c0931f 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -548,10 +548,11 @@ static void xiic_smbus_block_read_setup(struct xiic_i2c *i2c)
unsigned int pec_len = i2c->rx_msg->len - 1;
/* Set Receive fifo depth */
- if (rxmsg_len > IIC_RX_FIFO_DEPTH) {
+ if (rxmsg_len + pec_len > IIC_RX_FIFO_DEPTH) {
/*
- * When Rx msg len greater than or equal to Rx fifo capacity
- * Receive fifo depth should set to Rx fifo capacity minus 1
+ * Trailing payload (data + optional PEC) exceeds Rx FIFO
+ * capacity; drain in chunks. Fire RX_FULL when the FIFO is
+ * full and let the ISR re-arm for the remainder.
*/
rfd_set = IIC_RX_FIFO_DEPTH - 1;
i2c->rx_msg->len = rxmsg_len + 1 + pec_len;
@@ -572,11 +573,8 @@ static void xiic_smbus_block_read_setup(struct xiic_i2c *i2c)
i2c->rx_msg->len = SMBUS_BLOCK_READ_MIN_LEN;
i2c->smbus_actual_len = 1 + rxmsg_len + pec_len;
} else {
- /*
- * When Rx msg len less than Rx fifo capacity
- * Receive fifo depth should set to Rx msg len minus 2
- */
- rfd_set = rxmsg_len - 2;
+ /* Defer RX_FULL until all trailing bytes are in FIFO. */
+ rfd_set = rxmsg_len + pec_len - 1;
i2c->rx_msg->len = rxmsg_len + 1 + pec_len;
}
xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rfd_set);
--
2.53.0
^ permalink raw reply related
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