* [PATCH v9 2/5] i2c: mux: add support for per channel bus frequency
From: Marcus Folkesson @ 2026-03-24 13:54 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti, Andy Shevchenko, Bartosz Golaszewski
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson
In-Reply-To: <20260324-i2c-mux-v9-0-5292b0608243@gmail.com>
There may be several reasons why you may need to use a certain speed
on an I2C bus. E.g.
- When several devices are attached to the bus, the speed must be
selected according to the slowest device.
- Electrical conditions may limit the usable speed on the bus for
different reasons.
With an I2C multiplexer, it is possible to group the attached devices
after their preferred speed by e.g. putting all "slow" devices on a
separate channel on the multiplexer.
Consider the following topology:
.----------. 100kHz .--------.
.--------. 400kHz | |--------| dev D1 |
| root |--+-----| I2C MUX | '--------'
'--------' | | |--. 400kHz .--------.
| '----------' '-------| dev D2 |
| .--------. '--------'
'--| dev D3 |
'--------'
One requirement with this design is that a multiplexer may only use the
same or lower bus speed as its parent.
Otherwise, if the multiplexer would have to increase the bus frequency,
then all siblings (D3 in this case) would run into a clock speed it may
not support.
The bus frequency for each channel is set in the devicetree. As the
i2c-mux bindings import the i2c-controller schema, the clock-frequency
property is already allowed.
If no clock-frequency property is set, the channel inherits their parent
bus speed.
The following example uses dt bindings to illustrate the topology above:
i2c {
clock-frequency = <400000>;
i2c-mux {
i2c@0 {
clock-frequency = <100000>;
D1 {
...
};
};
i2c@1 {
D2 {
...
};
};
};
D3 {
...
}
};
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
drivers/i2c/i2c-mux.c | 107 ++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 95 insertions(+), 12 deletions(-)
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index d59644e50f14..6b5c9ae1efde 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -36,21 +36,75 @@ struct i2c_mux_priv {
u32 chan_id;
};
+static int i2c_mux_select_chan(struct i2c_adapter *adap, u32 chan_id, u32 *oldclock)
+{
+ struct i2c_mux_priv *priv = adap->algo_data;
+ struct i2c_mux_core *muxc = priv->muxc;
+ struct i2c_adapter *parent = muxc->parent;
+ int ret;
+
+ if (priv->adap.clock_hz && priv->adap.clock_hz < parent->clock_hz) {
+ *oldclock = parent->clock_hz;
+
+ if (muxc->mux_locked)
+ ret = i2c_adapter_set_clk_freq(parent, priv->adap.clock_hz);
+ else
+ ret = __i2c_adapter_set_clk_freq(parent, priv->adap.clock_hz);
+
+ dev_dbg(&adap->dev, "Set clock frequency %uHz on %s\n",
+ priv->adap.clock_hz, parent->name);
+
+ if (ret)
+ dev_err(&adap->dev,
+ "Failed to set clock frequency %uHz on adapter %s: %d\n",
+ *oldclock, parent->name, ret);
+ }
+
+ return muxc->select(muxc, priv->chan_id);
+}
+
+static void i2c_mux_deselect_chan(struct i2c_adapter *adap, u32 chan_id, u32 oldclock)
+{
+ struct i2c_mux_priv *priv = adap->algo_data;
+ struct i2c_mux_core *muxc = priv->muxc;
+ struct i2c_adapter *parent = muxc->parent;
+ int ret;
+
+ if (muxc->deselect)
+ muxc->deselect(muxc, priv->chan_id);
+
+ if (oldclock && oldclock != priv->adap.clock_hz) {
+ if (muxc->mux_locked)
+ ret = i2c_adapter_set_clk_freq(parent, oldclock);
+ else
+ ret = __i2c_adapter_set_clk_freq(parent, oldclock);
+
+ dev_dbg(&adap->dev, "Restored clock frequency %uHz on %s\n",
+ oldclock, parent->name);
+
+ if (ret)
+ dev_err(&adap->dev,
+ "Failed to set clock frequency %uHz on adapter %s: %d\n",
+ oldclock, parent->name, ret);
+ }
+}
+
static int __i2c_mux_master_xfer(struct i2c_adapter *adap,
struct i2c_msg msgs[], int num)
{
struct i2c_mux_priv *priv = adap->algo_data;
struct i2c_mux_core *muxc = priv->muxc;
struct i2c_adapter *parent = muxc->parent;
+ u32 oldclock = 0;
int ret;
/* Switch to the right mux port and perform the transfer. */
- ret = muxc->select(muxc, priv->chan_id);
+ ret = i2c_mux_select_chan(adap, priv->chan_id, &oldclock);
if (ret >= 0)
ret = __i2c_transfer(parent, msgs, num);
- if (muxc->deselect)
- muxc->deselect(muxc, priv->chan_id);
+
+ i2c_mux_deselect_chan(adap, priv->chan_id, oldclock);
return ret;
}
@@ -61,15 +115,16 @@ static int i2c_mux_master_xfer(struct i2c_adapter *adap,
struct i2c_mux_priv *priv = adap->algo_data;
struct i2c_mux_core *muxc = priv->muxc;
struct i2c_adapter *parent = muxc->parent;
+ u32 oldclock = 0;
int ret;
/* Switch to the right mux port and perform the transfer. */
- ret = muxc->select(muxc, priv->chan_id);
+ ret = i2c_mux_select_chan(adap, priv->chan_id, &oldclock);
if (ret >= 0)
ret = i2c_transfer(parent, msgs, num);
- if (muxc->deselect)
- muxc->deselect(muxc, priv->chan_id);
+
+ i2c_mux_deselect_chan(adap, priv->chan_id, oldclock);
return ret;
}
@@ -82,16 +137,17 @@ static int __i2c_mux_smbus_xfer(struct i2c_adapter *adap,
struct i2c_mux_priv *priv = adap->algo_data;
struct i2c_mux_core *muxc = priv->muxc;
struct i2c_adapter *parent = muxc->parent;
+ u32 oldclock = 0;
int ret;
/* Select the right mux port and perform the transfer. */
- ret = muxc->select(muxc, priv->chan_id);
+ ret = i2c_mux_select_chan(adap, priv->chan_id, &oldclock);
if (ret >= 0)
ret = __i2c_smbus_xfer(parent, addr, flags,
read_write, command, size, data);
- if (muxc->deselect)
- muxc->deselect(muxc, priv->chan_id);
+
+ i2c_mux_deselect_chan(adap, priv->chan_id, oldclock);
return ret;
}
@@ -104,16 +160,17 @@ static int i2c_mux_smbus_xfer(struct i2c_adapter *adap,
struct i2c_mux_priv *priv = adap->algo_data;
struct i2c_mux_core *muxc = priv->muxc;
struct i2c_adapter *parent = muxc->parent;
+ u32 oldclock = 0;
int ret;
/* Select the right mux port and perform the transfer. */
- ret = muxc->select(muxc, priv->chan_id);
+ ret = i2c_mux_select_chan(adap, priv->chan_id, &oldclock);
if (ret >= 0)
ret = i2c_smbus_xfer(parent, addr, flags,
read_write, command, size, data);
- if (muxc->deselect)
- muxc->deselect(muxc, priv->chan_id);
+
+ i2c_mux_deselect_chan(adap, priv->chan_id, oldclock);
return ret;
}
@@ -362,6 +419,32 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
}
}
+ of_property_read_u32(child, "clock-frequency", &priv->adap.clock_hz);
+
+ /* If the mux adapter has no clock-frequency property, inherit from parent */
+ if (!priv->adap.clock_hz)
+ priv->adap.clock_hz = parent->clock_hz;
+
+ /*
+ * Warn if the mux adapter is not parent-locked as
+ * this may cause issues for some hardware topologies.
+ */
+ if ((priv->adap.clock_hz < parent->clock_hz) && muxc->mux_locked)
+ dev_warn(muxc->dev,
+ "channel %u is slower than parent on a non parent-locked mux\n",
+ chan_id);
+
+ /* We don't support mux adapters faster than their parent */
+ if (priv->adap.clock_hz > parent->clock_hz) {
+ dev_err(muxc->dev,
+ "channel (%u) is faster (%u) than parent (%u)\n",
+ chan_id, priv->adap.clock_hz, parent->clock_hz);
+
+ of_node_put(mux_node);
+ ret = -EINVAL;
+ goto err_free_priv;
+ }
+
priv->adap.dev.of_node = child;
of_node_put(mux_node);
}
--
2.53.0
^ permalink raw reply related
* [PATCH v9 0/5] I2C Mux per channel bus speed
From: Marcus Folkesson @ 2026-03-24 13:54 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti, Andy Shevchenko, Bartosz Golaszewski
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson,
Bartosz Golaszewski
This was a RFC on how to implement a feature to have different bus
speeds on different channels with an I2C multiplexer/switch.
As no major complaints on the design came up during the review, I
decided to submit the series without the RFC tag.
The benefit with this feature is that you may group devices after
the fastest bus speed they can handle.
A real-world example is that you could have e.g. a display running @400kHz
and a smart battery running @100kHz using the same I2C controller.
There are many corner cases where this may cause a problem for some
hardware topologies. I've tried to describe those I could think of
in the documentation, see Patch #5.
E.g. one risk is that if the mux driver does not disconnect channels
when Idle, this may cause a higher frequency to "leak" through to
devices that are supposed to run at lower bus speed.
This is not only a "problem" for changing bus speed but could also be
an issue for potential address conflicts.
This patchset has been used and tested heavily the last months
on a custom board based on a da850 (DaVinci) platform.
The implementation is split up into several patches:
Patch #1 Introduce a callback for the i2c controller to set bus speed
Patch #2 Introduce functionality to adjust bus speed depending on mux
channel.
Patch #3 Cleanup i2c-davinci driver a bit to prepare it for set_clk_freq
Parch #4 Implement set_clk_freq for the i2c-davinci driver
Parch #5 Update documentation with this feature
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
Changes in v9:
- Fix stray blank line
- Link to v8: https://lore.kernel.org/r/20260314-i2c-mux-v8-0-fb1738a4df0a@gmail.com
Changes in v8:
- Fix gramatics and change %d to %u were appropriate
- Link to v7: https://lore.kernel.org/r/20260223-i2c-mux-v7-0-ec75b214718a@gmail.com
Changes in v7:
- Remove code for finding first mux-locked ancestor
- Introduce a unlocked (i2c_adapter_set_clk_freq) and unlocked
(__i2c_adapter_set_clk_freq) variant
- Let the locking be handled in __i2c_adapter_set_clk_freq
- Use I2C_MAX_STANDARD_MODE_FREQ instead of magic numbers where
appropriate
- Link to v6: https://lore.kernel.org/r/20260216-i2c-mux-v6-0-9be28ecfd7e3@gmail.com
Changes in v6:
- Change logic to find which ancestor to lock with I2C_LOCK_ROOT_ADAPTER
It now find the first mux-locked ancestor and then lock its parent.
- Remove bus_freq_hz in i2c-davinci and only use clock_hz instead
- Mention in commit message that clock_hz can be used to store frequency in an uniform way
- Swap order for change freq/deselect to keep symmetry
- Only allow bus frequency to be lowered in select()
This to not allow an intermediate frequency to be set when it is not
supposed to
- check if(ret) instead of ret(<0) where appropriate
- Fix typos in documentation
- Change i2c_adapter.clock_hz from int to u32
- Simplify i2c_adapter_set_clk_freq() by removing 'ret'
- Link to v5: https://lore.kernel.org/r/20260213-i2c-mux-v5-0-fb2cbf9979b3@gmail.com
Changes in v5:
- Take the lock of the top-most mutex locked mux to make sure that the
root is locked
- Link to v4: https://lore.kernel.org/r/20260128-i2c-mux-v4-0-dee49ce276c0@gmail.com
Changes in v4:
- Rebase on master
- Swap order for printing warning about "channel %u is slower than
parent on a non parent-locked mux\n"
- Fix typo in comment, adaper->adapter
- Link to v3: https://lore.kernel.org/r/20251020-i2c-mux-v3-0-908ac5cf9223@gmail.com
Changes in v3:
- Return -EINVAL if channel is faster than parent (kernel test robot)
- Link to v2: https://lore.kernel.org/r/20251002-i2c-mux-v2-0-b698564cd956@gmail.com
Changes in v2:
- Changed bus_freq field to bus_freq_hz in davinci_i2c_dev (Bartosz Golaszewski)
- Removed idle_state from mux core (Peter Rosin)
- Link to v1: https://lore.kernel.org/r/20250922-i2c-mux-v1-0-28c94a610930@gmail.com
---
Marcus Folkesson (5):
i2c: core: add callback to change bus frequency
i2c: mux: add support for per channel bus frequency
i2c: davinci: calculate bus freq from Hz instead of kHz
i2c: davinci: add support for setting bus frequency
docs: i2c: i2c-topology: add section about bus speed
Documentation/i2c/i2c-topology.rst | 178 +++++++++++++++++++++++++++++++++++++
drivers/i2c/busses/i2c-davinci.c | 43 ++++++---
drivers/i2c/i2c-mux.c | 107 +++++++++++++++++++---
include/linux/i2c.h | 35 ++++++++
4 files changed, 339 insertions(+), 24 deletions(-)
---
base-commit: 1f97d9dcf53649c41c33227b345a36902cbb08ad
change-id: 20250913-i2c-mux-b0063de2ae4d
Best regards,
--
Marcus Folkesson <marcus.folkesson@gmail.com>
^ permalink raw reply
* [PATCH v9 1/5] i2c: core: add callback to change bus frequency
From: Marcus Folkesson @ 2026-03-24 13:54 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti, Andy Shevchenko, Bartosz Golaszewski
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson
In-Reply-To: <20260324-i2c-mux-v9-0-5292b0608243@gmail.com>
All devices on the same I2C bus share the same clock line and the bus
frequency has therefor be chosen so that all attached devices are able
to tolarate that clock rate. IOW, the bus speed must be set for the
slowest attached device.
With I2C multiplexers/switches on the other hand, it would be possible
to have different "domains" that runs with different speeds.
Prepare for such a feature by provide an optional callback function to
change bus frequency.
As a side effect, several bus drivers keep the bus speed in a
private structure and can now have this value stored in a uniform way
instead.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
include/linux/i2c.h | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 20fd41b51d5c..712f9608108e 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -742,6 +742,8 @@ struct i2c_adapter {
struct rt_mutex mux_lock;
int timeout; /* in jiffies */
+ u32 clock_hz; /* bus clock speed */
+ int (*set_clk_freq)(struct i2c_adapter *adap, u32 clock_hz); /* Optional */
int retries;
struct device dev; /* the adapter device */
unsigned long locked_flags; /* owned by the I2C core */
@@ -835,6 +837,39 @@ i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags)
adapter->lock_ops->unlock_bus(adapter, flags);
}
+static inline int
+__i2c_adapter_set_clk_freq(struct i2c_adapter *adapter, u32 clock_hz)
+{
+ if (adapter->set_clk_freq)
+ return adapter->set_clk_freq(adapter, clock_hz);
+
+ /*
+ * If the adapter is a root adapter without .set_clk_freq() implemented, this feature is not
+ * supported.
+ */
+ if (!i2c_parent_is_i2c_adapter(adapter))
+ return -EOPNOTSUPP;
+
+ /*
+ * Update the clock_hz for non-root adapters, even if .set_clk_freq() is not implemented,
+ * to allow the clock frequency to be propagated to root adapters that do support it.
+ */
+ adapter->clock_hz = clock_hz;
+ return 0;
+}
+
+static inline int
+i2c_adapter_set_clk_freq(struct i2c_adapter *adapter, u32 clock_hz)
+{
+ int ret;
+
+ i2c_lock_bus(adapter, I2C_LOCK_SEGMENT);
+ ret = __i2c_adapter_set_clk_freq(adapter, clock_hz);
+ i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT);
+
+ return ret;
+}
+
/**
* i2c_mark_adapter_suspended - Report suspended state of the adapter to the core
* @adap: Adapter to mark as suspended
--
2.53.0
^ permalink raw reply related
* Re: [GIT,PULL,1/2] MediaTek ARM64 Device Tree updates for v7.1
From: Krzysztof Kozlowski @ 2026-03-24 13:54 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: arm-soc, soc, linux-arm-kernel, linux-mediatek, matthias.bgg
In-Reply-To: <b8b9ad39-0e9e-4c38-b080-85153b2a66d1@collabora.com>
On 24/03/2026 14:52, AngeloGioacchino Del Regno wrote:
>> Days in linux-next:
>> ----------------------------------------
>> 0 | +++ (3)
>>
>> With 0 days in next, you cannot really react on any bug reports.
>>
>
> OUCH!!!
>
> Sorry about that, I didn't notice that my for-next didn't get pushed when I tried
> to actually push it (and I was 100% convinced that I had checked after pushing).
>
> Krzysztof, thanks for making me notice, that was completely unintentional.
>
> I re-pushed the for-next branch exactly a second ago; that should give it some good
> time in -next ... or well, otherwise, we can always delay those commits for v7.2 or
> for fixes.
There is still plenty of time for this cycle, so no worries.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [GIT,PULL,1/2] MediaTek ARM64 Device Tree updates for v7.1
From: AngeloGioacchino Del Regno @ 2026-03-24 13:52 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: arm-soc, soc, linux-arm-kernel, linux-mediatek, matthias.bgg
In-Reply-To: <20260321-aspiring-real-foxhound-4a18e7@quoll>
Il 21/03/26 12:07, Krzysztof Kozlowski ha scritto:
> On Fri, Mar 20, 2026 at 09:56:38AM +0100, AngeloGioacchino Del Regno wrote:
>> The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
>>
>> Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
>>
>> are available in the Git repository at:
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux.git tags/mtk-dts64-for-v7.1
>>
>> for you to fetch changes up to 820ed0c1a13c5fafb36232538d793f99a0986ef3:
>>
>> arm64: dts: mediatek: mt7986a: Fix gpio-ranges pin count (2026-03-12 13:32:17 +0100)
>
> Days in linux-next:
> ----------------------------------------
> 0 | +++ (3)
>
> With 0 days in next, you cannot really react on any bug reports.
>
OUCH!!!
Sorry about that, I didn't notice that my for-next didn't get pushed when I tried
to actually push it (and I was 100% convinced that I had checked after pushing).
Krzysztof, thanks for making me notice, that was completely unintentional.
I re-pushed the for-next branch exactly a second ago; that should give it some good
time in -next ... or well, otherwise, we can always delay those commits for v7.2 or
for fixes.
Cheers,
Angelo
^ permalink raw reply
* Re: [PATCH] soc: fsl: qe: Fix potential NULL pointer dereference inqe_reset()
From: Christophe Leroy (CS GROUP) @ 2026-03-24 13:47 UTC (permalink / raw)
To: 未君, qiang.zhao, linux-arm-kernel, linuxppc-dev; +Cc: linux-kernel
In-Reply-To: <tencent_89405091B7744EA070AC53E11A3FFA355609@qq.com>
Hi,
Le 16/03/2026 à 04:28, 未君 a écrit :
>
> Vous n’obtenez pas souvent d’e-mail à partir de 1742789905@qq.com.
> Pourquoi c’est important <https://aka.ms/LearnAboutSenderIdentification>
>
>
> Hi,
>
> Thank you for the detailed review. You are completely right.
>
> My commit message was confusing, and returning early in qe_reset() just
> shifts the NULL pointer dereference to the dependent drivers later on,
> without actually fixing the root cause.
>
> To achieve what you suggested ("if qe_immr remap fails, all drivers
> depending on it don't get probed"), I plan to do the following in the v2
> patch:
>
> 1. Change the return type of qe_reset() from `void` to `int`.
> 2. Return `-ENOMEM` if the ioremap() fails.
> 3. Update the callers of qe_reset() (e.g., qe_probe() and other board-
> specific setup functions) to check this return value. If qe_reset()
> fails, the callers will abort their initialization/probing, which will
> properly prevent the child devices from being probed.
>
> Does this approach sound correct to you? If so, I will prepare and
> submit the v2 patch accordingly.
Well, it would probably work but is it worth it ?
If the board is already unable to get a few bytes of memory that early
in the boot process it is unlikely that it will be able to do much more
work.
Wouldn't it be good enough to just panic() when ioremap() fails, similar
to what happens when qe_sdma_init() fails, see
https://elixir.bootlin.com/linux/v7.0-rc5/source/drivers/soc/fsl/qe/qe.c#L101
Christophe
^ permalink raw reply
* Re: [PATCH v3 0/6] can: flexcan: Add NXP S32N79 SoC support
From: Marc Kleine-Budde @ 2026-03-24 13:46 UTC (permalink / raw)
To: Ciprian Costea
Cc: Vincent Mailhol, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Frank Li, Sascha Hauer, Fabio Estevam, Pengutronix Kernel Team,
linux-can, devicetree, linux-kernel, imx, linux-arm-kernel,
NXP S32 Linux Team, Christophe Lizzi, Alberto Ruiz,
Enric Balletbo, Eric Chanudet
In-Reply-To: <20260323135827.2129371-1-ciprianmarian.costea@oss.nxp.com>
[-- Attachment #1: Type: text/plain, Size: 1066 bytes --]
On 23.03.2026 14:58:21, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
>
> This patch series adds FlexCAN support for the NXP S32N79 SoC.
>
> The S32N79 is an automotive-grade processor from NXP with multiple
> FlexCAN instances. The FlexCAN IP integration on S32N79 differs from
> other SoCs in the interrupt routing - it uses two separate interrupt
> lines:
> - one interrupt for mailboxes 0-127
> - one interrupt for bus error detection and device state changes
Can you check if the S32N79 suffers from the
| /* No interrupt for error passive */
| #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6)
problem? Maybe everyone just added the FLEXCAN_QUIRK_BROKEN_PERR_STATE
for the new SoC without actually testing it.
regards,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v3 1/6] can: flexcan: use dedicated IRQ handlers for multi-IRQ platforms
From: Marc Kleine-Budde @ 2026-03-24 13:44 UTC (permalink / raw)
To: Ciprian Marian Costea
Cc: Vincent Mailhol, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Frank Li, Sascha Hauer, Fabio Estevam, Pengutronix Kernel Team,
linux-can, devicetree, linux-kernel, imx, linux-arm-kernel,
NXP S32 Linux Team, Christophe Lizzi, Alberto Ruiz,
Enric Balletbo, Eric Chanudet
In-Reply-To: <024316c6-aa33-4561-889c-abd9eeb9d83f@oss.nxp.com>
[-- Attachment #1: Type: text/plain, Size: 3341 bytes --]
On 24.03.2026 14:30:50, Ciprian Marian Costea wrote:
> > Can you take care of the S32G2 which has 2 mailbox IRQs, too? Please in
> > a separate patch.
> >
> > My idea was to take the "irq" argument of the IRQ handler and the quirks
> > and figure out if you are the first or second mailbox IRQ handler.
> >
> > Convert these
> >
> > | struct flexcan_priv {
> > | [...]
> > | u64 rx_mask;
> > | u64 tx_mask;
> > | [...]
> > | }
> >
> > into a struct and put an array of 2 of these structs into "struct
> > flexcan_priv". Use correct mask array depending on IRQ handler.
> >
> > regards,
> > Marc
> >
> > --
> > Pengutronix e.K. | Marc Kleine-Budde |
> > Embedded Linux | https://www.pengutronix.de |
> > Vertretung Nürnberg | Phone: +49-5121-206917-129 |
> > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
>
> Thanks for your review.
> I'll add a separate patch implementing per-MB-IRQ mask handling (needed
> by S32G2) in V4. And thanks for the implementation suggestion. I'll take
> it into account.
Maybe you can come up with a improved/better solution.
With the potential concurrent mailbox IRQ handlers on the s32g we have a
problem with the rx-offload infrastructure. After converting it to
per-CPU lists, we still have to merge the lists to the global one.
The current supported use case is a single IRQ handler that adds all
received CAN frames (and CAN error frames) sorted to the skb_irq_queue
list. At the end of the IRQ handler the list is appended to the
skb_queue and NAPI pushes the CAN frames into the networking stack.
This is done to preserve the order of CAN frames, which is crucial for
some CAN protocols.
If we have 2 IRQ handlers adding the per-cpu skb_irq_queue to the
skb_queue might lead to out-of-order reception.
I see 2 options to workaround this:
- Lock the skb_queue and sort each packet into it.
This makes the lock longer and
if an IRQ is delayed old packets might already been processed, so
out-of-order reception is still possible.
- Disable mailboxes 1...8 for the s32g and only use the 2nd IRQ handler.
This obviously reduces the number of RX mailboxes, this increases the
change of RX buffer overflows on systems under high load.
On the other hand the driver can be extended to use the mailboxes
64...127.
As I don't have a s32g SoC nor a customer using it, I have no time to
implement this. Maybe you or someone from NXP is willing to do this.
> Now, unrelated to the per-MB-IRQ refactor, one thing I noticed during the
> IRQ handlers split: dev->stats counters (e.g. rx_fifo_errors) can
> be incremented concurrently from different IRQ handlers on different CPUs.
>
> That said, these are just diagnostic counters and lost increments
> should be benign. Do you think this warrants any synchronization/locking
> mechanism, or is the current behavior acceptable?
There are better ways to do stats, but IMHO for now we can live with the
problem.
regards,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: arm64: pseudo NMI bootconfig question
From: Breno Leitao @ 2026-03-24 13:43 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: oss, catalin.marinas, will, mark.rutland, paulmck,
linux-arm-kernel, linux-kernel, kernel-team
In-Reply-To: <20260320130316.5be6fc45f7860d5ac44c4de1@kernel.org>
Hello Masami,
On Fri, Mar 20, 2026 at 01:03:16PM +0900, Masami Hiramatsu wrote:
> On Thu, 19 Mar 2026 08:20:27 -0700> Breno Leitao <leitao@debian.org> wrote:
> > On Thu, Nov 13, 2025 at 02:37:22AM -0800, Breno Leitao wrote:
> > > On Thu, Nov 13, 2025 at 01:34:03PM +0900, Masami Hiramatsu wrote:
> > >
> > > Another possible solution would be to load bootconfig earlier in the
> > > boot process so that early parameters can be defined within bootconfig.
> > > Petr suggested this approach some time back, but it doesn't appear to
> > > have made it upstream.
> > >
> > > https://lore.kernel.org/all/20231123194106.08f5832f558fe806b1fd8098@kernel.org/
> > >
> > > I'm not fully up to speed on the details of this change, so I want to
> > > ask directly: Would Petr's approach—allowing early parameters to be set
> > > via bootconfig make sense from a bootconfig design perspective?
> >
> > Would it be worthwhile for me to take Petr's patch, update it to the
> > current codebase, address any issues, and verify that it resolves the
> > problem described above? If so, would you be open to reviewing and
> > potentially accepting such a patch?
>
> Hmm, let me recheck it. But the thread seems suspended.
> Can you or Petr continue to work on this?
Thank you for the feedback.
I reviewed Petr's patch and decided to take a more focused approach that
specifically addresses the early parameter issue, which is currently
biting me.
I'd appreciate your thoughts on whether this direction properly solves
the problem, and we can continue the discussion there.
https://lore.kernel.org/all/20260324-early_bootconfig-v1-1-1c0e625aff06@debian.org/
^ permalink raw reply
* Re: [PATCH v2 08/13] firmware: arm_scmi: Harden clock protocol initialization
From: Geert Uytterhoeven @ 2026-03-24 13:43 UTC (permalink / raw)
To: Cristian Marussi
Cc: Sudeep Holla, linux-kernel, linux-arm-kernel, arm-scmi, linux-clk,
linux-renesas-soc, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
dan.carpenter, geert+renesas, kuninori.morimoto.gx,
marek.vasut+renesas
In-Reply-To: <CAMuHMdU1Z9NiQOd10zsimMcOfSC=dVYbfjAKKT4aD3Zx9KttVQ@mail.gmail.com>
Hi Cristian,
On Mon, 16 Mar 2026 at 17:35, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Mon, 16 Mar 2026 at 17:14, Cristian Marussi <cristian.marussi@arm.com> wrote:
> > On Mon, Mar 16, 2026 at 04:50:17PM +0100, Geert Uytterhoeven wrote:
> > > Then I came up with the following preliminary (have to check more
> > > firmware versions) quirk (Gmail whitespace-damaged):
> > >
> > > diff --git a/drivers/firmware/arm_scmi/clock.c
> > > b/drivers/firmware/arm_scmi/clock.c
> > > index f62f9492bd42afbc..6f2af6e9084836c6 100644
> > > --- a/drivers/firmware/arm_scmi/clock.c
> > > +++ b/drivers/firmware/arm_scmi/clock.c
> > > @@ -1230,6 +1230,18 @@ static const struct scmi_protocol_events
> > > clk_protocol_events = {
> > > .num_events = ARRAY_SIZE(clk_events),
> > > };
> > >
> > > +#define QUIRK_RCAR_X5H_NO_ATTRIBUTES \
> > > + ({ \
> > > + if (ret == -EREMOTEIO || ret == -EOPNOTSUPP) \
> > > + continue; \
> > > + })
> > > +
> > > +#define QUIRK_RCAR_X5H_NO_RATES
> > > \
> > > + ({ \
> > > + if (ret == -EOPNOTSUPP) \
> > > + ret = 0; \
> > > + })
> > > +
> > > static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
> > > {
> > > int clkid, ret;
> > > @@ -1254,10 +1266,12 @@ static int scmi_clock_protocol_init(const
> > > struct scmi_protocol_handle *ph)
> > > for (clkid = 0; clkid < cinfo->num_clocks; clkid++) {
> > > cinfo->clkds[clkid].id = clkid;
> > > ret = scmi_clock_attributes_get(ph, clkid, cinfo);
> > > + SCMI_QUIRK(clock_rcar_x5h_no_attributes,
> > > QUIRK_RCAR_X5H_NO_ATTRIBUTES);
> > > if (ret)
> > > return ret;
> > >
> > > ret = scmi_clock_describe_rates_get(ph, clkid, cinfo);
> > > + SCMI_QUIRK(clock_rcar_x5h_no_attributes,
> > > QUIRK_RCAR_X5H_NO_RATES);
> > > if (ret)
> > > return ret;
> > > }
>
> > > Does that look like what you have in mind?
> > > Thanks!
> >
> > Yes in quirk I was only addressing NOT_ATTRIBUTES and mimicing the old
> > behaviour with continue, BUT if the set of clocks not supporting attributes
> > and the set of clocks not suppporting rates is disjoint, I feel we need your
> > double quirks :P
>
> I could have used
>
> SCMI_QUIRK(clock_rcar_x5h_no_attributes, QUIRK_RCAR_X5H_NO_ATTRIBUTES);
>
> after both scmi_clock_attributes_get() and
> scmi_clock_describe_rates_get(), but I wanted to keep the check as
> strict as possible: the former returns two error codes to ignore,
> the latter only one.
So these are two mitigations:
#define QUIRK_RCAR_X5H_NO_ATTRIBUTES ({ ... })
SCMI_QUIRK(clock_rcar_x5h_no_attributes, QUIRK_RCAR_X5H_NO_ATTRIBUTES);
and
#define QUIRK_RCAR_X5H_NO_RATES ({ ... })
SCMI_QUIRK(clock_rcar_x5h_no_attributes, QUIRK_RCAR_X5H_NO_RATES);
gated by a single quirk entry clock_rcar_x5h_no_attributes:
DECLARE_SCMI_QUIRK(clock_rcar_x5h_no_attributes);
DEFINE_SCMI_QUIRK(clock_rcar_x5h_no_attributes, "Renesas", NULL,
"0x10a0000", "renesas,r8a78000");
__DECLARE_SCMI_QUIRK_ENTRY(clock_rcar_x5h_no_attributes),
In general, when a specific SCMI implementation has multiple quirks
and needs multiple mitigations, do you prefer to have individual
entries for each quirk plus mitigation, or just a single entry with
multiple mitigations (which may not be limited to a single protocol,
unlike my example above)?
Thanks!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* RE: [PATCH v2 7/9] accel/neutron: Add job submission IOCTL
From: Ioana Ciocoi Radulescu @ 2026-03-24 13:38 UTC (permalink / raw)
To: Frank Li, Oded Gabbay, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sumit Semwal,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Christian König
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, devicetree@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org,
Jiwei Fu, Forrest Shi, Alexandru Iulian Taran, Daniel Baluta
In-Reply-To: <20260306170259.296712-1-Frank.Li@nxp.com>
On Friday, March 6, 2026 at 7:03 PM, Frank Li wrote:
> > + if (appstatus & APPSTATUS_FAULTCAUSE_MASK) {
> > + dev_err(ndev->dev, "Neutron halted due to fault: 0x%lx\n",
> > + FIELD_GET(APPSTATUS_FAULTCAUSE_MASK,
> appstatus));
> > + return neutron_job_err_handler(ndev);
>
> AI: neutron_job_err_handler() returns void, not int. Remove 'return'.
Ok, will fix.
>
> > + ret = drm_sched_job_init(&job->base, &npriv->sched_entity, 1, NULL,
> > + filp->client_id);
> > + if (ret)
> > + goto out_put_syncobj;
> > +
> > + ret = neutron_push_job(job, syncobj);
> > + if (ret)
> > + goto out_sched_cleanup;
> > +
> > + neutron_put_job(job);
> > + drm_syncobj_put(syncobj);
> > +
> > + return 0;
> > +
> > +out_sched_cleanup:
> > + drm_sched_job_cleanup(&job->base);
> > +out_put_syncobj:
> > + drm_syncobj_put(syncobj);
> > +out_put_gem:
> > + drm_gem_object_put(job->bo);
>
> AI: In the success path, neutron_put_job(job) is called which decrements
> refcnt. But if neutron_push_job() fails and we hit out_sched_cleanup, the job
> refcnt is never decremented. This leaks the job structure.
> Consider: if neutron_push_job() succeeds, it calls kref_get() inside sched_lock.
> If it fails, no kref_get() happens, so don't call
>
> (Need owner do judgment. Not sure if AI said correctly.)
I don't see an issue here, kref_get() is called at a point where
neutron_push_job() can't fail anymore. And if neutron_push_job() fails
earlier, error path looks clean, it frees everything in reverse order,
including the job struct.
Btw, what agent did you use for review?
Thanks,
Ioana
>
> Frank
^ permalink raw reply
* RE: [PATCH v2 4/9] accel/neutron: Add driver for NXP Neutron NPU
From: Ioana Ciocoi Radulescu @ 2026-03-24 13:36 UTC (permalink / raw)
To: Krzysztof Kozlowski, Oded Gabbay, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Sumit Semwal, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Shawn Guo, Frank Li, Christian König
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, devicetree@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org,
Jiwei Fu, Forrest Shi, Alexandru Iulian Taran, Daniel Baluta
In-Reply-To: <110dace9-3ff9-4750-813f-93c6827b105c@kernel.org>
On Friday, March 6, 2026 at 4:22 PM, Krzysztof Kozlowski wrote:
> On 06/03/2026 14:27, Ioana Ciocoi-Radulescu wrote:
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS index
> > 8a5b27b061da..f7a687eb6b54 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -19191,6 +19191,16 @@ S: Orphan
> > F: Documentation/devicetree/bindings/net/nfc/nxp,nci.yaml
> > F: drivers/nfc/nxp-nci
> >
> > +NXP Neutron NPU DRIVER
>
> s/Neutron/NEUTRON/ as everything here is in uppercase
Ok.
>
> > +M: Ioana Ciocoi Radulescu <ruxandra.radulescu@nxp.com>
> > +M: Jiwei Fu <jiwei.fu@nxp.com>
> > +L: dri-devel@lists.freedesktop.org
> > +S: Maintained
> > +T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
> > +F: Documentation/accel/neutron/
> > +F: drivers/accel/neutron/
> > +F: include/uapi/drm/neutron_accel.h
>
>
> >
> > diff --git a/drivers/accel/Makefile b/drivers/accel/Makefile index
> > 1d3a7251b950..698136e12cce 100644
> > --- a/drivers/accel/Makefile
> > +++ b/drivers/accel/Makefile
> > @@ -4,5 +4,6 @@ obj-$(CONFIG_DRM_ACCEL_AMDXDNA) +=
> amdxdna/
> > obj-$(CONFIG_DRM_ACCEL_ARM_ETHOSU) += ethosu/
> > obj-$(CONFIG_DRM_ACCEL_HABANALABS) += habanalabs/
> > obj-$(CONFIG_DRM_ACCEL_IVPU) += ivpu/
> > +obj-$(CONFIG_DRM_ACCEL_NXP_NEUTRON) += neutron/
> > obj-$(CONFIG_DRM_ACCEL_QAIC) += qaic/
> > -obj-$(CONFIG_DRM_ACCEL_ROCKET) += rocket/
> > \ No newline at end of file
>
> You still have patch warnings.
Yeah, so the last line of this Makefile lacked the line ending and vim
fixed that on its own when I edited the file. I can add the neutron line
and leave the rest untouched, just making sure this is what you're
requesting?
>
> > +obj-$(CONFIG_DRM_ACCEL_ROCKET) += rocket/
> > diff --git a/drivers/accel/neutron/Kconfig
> > b/drivers/accel/neutron/Kconfig new file mode 100644 index
> > 000000000000..37b8ecb49804
> > --- /dev/null
> > +++ b/drivers/accel/neutron/Kconfig
> > @@ -0,0 +1,16 @@
> > +# SPDX-License-Identifier: GPL-2.0+
> > +
> > +config DRM_ACCEL_NXP_NEUTRON
> > + tristate "NXP Neutron NPU"
> > + depends on HAS_IOMEM
> > + depends on DRM_ACCEL
> > + depends on ARCH_MXC
>
> Missing compile test
Will add.
>
> > + select DRM_GEM_DMA_HELPER
> > + select DRM_SCHED
> > + help
> > + Enables driver for NXP Neutron NPU.
> > +
> > + Select this if you have an NXP SoC with Neutron, like i.MX95,
> > + and want to run machine learning applications.
> > +
> > + If built as module, the module is named neutron.
>
> ...
>
> > +
> > + ret = devm_request_threaded_irq(dev, ndev->irq, NULL,
> > + neutron_irq_handler_thread,
> > + IRQF_ONESHOT, KBUILD_MODNAME,
> ndev);
> > + if (ret) {
> > + dev_err(dev, "Failed to request irq %d\n", ndev->irq);
>
> Drop, not needed.
Ok
>
> > + return ret;
> > + }
> > +
> > + ret = of_reserved_mem_device_init(&pdev->dev);
> > + if (ret) {
> > + dev_err(dev, "Failed to initialize reserved memory\n");
> > + return ret;
> > + }
> > +
> > + ret = devm_pm_runtime_enable(dev);
> > + if (ret)
> > + goto free_reserved;
> > +
> > + pm_runtime_set_autosuspend_delay(dev,
> NEUTRON_SUSPEND_DELAY_MS);
> > + pm_runtime_use_autosuspend(dev);
> > +
> > + ret = drm_dev_register(&ndev->base, 0);
> > + if (ret)
> > + goto free_reserved;
> > +
> > + return 0;
> > +
> > +free_reserved:
> > + of_reserved_mem_device_release(&pdev->dev);
> > +
> > + return ret;
> > +}
> > +
> > +static void neutron_remove(struct platform_device *pdev) {
> > + struct neutron_device *ndev = platform_get_drvdata(pdev);
> > +
> > + drm_dev_unregister(&ndev->base);
> > + of_reserved_mem_device_release(&pdev->dev);
> > +}
> > +
> > +static int neutron_runtime_suspend(struct device *dev) {
> > + struct neutron_device *ndev = dev_get_drvdata(dev);
> > +
> > + neutron_disable_irq(ndev);
> > + neutron_shutdown(ndev);
> > +
> > + clk_bulk_disable_unprepare(ndev->num_clks, ndev->clks);
> > +
> > + return 0;
> > +}
> > +
> > +static int neutron_runtime_resume(struct device *dev) {
> > + struct neutron_device *ndev = dev_get_drvdata(dev);
> > + int ret;
> > +
> > + ret = clk_bulk_prepare_enable(ndev->num_clks, ndev->clks);
> > + if (ret)
> > + return ret;
> > +
> > + ret = neutron_boot(ndev);
> > + if (ret) {
> > + clk_bulk_disable_unprepare(ndev->num_clks, ndev->clks);
> > + return ret;
> > + }
> > +
> > + neutron_enable_irq(ndev);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct dev_pm_ops neutron_pm_ops = {
> > + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> pm_runtime_force_resume)
> > + RUNTIME_PM_OPS(neutron_runtime_suspend,
> neutron_runtime_resume,
> > +NULL) };
> > +
> > +static const struct of_device_id neutron_match_table[] = {
> > + { .compatible = "nxp,imx95-neutron" },
> > + {}
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, neutron_match_table);
> > +
> > +static struct platform_driver neutron_driver = {
> > + .probe = &neutron_probe,
> > + .remove = &neutron_remove,
> > + .driver = {
> > + .name = "neutron",
> > + .of_match_table =
> of_match_ptr(neutron_match_table),
>
> Drop of_match_ptr. You will have (or you have already same as v1) here
> warning.
Will fix. But how do I get to see the warning here? Tried building with
W=1 and OF support disabled but it didn't complain.
Thanks!
Ioana
>
> > + .pm = pm_ptr(&neutron_pm_ops),
> > + },
> > +};
> Best regards,
> Krzysztof
^ permalink raw reply
* Re: [PATCH v5 0/3] dmaengine: arm-dma350: support combined IRQ mode with runtime IRQ topology detection
From: Robin Murphy @ 2026-03-24 13:36 UTC (permalink / raw)
To: Jun Guo, peter.chen, fugang.duan, robh, krzk+dt, conor+dt, vkoul,
ychuang3, schung, Frank.Li
Cc: dmaengine, devicetree, linux-kernel, cix-kernel-upstream,
linux-arm-kernel
In-Reply-To: <20260324120113.3681830-1-jun.guo@cixtech.com>
On 2026-03-24 12:01 pm, Jun Guo wrote:
> DMA-350 can be integrated with either one interrupt per channel or a
> single combined interrupt for all channels. This series adds support
> for the combined IRQ topology while keeping compatibility with the
> per-channel topology.
>
> Patch 1 updates the DT binding to describe both interrupt topologies
> (1 combined IRQ or 8 per-channel IRQs).
>
> Patch 2 updates the driver to detect IRQ topology at runtime via
> platform_irq_count(), handle both modes in one code path, and enable
> DMANSECCTRL.INTREN_ANYCHINTR only in combined IRQ mode.
>
> Patch 3 adds the Sky1 DMA DT node using the combined IRQ topology.
>
> Tested on CIX SKY1 with dmatest:
> % echo 2000 > /sys/module/dmatest/parameters/timeout
> % echo 1 > /sys/module/dmatest/parameters/iterations
> % echo "" > /sys/module/dmatest/parameters/channel
> % echo 1 > /sys/module/dmatest/parameters/run
>
> Changes in v5:
> - Fix the formatting issue in the AI tag.
> - Remove the unnecessary "cix,sky1-dma-350".
Please don't churn reposts of a series so quickly. I've only just had
time to finish the review of v3 that you posted only 3 working days ago,
that I already moved over as a reply to yesterday's v4 for visibility...
Thanks,
Robin.
> Changes in v4:
> - Reword binding text to align with kernel style.
> - Revise the AI attribution to the standard format.
> - Remove redundant links from the commit log.
>
> Changes in v3:
> - Rework binding compatible description to match generic-first model.
> - Keep interrupts schema support for both 1-IRQ and 8-IRQ topologies.
> - Drop SoC match-data dependency for IRQ mode selection.
> - Detect IRQ topology via platform_irq_count() in probe path.
> - Refactor IRQ handling into a shared channel handler.
> - Enable DMANSECCTRL.INTREN_ANYCHINTR only in combined IRQ mode.
>
> Changes in v2:
> - Update to kernel standards, enhance patch description, and refactor
> driver to use match data for hardware differentiation instead of
> compatible strings.
>
> Jun Guo (3):
> dt-bindings: dma: arm-dma350: document combined and per-channel IRQ
> topologies
> dma: arm-dma350: support combined IRQ mode with runtime IRQ topology
> detection
> arm64: dts: cix: add DT nodes for DMA
>
> .../devicetree/bindings/dma/arm,dma-350.yaml | 25 ++-
> arch/arm64/boot/dts/cix/sky1.dtsi | 7 +
> drivers/dma/arm-dma350.c | 164 +++++++++++++++---
> 3 files changed, 161 insertions(+), 35 deletions(-)
>
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: st: spear: fix dtbs warning on spear thermal sensor
From: Gopi Krishna Menon @ 2026-03-24 13:34 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Daniel Baluta, rafael, daniel.lezcano, rui.zhang, lukasz.luba,
robh, krzk+dt, vireshk, conor+dt, linux-pm, devicetree,
linux-kernel, linux-arm-kernel, soc, simona.toaca, d-gole,
m-chawdhry
In-Reply-To: <acKEJrB6vc9wfd1k@toolbx>
On Tue, Mar 24, 2026 at 07:00:49PM +0530, Gopi Krishna Menon wrote:
> On Tue, Mar 24, 2026 at 11:01:05AM +0100, Krzysztof Kozlowski wrote:
>
> > On 24/03/2026 11:00, Daniel Baluta wrote:
> > > On 3/24/26 11:26, Krzysztof Kozlowski wrote:
> > >> On Mon, Mar 23, 2026 at 07:08:09PM +0530, Gopi Krishna Menon wrote:
> > >>> Running DTBS checks on st/spear1340-evb.dtb results in the following
> > >>> warning:
> > >>>
> > >>> thermal@e07008c4 (st,thermal-spear1340): Unevaluated properties are not allowed ('thermal_flags' was unexpected)
> > >>> from schema $id: http://devicetree.org/schemas/thermal/st,thermal-spear1340.yaml
> > >> How is it possible if there is no such file?
> > >>
> > >> Did you just add new warning in patch #1 and then claim in patch #2 that
> > >> you fix it?
> > >>
> > >> You completely miss the point why this change is needed: how could the
> > >> DTS work before? It could not. And that should be your justification for
> > >> the patch, with explanation why it could not work.
> > >
> > > Correct me if I'm wrong but I think there was a hidden bug here
> > >
> > > drivers/thermal/spear_thermal.c:spear_thermal_probe:
> > >
> > > if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
> > > » » dev_err(&pdev->dev, "Failed: DT Pdata not passed\n");
> > > » » return -EINVAL;
> > > » }
> > >
> > > So, the driver was checking for the correct property as pointed by
> >
> > Yes
> >
> > >
> > > bindings/thermal/spear-thermal.txt but the dts was using the wrong
> >
> > No, DTS had two properties - correct one and incorrect.
> >
>
> Yup, spear13xx is included by spear1310.dtsi and spear1340.dtsi both of
> which have st,thermal-flags correctly defined. When working on this
> patch, after converting the binding, I ran dtbs check and upon seeing
> dtbs warning immediately fixed it thinking it was complaining because
> st,thermal-flags (thermal_flags) was written incorrectly. (Which is not
> incorrect as st,thermal-flags was there in the final node but there was one
I meant 'incorrect' here not 'not incorrect'
> additional property named thermal_flags as well which is not allowed as
> UnevaluatedProperty is set to false).
>
> Also I dont think we have to override the st,thermal-flags property in
> spear1310.dtsi as the flags value is same in spear13xx.dtsi and
> spear1310.dtsi (0x7000).
>
> > >
> > > property name: arch/arm/boot/dts/st/spear13xx.dtsi » » » thermal@e07008c4 { » » » » compatible = "st,thermal-spear1340"; » » » » reg = <0xe07008c4 0x4>; » » » » thermal_flags = <0x7000>; » » » }; And because this check is wrong:
> > >
> > > if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
> > >
> > > people really didn't notice it.
> > >
> > > The check should be:
> > >
> > > if (!np || of_property_read_u32(np, "st,thermal-flags", &val)) {
> > > » » dev_err(&pdev->dev, "Failed: DT Pdata not passed\n");
> > > » » return -EINVAL;
> > > » }
> > >
> > > So, this actual patch has uncovered a bug!
> >
> > Yes. Driver also has bug, so probably was never working. The point is
> > whatever commit is doing, the dtbs_check warning is not the
> > justification, because it was introduced by this patchset.
> >
>
> Please correct me if I am wrong Krzysztof but should i send a seperate patch
> fixing the thermal_flags property (Not connected to these converted
> bindings)?.
>
> Also, is it necessary to set additionalProperties to true? I am not able to
> figure out if that is needed.
>
> > Best regards,
> > Krzysztof
>
> Thanks,
> Gopi Krishna Menon
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: st: spear: fix dtbs warning on spear thermal sensor
From: Gopi Krishna Menon @ 2026-03-24 13:30 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Daniel Baluta, rafael, daniel.lezcano, rui.zhang, lukasz.luba,
robh, krzk+dt, vireshk, conor+dt, linux-pm, devicetree,
linux-kernel, linux-arm-kernel, soc, simona.toaca, d-gole,
m-chawdhry
In-Reply-To: <5a9f84fe-5827-48e7-8e4e-699cf8ae4776@kernel.org>
On Tue, Mar 24, 2026 at 11:01:05AM +0100, Krzysztof Kozlowski wrote:
> On 24/03/2026 11:00, Daniel Baluta wrote:
> > On 3/24/26 11:26, Krzysztof Kozlowski wrote:
> >> On Mon, Mar 23, 2026 at 07:08:09PM +0530, Gopi Krishna Menon wrote:
> >>> Running DTBS checks on st/spear1340-evb.dtb results in the following
> >>> warning:
> >>>
> >>> thermal@e07008c4 (st,thermal-spear1340): Unevaluated properties are not allowed ('thermal_flags' was unexpected)
> >>> from schema $id: http://devicetree.org/schemas/thermal/st,thermal-spear1340.yaml
> >> How is it possible if there is no such file?
> >>
> >> Did you just add new warning in patch #1 and then claim in patch #2 that
> >> you fix it?
> >>
> >> You completely miss the point why this change is needed: how could the
> >> DTS work before? It could not. And that should be your justification for
> >> the patch, with explanation why it could not work.
> >
> > Correct me if I'm wrong but I think there was a hidden bug here
> >
> > drivers/thermal/spear_thermal.c:spear_thermal_probe:
> >
> > if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
> > » » dev_err(&pdev->dev, "Failed: DT Pdata not passed\n");
> > » » return -EINVAL;
> > » }
> >
> > So, the driver was checking for the correct property as pointed by
>
> Yes
>
> >
> > bindings/thermal/spear-thermal.txt but the dts was using the wrong
>
> No, DTS had two properties - correct one and incorrect.
>
Yup, spear13xx is included by spear1310.dtsi and spear1340.dtsi both of
which have st,thermal-flags correctly defined. When working on this
patch, after converting the binding, I ran dtbs check and upon seeing
dtbs warning immediately fixed it thinking it was complaining because
st,thermal-flags (thermal_flags) was written incorrectly. (Which is not
incorrect as st,thermal-flags was there in the final node but there was one
additional property named thermal_flags as well which is not allowed as
UnevaluatedProperty is set to false).
Also I dont think we have to override the st,thermal-flags property in
spear1310.dtsi as the flags value is same in spear13xx.dtsi and
spear1310.dtsi (0x7000).
> >
> > property name: arch/arm/boot/dts/st/spear13xx.dtsi » » » thermal@e07008c4 { » » » » compatible = "st,thermal-spear1340"; » » » » reg = <0xe07008c4 0x4>; » » » » thermal_flags = <0x7000>; » » » }; And because this check is wrong:
> >
> > if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
> >
> > people really didn't notice it.
> >
> > The check should be:
> >
> > if (!np || of_property_read_u32(np, "st,thermal-flags", &val)) {
> > » » dev_err(&pdev->dev, "Failed: DT Pdata not passed\n");
> > » » return -EINVAL;
> > » }
> >
> > So, this actual patch has uncovered a bug!
>
> Yes. Driver also has bug, so probably was never working. The point is
> whatever commit is doing, the dtbs_check warning is not the
> justification, because it was introduced by this patchset.
>
Please correct me if I am wrong Krzysztof but should i send a seperate patch
fixing the thermal_flags property (Not connected to these converted
bindings)?.
Also, is it necessary to set additionalProperties to true? I am not able to
figure out if that is needed.
> Best regards,
> Krzysztof
Thanks,
Gopi Krishna Menon
^ permalink raw reply
* [PATCH net-next 14/15] net: stmmac: qcom-ethqos: correct prg_rclk_dly comment
From: Russell King (Oracle) @ 2026-03-24 13:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-stm32,
Mohd Ayaan Anwar, netdev, Paolo Abeni
In-Reply-To: <acKNcX5PqtWYf8m3@shell.armlinux.org.uk>
The comment for calculating the prg_rclk_dly value is incorrect as it
omits the brackets around the divisor. Add the brackets to allow the
reader to correctly evaluate the value. Validated with the values given
in the driver.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 3faea7ceebd3..0cc5b925cdb6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -450,8 +450,10 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
rgmii_setmask(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
SDCC_HC_REG_DDR_CONFIG);
} else {
- /* PRG_RCLK_DLY = TCXO period * TCXO_CYCLES_CNT / 2 * RX delay ns,
- * in practice this becomes PRG_RCLK_DLY = 52 * 4 / 2 * RX delay ns
+ /* PRG_RCLK_DLY = TCXO period * TCXO_CYCLES_CNT /
+ * (2 * RX delay ns),
+ * in practice this becomes PRG_RCLK_DLY = 52 * 4 /
+ * (2 * RX delay ns)
*/
if (ethqos->has_emac_ge_3) {
/* 0.9 ns */
--
2.47.3
^ permalink raw reply related
* [PATCH net-next 15/15] net: stmmac: qcom-ethqos: move phase_shift to register update site
From: Russell King (Oracle) @ 2026-03-24 13:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-stm32,
Mohd Ayaan Anwar, netdev, Paolo Abeni
In-Reply-To: <acKNcX5PqtWYf8m3@shell.armlinux.org.uk>
Move the determination of the phase shift enable alongside the register
update, and make "phase_shift" unsigned.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 0cc5b925cdb6..18412a6ca77a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -375,14 +375,7 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
{
struct device *dev = ðqos->pdev->dev;
unsigned int prg_rclk_dly, loopback;
- int phase_shift;
-
- /* Determine if the PHY adds a 2 ns TX delay or the MAC handles it */
- if (ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_ID ||
- ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID)
- phase_shift = 0;
- else
- phase_shift = RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN;
+ unsigned int phase_shift;
/* Disable loopback mode */
rgmii_clrmask(ethqos, RGMII_CONFIG2_TX_TO_RX_LOOPBACK_EN,
@@ -416,6 +409,14 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
rgmii_clrmask(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,
RGMII_IO_MACRO_CONFIG2);
+
+ /* Determine if the PHY adds a 2 ns TX delay or the MAC handles it */
+ if (ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_ID ||
+ ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID)
+ phase_shift = 0;
+ else
+ phase_shift = RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN;
+
rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN, phase_shift,
RGMII_IO_MACRO_CONFIG2);
--
2.47.3
^ permalink raw reply related
* [PATCH net-next 13/15] net: stmmac: qcom-ethqos: move loopback decision next to reg update
From: Russell King (Oracle) @ 2026-03-24 13:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-stm32,
Mohd Ayaan Anwar, netdev, Paolo Abeni
In-Reply-To: <acKNcX5PqtWYf8m3@shell.armlinux.org.uk>
Move the loopback decision next to the register update, and make the
local variable unsigned. As a result, there is now no need for the
comment referring to the programming being later.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index f9d6e97f197a..3faea7ceebd3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -374,9 +374,8 @@ static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
{
struct device *dev = ðqos->pdev->dev;
- unsigned int prg_rclk_dly;
+ unsigned int prg_rclk_dly, loopback;
int phase_shift;
- int loopback;
/* Determine if the PHY adds a 2 ns TX delay or the MAC handles it */
if (ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_ID ||
@@ -389,12 +388,6 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
rgmii_clrmask(ethqos, RGMII_CONFIG2_TX_TO_RX_LOOPBACK_EN,
RGMII_IO_MACRO_CONFIG2);
- /* Determine if this platform wants loopback enabled after programming */
- if (ethqos->rgmii_config_loopback_en)
- loopback = RGMII_CONFIG_LOOPBACK_EN;
- else
- loopback = 0;
-
/* Select RGMII, write 0 to interface select */
rgmii_clrmask(ethqos, RGMII_CONFIG_INTF_SEL, RGMII_IO_MACRO_CONFIG);
@@ -476,6 +469,11 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
SDCC_HC_REG_DDR_CONFIG);
}
+ if (ethqos->rgmii_config_loopback_en)
+ loopback = RGMII_CONFIG_LOOPBACK_EN;
+ else
+ loopback = 0;
+
rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN, loopback,
RGMII_IO_MACRO_CONFIG);
--
2.47.3
^ permalink raw reply related
* [PATCH net-next 12/15] net: stmmac: qcom-ethqos: simplify prg_rclk_dly programming
From: Russell King (Oracle) @ 2026-03-24 13:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-stm32,
Mohd Ayaan Anwar, netdev, Paolo Abeni
In-Reply-To: <acKNcX5PqtWYf8m3@shell.armlinux.org.uk>
Rather than coding the entire register update twice with different
values, use a local variable to specify the value and have one
register update statement that uses this local variable. This results
in neater code.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index c88c693137d6..f9d6e97f197a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -374,6 +374,7 @@ static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
{
struct device *dev = ðqos->pdev->dev;
+ unsigned int prg_rclk_dly;
int phase_shift;
int loopback;
@@ -461,16 +462,16 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
*/
if (ethqos->has_emac_ge_3) {
/* 0.9 ns */
- rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_RCLK_DLY,
- FIELD_PREP(SDCC_DDR_CONFIG_PRG_RCLK_DLY,
- 115), SDCC_HC_REG_DDR_CONFIG);
+ prg_rclk_dly = 115;
} else {
/* 1.8 ns */
- rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_RCLK_DLY,
- FIELD_PREP(SDCC_DDR_CONFIG_PRG_RCLK_DLY,
- 57), SDCC_HC_REG_DDR_CONFIG);
+ prg_rclk_dly = 57;
}
+ rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_RCLK_DLY,
+ FIELD_PREP(SDCC_DDR_CONFIG_PRG_RCLK_DLY,
+ prg_rclk_dly), SDCC_HC_REG_DDR_CONFIG);
+
rgmii_setmask(ethqos, SDCC_DDR_CONFIG_PRG_DLY_EN,
SDCC_HC_REG_DDR_CONFIG);
}
--
2.47.3
^ permalink raw reply related
* Re: [PATCH] firmware: arm_scmi: clock: Relax check in scmi_clock_protocol_init
From: Geert Uytterhoeven @ 2026-03-24 13:15 UTC (permalink / raw)
To: Cristian Marussi
Cc: Sudeep Holla, Peng Fan (OSS), Jacky Bai, arm-scmi,
linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <acJI7o79lVNMjV_d@pluto>
Hi Cristian,
On Tue, 24 Mar 2026 at 09:41, Cristian Marussi <cristian.marussi@arm.com> wrote:
> On Tue, Mar 24, 2026 at 07:49:22AM +0000, Sudeep Holla wrote:
> > On Tue, Mar 24, 2026 at 02:24:14PM +0800, Peng Fan (OSS) wrote:
> > > On i.MX95, the SCMI Clock protocol defines several reserved clock IDs that
> > > are not backed by real clock devices
> > > (see arch/arm64/boot/dts/freescale/imx95-clock.h).
> > >
> > > For these reserved IDs, the SCMI firmware correctly returns NOT_FOUND in
> > > response to the CLOCK_ATTRIBUTES command. According to the SCMI Clock
> > > specification, NOT_FOUND is expected when a clock_id does not correspond to
> > > a valid clock device.
> > >
> > > The recent hardening added in scmi_clock_protocol_init() treats any error
> > > return as fatal, causing SCMI clock probe to fail and preventing i.MX9
> > > platforms from booting.
> > >
> > > Relax the check so that -ENOENT is treated as a non-fatal condition.
> >
> > I understand the use-case and the fix here, but still wonder if this
> > should be treated as quirk or handle it in the core. I am inclined to
> > latter as reserved SCMI clock/resource ID seems to be trend in its usage
> > and hard to classify as quirks.
> >
> > Cristain, agree or have a different view ?
>
> I was just replying...
>
> Looking at the spec 3.6.2.5 CLOCK_ATTRIBUTES
>
> "This command returns the attributes that are associated with a specific clock. An agent might be allowed access to only
> a subset of the clocks available in the system. The platform must thus guarantee that clocks that an agent cannot access
> are not visible to it."
>
> ...not sure if this sheds some light or it is ambiguos anyway...I'd say that
> NOT_FOUND does NOT equate to be invisible...
>
> ...BUT at the same time I think that this practice of exposing a non-contiguos
> set of resources IDs (a set with holes in it) is the a well-known spec-loophole
> used by many vendors to deploy one single FW image across all of their platforms
> without having to reconfigure their reosurces IDs ro expose a common set of
> contiguos IDs like the spec would suggest...
>
> Having said that, since we unfortunately left this door open in the
> implementation, now this loophole has become common practice
> apparently...
When I first read that paragraph, I was also confused.
What does "not visible" mean?
- Not present in the clock ID space exposed to that client of
the system?
Yeah, multiple different sequences of contiguous IDs, depending
on client!
- Return failure on CLOCK_ATTRIBUTES?
Which is what implementations seem to do.
The next step in the fun is when the system actually needs to know the
clock rate of such a clock...
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH net-next 11/15] net: stmmac: qcom-ethqos: finally eliminate the switch
From: Russell King (Oracle) @ 2026-03-24 13:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-stm32,
Mohd Ayaan Anwar, netdev, Paolo Abeni
In-Reply-To: <acKNcX5PqtWYf8m3@shell.armlinux.org.uk>
Move the RCLK delay configuration out of the switch, which just leaves
the RGMII_CONFIG_LOOPBACK_EN setting in all three paths. This makes it
trivial to eliminate the switch.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../stmicro/stmmac/dwmac-qcom-ethqos.c | 47 +++++++------------
1 file changed, 16 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index a24f0b24f778..c88c693137d6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -444,8 +444,18 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
rgmii_clrmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_IO_MACRO_CONFIG2);
- switch (speed) {
- case SPEED_1000:
+ if (speed != SPEED_1000) {
+ /* Write 0x5 to PRG_RCLK_DLY_CODE */
+ rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
+ FIELD_PREP(SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
+ 5), SDCC_HC_REG_DDR_CONFIG);
+
+ rgmii_setmask(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,
+ SDCC_HC_REG_DDR_CONFIG);
+
+ rgmii_setmask(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
+ SDCC_HC_REG_DDR_CONFIG);
+ } else {
/* PRG_RCLK_DLY = TCXO period * TCXO_CYCLES_CNT / 2 * RX delay ns,
* in practice this becomes PRG_RCLK_DLY = 52 * 4 / 2 * RX delay ns
*/
@@ -460,39 +470,14 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
FIELD_PREP(SDCC_DDR_CONFIG_PRG_RCLK_DLY,
57), SDCC_HC_REG_DDR_CONFIG);
}
- rgmii_setmask(ethqos, SDCC_DDR_CONFIG_PRG_DLY_EN,
- SDCC_HC_REG_DDR_CONFIG);
- rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
- loopback, RGMII_IO_MACRO_CONFIG);
- break;
-
- case SPEED_100:
- /* Write 0x5 to PRG_RCLK_DLY_CODE */
- rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
- FIELD_PREP(SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
- 5), SDCC_HC_REG_DDR_CONFIG);
- rgmii_setmask(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,
- SDCC_HC_REG_DDR_CONFIG);
- rgmii_setmask(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
- SDCC_HC_REG_DDR_CONFIG);
- rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
- loopback, RGMII_IO_MACRO_CONFIG);
- break;
- case SPEED_10:
- /* Write 0x5 to PRG_RCLK_DLY_CODE */
- rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
- FIELD_PREP(SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
- 5), SDCC_HC_REG_DDR_CONFIG);
- rgmii_setmask(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,
- SDCC_HC_REG_DDR_CONFIG);
- rgmii_setmask(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
+ rgmii_setmask(ethqos, SDCC_DDR_CONFIG_PRG_DLY_EN,
SDCC_HC_REG_DDR_CONFIG);
- rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
- loopback, RGMII_IO_MACRO_CONFIG);
- break;
}
+ rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN, loopback,
+ RGMII_IO_MACRO_CONFIG);
+
return 0;
}
--
2.47.3
^ permalink raw reply related
* [PATCH net-next 09/15] net: stmmac: qcom-ethqos: move RGMII_CONFIG2_RSVD_CONFIG15 out
From: Russell King (Oracle) @ 2026-03-24 13:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-stm32,
Mohd Ayaan Anwar, netdev, Paolo Abeni
In-Reply-To: <acKNcX5PqtWYf8m3@shell.armlinux.org.uk>
All paths through the switch clear the RGMII_CONFIG2_RSVD_CONFIG15
field. move it out of the switch statement.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 10676897619e..73f0ebc5eddd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -434,10 +434,11 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
FIELD_PREP(RGMII_CONFIG_MAX_SPD_PRG_9, 19),
RGMII_IO_MACRO_CONFIG);
+ rgmii_clrmask(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
+ RGMII_IO_MACRO_CONFIG2);
+
switch (speed) {
case SPEED_1000:
- rgmii_clrmask(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
- RGMII_IO_MACRO_CONFIG2);
rgmii_setmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_IO_MACRO_CONFIG2);
@@ -462,9 +463,6 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
break;
case SPEED_100:
- rgmii_clrmask(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
- RGMII_IO_MACRO_CONFIG2);
-
if (ethqos->has_emac_ge_3)
rgmii_setmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_IO_MACRO_CONFIG2);
@@ -485,8 +483,6 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
break;
case SPEED_10:
- rgmii_clrmask(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
- RGMII_IO_MACRO_CONFIG2);
if (ethqos->has_emac_ge_3)
rgmii_setmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_IO_MACRO_CONFIG2);
--
2.47.3
^ permalink raw reply related
* [PATCH net-next 10/15] net: stmmac: qcom-ethqos: move RGMII_CONFIG2_RX_PROG_SWAP
From: Russell King (Oracle) @ 2026-03-24 13:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-stm32,
Mohd Ayaan Anwar, netdev, Paolo Abeni
In-Reply-To: <acKNcX5PqtWYf8m3@shell.armlinux.org.uk>
Move RGMII_CONFIG2_RX_PROG_SWAP out of the switch. 1G speed always
sets this field. 100M and 10M sets it for has_emac_ge_3 devices,
otherwise it is cleared.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../stmicro/stmmac/dwmac-qcom-ethqos.c | 21 ++++++-------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 73f0ebc5eddd..a24f0b24f778 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -437,11 +437,15 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
rgmii_clrmask(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
RGMII_IO_MACRO_CONFIG2);
- switch (speed) {
- case SPEED_1000:
+ if (speed == SPEED_1000 || ethqos->has_emac_ge_3)
rgmii_setmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_IO_MACRO_CONFIG2);
+ else
+ rgmii_clrmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
+ RGMII_IO_MACRO_CONFIG2);
+ switch (speed) {
+ case SPEED_1000:
/* PRG_RCLK_DLY = TCXO period * TCXO_CYCLES_CNT / 2 * RX delay ns,
* in practice this becomes PRG_RCLK_DLY = 52 * 4 / 2 * RX delay ns
*/
@@ -463,13 +467,6 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
break;
case SPEED_100:
- if (ethqos->has_emac_ge_3)
- rgmii_setmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
- RGMII_IO_MACRO_CONFIG2);
- else
- rgmii_clrmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
- RGMII_IO_MACRO_CONFIG2);
-
/* Write 0x5 to PRG_RCLK_DLY_CODE */
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
FIELD_PREP(SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
@@ -483,12 +480,6 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
break;
case SPEED_10:
- if (ethqos->has_emac_ge_3)
- rgmii_setmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
- RGMII_IO_MACRO_CONFIG2);
- else
- rgmii_clrmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
- RGMII_IO_MACRO_CONFIG2);
/* Write 0x5 to PRG_RCLK_DLY_CODE */
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
FIELD_PREP(SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
--
2.47.3
^ permalink raw reply related
* [PATCH net-next 08/15] net: stmmac: qcom-ethqos: move 100M/10M speed programming
From: Russell King (Oracle) @ 2026-03-24 13:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-stm32,
Mohd Ayaan Anwar, netdev, Paolo Abeni
In-Reply-To: <acKNcX5PqtWYf8m3@shell.armlinux.org.uk>
Move the speed programming for 100M and 10M out of the switch. There
is no programming done for 1G speed.
It looks like there are two fields, 7:6 which are programemd to '1'
to select a /2 divisor for 100M, and bits 16:8 which are programmed
to '19' to select a /20 divisor.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 84db57b3d7cb..10676897619e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -425,6 +425,15 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN, phase_shift,
RGMII_IO_MACRO_CONFIG2);
+ if (speed == SPEED_100)
+ rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_2,
+ FIELD_PREP(RGMII_CONFIG_MAX_SPD_PRG_2, 1),
+ RGMII_IO_MACRO_CONFIG);
+ else if (speed == SPEED_10)
+ rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_9,
+ FIELD_PREP(RGMII_CONFIG_MAX_SPD_PRG_9, 19),
+ RGMII_IO_MACRO_CONFIG);
+
switch (speed) {
case SPEED_1000:
rgmii_clrmask(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
@@ -453,9 +462,6 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
break;
case SPEED_100:
- rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_2,
- FIELD_PREP(RGMII_CONFIG_MAX_SPD_PRG_2, 1),
- RGMII_IO_MACRO_CONFIG);
rgmii_clrmask(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
RGMII_IO_MACRO_CONFIG2);
@@ -479,9 +485,6 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
break;
case SPEED_10:
- rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_9,
- FIELD_PREP(RGMII_CONFIG_MAX_SPD_PRG_9, 19),
- RGMII_IO_MACRO_CONFIG);
rgmii_clrmask(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
RGMII_IO_MACRO_CONFIG2);
if (ethqos->has_emac_ge_3)
--
2.47.3
^ permalink raw reply related
* [PATCH net-next 07/15] net: stmmac: qcom-ethqos: move two more RGMII_IO_MACRO_CONFIG2 out
From: Russell King (Oracle) @ 2026-03-24 13:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, linux-arm-kernel, linux-arm-msm, linux-stm32,
Mohd Ayaan Anwar, netdev, Paolo Abeni
In-Reply-To: <acKNcX5PqtWYf8m3@shell.armlinux.org.uk>
RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL is always cleared, and
RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN is always updated with the phase
shift in each path through the switch, so these are independent of
the speed. Move them out.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
.../stmicro/stmmac/dwmac-qcom-ethqos.c | 18 +++++-------------
1 file changed, 5 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 87af44dcef5a..84db57b3d7cb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -420,13 +420,13 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
RGMII_IO_MACRO_CONFIG);
}
+ rgmii_clrmask(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,
+ RGMII_IO_MACRO_CONFIG2);
+ rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN, phase_shift,
+ RGMII_IO_MACRO_CONFIG2);
+
switch (speed) {
case SPEED_1000:
- rgmii_clrmask(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,
- RGMII_IO_MACRO_CONFIG2);
-
- rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
- phase_shift, RGMII_IO_MACRO_CONFIG2);
rgmii_clrmask(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
RGMII_IO_MACRO_CONFIG2);
rgmii_setmask(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
@@ -453,10 +453,6 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
break;
case SPEED_100:
- rgmii_clrmask(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,
- RGMII_IO_MACRO_CONFIG2);
- rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
- phase_shift, RGMII_IO_MACRO_CONFIG2);
rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_2,
FIELD_PREP(RGMII_CONFIG_MAX_SPD_PRG_2, 1),
RGMII_IO_MACRO_CONFIG);
@@ -483,10 +479,6 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
break;
case SPEED_10:
- rgmii_clrmask(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,
- RGMII_IO_MACRO_CONFIG2);
- rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
- phase_shift, RGMII_IO_MACRO_CONFIG2);
rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_9,
FIELD_PREP(RGMII_CONFIG_MAX_SPD_PRG_9, 19),
RGMII_IO_MACRO_CONFIG);
--
2.47.3
^ 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