* [PATCHv3 6/6] serial: mxs-auart: terminate DMA before releasing channels in exit
From: Rosen Penev @ 2026-06-11 3:38 UTC (permalink / raw)
To: linux-serial
Cc: Greg Kroah-Hartman, Jiri Slaby, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam,
open list:TTY LAYER AND SERIAL DRIVERS,
open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20260611033856.6476-1-rosenp@gmail.com>
mxs_auart_dma_exit_channel() calls dma_release_channel() and then
kfree() on the DMA buffers without first terminating any in-flight
transfers. If an asynchronous DMA transfer completes after the buffers
have been freed, the callback will access freed memory.
Call dmaengine_terminate_sync() on each channel before releasing it
to safely abort pending transfers.
Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/tty/serial/mxs-auart.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index fe48a372d022..ec2c60dd0f52 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -872,10 +872,12 @@ static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s)
static void mxs_auart_dma_exit_channel(struct mxs_auart_port *s)
{
if (s->tx_dma_chan) {
+ dmaengine_terminate_sync(s->tx_dma_chan);
dma_release_channel(s->tx_dma_chan);
s->tx_dma_chan = NULL;
}
if (s->rx_dma_chan) {
+ dmaengine_terminate_sync(s->rx_dma_chan);
dma_release_channel(s->rx_dma_chan);
s->rx_dma_chan = NULL;
}
--
2.54.0
^ permalink raw reply related
* [PATCHv3 4/6] serial: mxs-auart: fix IRQ registration ordering and manage console clock
From: Rosen Penev @ 2026-06-11 3:38 UTC (permalink / raw)
To: linux-serial
Cc: Greg Kroah-Hartman, Jiri Slaby, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam,
open list:TTY LAYER AND SERIAL DRIVERS,
open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20260611033856.6476-1-rosenp@gmail.com>
Move the main UART IRQ registration after uart_add_one_port so that
s->port.state and s->port.lock are initialized before the interrupt
handler can run. Mask all UART interrupts before adding the port to
prevent spurious IRQs left by the bootloader.
After probe succeeds, disable the module clock for non-console ports
since startup will re-enable it on port open. For console ports, keep
the clock prepared so auart_console_write() can safely call
clk_enable() from atomic context.
Guard the IRQ handler and get_mctrl with clk_enable/clk_disable since
GPIO IRQs and serial-core status queries can fire while the clock is
disabled for non-console ports.
In remove, disable the clock for console ports to balance the enable
done in probe, preventing a clock leak on unbind.
Assisted-by: opencode:big-pickle
---
drivers/tty/serial/mxs-auart.c | 49 +++++++++++++++++++++++++++-------
1 file changed, 39 insertions(+), 10 deletions(-)
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 4499e3206e85..e2b656638ab3 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -738,9 +738,13 @@ static u32 mxs_auart_modem_status(struct mxs_auart_port *s, u32 mctrl)
static u32 mxs_auart_get_mctrl(struct uart_port *u)
{
struct mxs_auart_port *s = to_auart_port(u);
- u32 stat = mxs_read(s, REG_STAT);
+ u32 stat;
u32 mctrl = 0;
+ clk_enable(s->clk);
+ stat = mxs_read(s, REG_STAT);
+ clk_disable(s->clk);
+
if (stat & AUART_STAT_CTS)
mctrl |= TIOCM_CTS;
@@ -1079,6 +1083,7 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
struct mxs_auart_port *s = context;
u32 mctrl_temp = s->mctrl_prev;
+ clk_enable(s->clk);
uart_port_lock(&s->port);
stat = mxs_read(s, REG_STAT);
@@ -1118,6 +1123,7 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
}
uart_port_unlock(&s->port);
+ clk_disable(s->clk);
return IRQ_HANDLED;
}
@@ -1603,10 +1609,6 @@ static int mxs_auart_probe(struct platform_device *pdev)
}
s->port.irq = irq;
- ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0,
- dev_name(&pdev->dev), s);
- if (ret)
- goto out_disable_clk;
platform_set_drvdata(pdev, s);
@@ -1627,9 +1629,28 @@ static int mxs_auart_probe(struct platform_device *pdev)
mxs_auart_reset_deassert(s);
+ /* Mask all UART interrupts to prevent spurious IRQs from bootloader */
+ mxs_write(0, s, REG_INTR);
+
ret = uart_add_one_port(&auart_driver, &s->port);
- if (ret)
- goto out_free_qpio_irq;
+ if (ret) {
+ auart_port[s->port.line] = NULL;
+ goto out_disable_clk;
+ }
+
+ /*
+ * Request the main IRQ after uart_add_one_port so that
+ * s->port.state and s->port.lock are initialized before
+ * the handler can run in response to a bootloader-left
+ * interrupt.
+ */
+ ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0,
+ dev_name(&pdev->dev), s);
+ if (ret) {
+ uart_remove_one_port(&auart_driver, &s->port);
+ auart_port[s->port.line] = NULL;
+ goto out_disable_clk;
+ }
/* ASM9260 don't have version reg */
if (is_asm9260_auart(s)) {
@@ -1641,10 +1662,16 @@ static int mxs_auart_probe(struct platform_device *pdev)
(version >> 16) & 0xff, version & 0xffff);
}
- return 0;
+ /*
+ * Disable clock -- startup will re-enable when the port is opened.
+ * For the console port the clock must stay prepared so that
+ * auart_console_write() can safely call clk_enable() from
+ * atomic context.
+ */
+ if (!uart_console(&s->port))
+ clk_disable_unprepare(s->clk);
-out_free_qpio_irq:
- auart_port[s->port.line] = NULL;
+ return 0;
out_disable_clk:
clk_disable_unprepare(s->clk);
@@ -1657,6 +1684,8 @@ static void mxs_auart_remove(struct platform_device *pdev)
uart_remove_one_port(&auart_driver, &s->port);
auart_port[s->port.line] = NULL;
+ if (uart_console(&s->port))
+ clk_disable_unprepare(s->clk);
}
static struct platform_driver mxs_auart_driver = {
--
2.54.0
^ permalink raw reply related
* [PATCH] rtc: meson: fix refcount leak in meson_rtc_get_bus
From: WenTao Liang @ 2026-06-11 3:40 UTC (permalink / raw)
To: alexandre.belloni
Cc: neil.armstrong, khilman, jbrunet, martin.blumenstingl, p.zabel,
ben.dooks, linux-rtc, linux-arm-kernel, linux-amlogic,
linux-kernel, WenTao Liang, stable
In meson_rtc_get_bus(), reset_control_reset() is called to trigger
a hardware reset when the serial bus is not ready. The function may
retry up to three times, but neither the successful nor the failure
path calls reset_control_rearm() to balance the reference count,
leaking the triggered_count on shared reset controls.
Fix this by adding reset_control_rearm() after reset_control_reset()
on both the error return path and the success path within the retry
loop, ensuring the reset control can be re-triggered on subsequent
bus acquisition attempts.
Cc: stable@vger.kernel.org
Fixes: d8fe6009aa3e ("rtc: support for the Amlogic Meson RTC")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/rtc/rtc-meson.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-meson.c b/drivers/rtc/rtc-meson.c
index 21eceb9e2e13..729384dceb12 100644
--- a/drivers/rtc/rtc-meson.c
+++ b/drivers/rtc/rtc-meson.c
@@ -146,8 +146,12 @@ static int meson_rtc_get_bus(struct meson_rtc *rtc)
dev_warn(rtc->dev, "failed to get bus, resetting RTC\n");
ret = reset_control_reset(rtc->reset);
- if (ret)
+ if (ret) {
+ reset_control_rearm(rtc->reset);
return ret;
+ }
+
+ reset_control_rearm(rtc->reset);
}
dev_err(rtc->dev, "bus is not ready\n");
--
2.50.1 (Apple Git-155)
^ permalink raw reply related
* [PATCH RESEND] nvmem: apple-spmi-nvmem: wrap regmap calls to satisfy CFI
From: Aelin Reidel @ 2026-06-11 3:46 UTC (permalink / raw)
To: Sven Peter, Janne Grunau, Neal Gompa, Srinivas Kandagatla,
Greg Kroah-Hartman, Sasha Finkelstein, Hector Martin
Cc: asahi, linux-arm-kernel, linux-kernel, Aelin Reidel,
Clayton Craft, stable
The Apple SPMI NVMEM driver previously cast regmap_bulk_read/write to
void * when assigning them to nvmem_config's reg_read/reg_write
function pointers.
This cast breaks the expected function signature of nvmem_reg_read_t
and nvmem_reg_write_t. With CFI enabled, indirect calls through
these pointers fail:
CFI failure at nvmem_reg_write+0x194/0x1e4 (target: regmap_bulk_write+0x0/0x2c8; expected type: 0x83a189c3)
...
Call trace:
nvmem_reg_write+0x194/0x1e4 (P)
__nvmem_cell_entry_write+0x298/0x2e8
nvmem_cell_write+0x24/0x34
macsmc_reboot_probe+0x1dc/0x454 [macsmc_reboot]
...
Introduce thin wrapper functions with the correct nvmem function
pointer types to satisfy the CFI checks.
Fixes: fe91c24a551c ("nvmem: Add apple-spmi-nvmem driver")
Signed-off-by: Aelin Reidel <aelin@mainlining.org>
Reported-by: Clayton Craft <craftyguy@postmarketos.org>
Tested-by: Clayton Craft <craftyguy@postmarketos.org>
Reviewed-by: Sven Peter <sven@kernel.org>
Cc: stable@vger.kernel.org
---
Difference vs the original patch:
- Updated my name and email
- Picked up Sven's R-b
- Link to original: https://lore.kernel.org/all/20251118-apple-spmi-nvmem-cfi-v1-1-75b9ced0a2c2@mainlining.org/
It's been half a year, so I figured I'd gently poke for this to be
applied.
---
drivers/nvmem/apple-spmi-nvmem.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/nvmem/apple-spmi-nvmem.c b/drivers/nvmem/apple-spmi-nvmem.c
index 88614005d5ce..7acb0c07d6ab 100644
--- a/drivers/nvmem/apple-spmi-nvmem.c
+++ b/drivers/nvmem/apple-spmi-nvmem.c
@@ -18,6 +18,22 @@ static const struct regmap_config apple_spmi_regmap_config = {
.max_register = 0xffff,
};
+static int apple_spmi_nvmem_read(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct regmap *map = priv;
+
+ return regmap_bulk_read(map, offset, val, bytes);
+}
+
+static int apple_spmi_nvmem_write(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct regmap *map = priv;
+
+ return regmap_bulk_write(map, offset, val, bytes);
+}
+
static int apple_spmi_nvmem_probe(struct spmi_device *sdev)
{
struct regmap *regmap;
@@ -28,8 +44,8 @@ static int apple_spmi_nvmem_probe(struct spmi_device *sdev)
.word_size = 1,
.stride = 1,
.size = 0xffff,
- .reg_read = (void *)regmap_bulk_read,
- .reg_write = (void *)regmap_bulk_write,
+ .reg_read = apple_spmi_nvmem_read,
+ .reg_write = apple_spmi_nvmem_write,
};
regmap = devm_regmap_init_spmi_ext(sdev, &apple_spmi_regmap_config);
---
base-commit: abe651837cb394f76d738a7a747322fca3bf17ba
change-id: 20260611-apple-spmi-nvmem-cfi-673d5202f7e4
Best regards,
--
Aelin Reidel <aelin@mainlining.org>
^ permalink raw reply related
* [PATCH] rtc: meson: fix refcount leak in meson_rtc_get_bus
From: WenTao Liang @ 2026-06-11 3:56 UTC (permalink / raw)
To: alexandre.belloni, neil.armstrong, khilman, p.zabel
Cc: jbrunet, martin.blumenstingl, ben.dooks, linux-rtc,
linux-arm-kernel, linux-amlogic, linux-kernel, WenTao Liang,
stable
In meson_rtc_get_bus(), reset_control_reset() is called to trigger
a hardware reset when the serial bus is not ready. The function may
retry up to three times, but neither the successful nor the failure
path calls reset_control_rearm() to balance the reference count,
leaking the triggered_count on shared reset controls.
Fix this by adding reset_control_rearm() after reset_control_reset()
on both the error return path and the success path within the retry
loop, ensuring the reset control can be re-triggered on subsequent
bus acquisition attempts.
Cc: stable@vger.kernel.org
Fixes: d8fe6009aa3e ("rtc: support for the Amlogic Meson RTC")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/rtc/rtc-meson.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-meson.c b/drivers/rtc/rtc-meson.c
index 21eceb9e2e13..729384dceb12 100644
--- a/drivers/rtc/rtc-meson.c
+++ b/drivers/rtc/rtc-meson.c
@@ -146,8 +146,12 @@ static int meson_rtc_get_bus(struct meson_rtc *rtc)
dev_warn(rtc->dev, "failed to get bus, resetting RTC\n");
ret = reset_control_reset(rtc->reset);
- if (ret)
+ if (ret) {
+ reset_control_rearm(rtc->reset);
return ret;
+ }
+
+ reset_control_rearm(rtc->reset);
}
dev_err(rtc->dev, "bus is not ready\n");
--
2.50.1 (Apple Git-155)
^ permalink raw reply related
* Re: [PATCH v3 0/9] ARM: dts: aspeed: anacapa: restructure devicetree for development-phase
From: Andrew Jeffery @ 2026-06-11 4:06 UTC (permalink / raw)
To: u8813345, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley
Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
colin.huang2, Carl Lee, Rex Fu, Andy Chung, Peter Shen
In-Reply-To: <20260602-anacapa-devlop-phase-devicetree-v3-0-7c93c5df8d9b@gmail.com>
Hi Colin,
On Tue, 2026-06-02 at 21:24 +0800, Colin Huang via B4 Relay wrote:
...
>
> Colin Huang (5):
> ARM: dts: aspeed: anacapa: add EVT1 devicetree and point wrapper to it
> ARM: dts: aspeed: anacapa: add EVT2 devicetree inheriting EVT1
> ARM: dts: aspeed: anacapa: add DVT devicetree inheriting EVT2
So my concern with these three are that none of the EVT1, EVT2 or DVT
devicetrees correspond with the current Anacapa devicetree. All of them
have variations on the configured GPIOs. Some GPIO lines are renamed
while others are added.
Adding them is (eventually) fine, but I'd rather not do that while
we're shuffling the devicetree sources around.
Renaming them to accommodate changes in the one devicetree is what
we're trying to escape here, so having renames hide in the rest of the
shuffling is definitely problematic.
For example:
-""
+"L_FNIC_FLT"
"FM_CPU0_SYS_RESET_N"
-""
+"L_BNIC0_FLT"
"CPU0_KBRST_N"
-""
+"L_BNIC1_FLT"
"FM_CPU0_PROCHOT_trigger_N"
-""
+"L_BNIC2_FLT"
"FM_CLR_CMOS_R_P0"
-""
+"L_BNIC3_FLT"
"Force_I3C_SEL"
-""
+"L_RTM_SW_FLT"
"SYSTEM_Force_Run_AC_Cycle"
""
""
@@ -20,55 +20,57 @@
"FM_SCM_JTAG_MUX_SEL"
"Channel2_leakage_Manifold1"
"FM_BRIDGE_JTAG_MUX_SEL"
-"Channel3_leakage"
+"Channel5_leakage_present_EAM1"
I've pasted a script below that helps compare the various dts files.
You can use it to generate the reference from the current aspeed-bmc-
facebook-anacapa.dts, then generate the comparison files from the newly
introduced dts files.
To reiterate, I expect the shuffling of the dts files to result in at
least one of the variants producing the same devicetree as the current
aspeed-bmc-facebook-anacapa.dts.
Andrew
#!/usr/bin/bash
set -x
: ${ANACAPA_VARIANT:=""}
: ${ANACAPA_REFERENCE:="arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.rt.dts.tmp"}
if [ -z "$ANACAPA_REFERENCE" ] || ! [ -e "$ANACAPA_REFERENCE" ]
then
gcc -E -Wp,-MMD,arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.d.pre.tmp -nostdinc -I ../scripts/dtc/include-prefixes -undef -D__DTS__ -x assembler-with-cpp -o arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.dts.tmp ../arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts ; ./scripts/dtc/dtc -o arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dtb -b 0 -i../arch/arm/boot/dts/aspeed/ -i../scripts/dtc/include-prefixes -Wno-unique_unit_address -Wno-unit_address_vs_reg -Wno-avoid_unnecessary_addr_size -Wno-alias_paths -Wno-interrupt_map -Wno-simple_bus_reg -d arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.d.dtc.tmp arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.dts.tmp ; cat arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.d.pre.tmp arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.d.dtc.tmp > arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.d
dtc -I dts -O dts -o arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.rt.dts.tmp arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.dts.tmp
ANACAPA_REFERENCE=arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa.dtb.rt.dts.tmp
fi
if [ -n "$ANACAPA_VARIANT" ]
then
gcc -E -Wp,-MMD,arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb.d.pre.tmp -nostdinc -I ../scripts/dtc/include-prefixes -undef -D__DTS__ -x assembler-with-cpp -o arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb.dts.tmp ../arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dts ; ./scripts/dtc/dtc -o arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb -b 0 -i../arch/arm/boot/dts/aspeed/ -i../scripts/dtc/include-prefixes -Wno-unique_unit_address -Wno-unit_address_vs_reg -Wno-avoid_unnecessary_addr_size -Wno-alias_paths -Wno-interrupt_map -Wno-simple_bus_reg -d arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb.d.dtc.tmp arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb.dts.tmp ; cat arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb.d.pre.tmp arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb.d.dtc.tmp > arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb.d
dtc -I dts -O dts -o arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb.rt.dts.tmp arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb.dts.tmp
diff -u "$ANACAPA_REFERENCE" arch/arm/boot/dts/aspeed/.aspeed-bmc-facebook-anacapa-${ANACAPA_VARIANT}.dtb.rt.dts.tmp | tee ${ANACAPA_VARIANT}-{remove,add}
grep '^-[^-]' ${ANACAPA_VARIANT}-remove | grep gpio-line-names | sed -E 's/.+gpio-line-names = //' | tr ',' '\n' | sed -E 's/^ //' | sponge ${ANACAPA_VARIANT}-remove
grep '^[+][^+]' ${ANACAPA_VARIANT}-add | grep gpio-line-names | sed -E 's/.+gpio-line-names = //' | tr ',' '\n' | sed -E 's/^ //' | sponge ${ANACAPA_VARIANT}-add
diff -u ${ANACAPA_VARIANT}-{remove,add}
fi
^ permalink raw reply
* Re: [PATCH 1/2] arm64: ftrace: prepare ftrace_modify_call() for use without CALL_OPS
From: Xu Kuohai @ 2026-06-11 4:06 UTC (permalink / raw)
To: Jose Fernandez (Anthropic), Steven Rostedt, Masami Hiramatsu,
Mark Rutland, Catalin Marinas, Will Deacon, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: linux-kernel, linux-trace-kernel, linux-arm-kernel, llvm, bpf,
Florent Revest, Puranjay Mohan
In-Reply-To: <20260609-arm64-ftrace-direct-calls-v1-1-4a46f266697f@linux.dev>
On 6/9/2026 1:19 PM, Jose Fernandez (Anthropic) wrote:
> ftrace_modify_call() is guarded by CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS
> and calls ftrace_rec_set_ops(rec, arm64_rec_get_ops(rec)) directly,
> which only exists when CALL_OPS is enabled.
>
> Generic ftrace also needs ftrace_modify_call() when
> CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS is enabled, to retarget a
> callsite between two non-FTRACE_ADDR destinations, as happens when a
> direct trampoline is modified. The next patch allows DIRECT_CALLS without
> CALL_OPS, so widen the guard to cover both configurations and switch
> the body to the ftrace_rec_update_ops() wrapper, which already has a
> stub for the !CALL_OPS case. ftrace_make_call() already uses the same
> wrapper today.
>
> No functional change: with CALL_OPS enabled, ftrace_rec_update_ops()
> expands to the exact call this replaces.
>
> Assisted-by: Claude:unspecified
> Signed-off-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
> ---
> arch/arm64/kernel/ftrace.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
> index 5a1554a441628..e1a3c0b3a0514 100644
> --- a/arch/arm64/kernel/ftrace.c
> +++ b/arch/arm64/kernel/ftrace.c
> @@ -409,7 +409,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> return ftrace_modify_code(pc, old, new, true);
> }
>
> -#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS
> +#if defined(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS) || \
> + defined(CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS)
> int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
> unsigned long addr)
> {
> @@ -417,7 +418,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
> u32 old, new;
> int ret;
>
> - ret = ftrace_rec_set_ops(rec, arm64_rec_get_ops(rec));
> + ret = ftrace_rec_update_ops(rec);
> if (ret)
> return ret;
>
>
Acked-by: Xu Kuohai <xukuohai@huawei.com>
^ permalink raw reply
* Re: [PATCH 2/2] arm64: ftrace: allow DIRECT_CALLS without CALL_OPS
From: Xu Kuohai @ 2026-06-11 4:06 UTC (permalink / raw)
To: Jose Fernandez (Anthropic), Steven Rostedt, Masami Hiramatsu,
Mark Rutland, Catalin Marinas, Will Deacon, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
Cc: linux-kernel, linux-trace-kernel, linux-arm-kernel, llvm, bpf,
Florent Revest, Puranjay Mohan
In-Reply-To: <20260609-arm64-ftrace-direct-calls-v1-2-4a46f266697f@linux.dev>
On 6/9/2026 1:19 PM, Jose Fernandez (Anthropic) wrote:
> arm64 gained ftrace direct calls in commit 2aa6ac03516d ("arm64:
> ftrace: Add direct call support") on top of
> DYNAMIC_FTRACE_WITH_CALL_OPS, using the per-callsite ops pointer as a
> fast path to reach the direct trampoline. Since commit baaf553d3bc3
> ("arm64: Implement HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS"), CALL_OPS is
> mutually exclusive with CFI: the pre-function NOPs would change the
> offset of the pre-function kCFI type hash, and the compiler support
> needed to keep that offset consistent does not exist yet.
>
> The result is that a CONFIG_CFI=y kernel loses CALL_OPS, and with it
> DIRECT_CALLS, and with it every BPF trampoline attachment to kernel
> functions: register_fentry() returns -ENOTSUPP, so fentry/fexit,
> fmod_ret and BPF LSM programs cannot attach at all. This is a real
> problem for hardened arm64 deployments that rely on BPF LSM for
> security monitoring while keeping kCFI enabled.
>
> CALL_OPS is an optimization for direct calls, not a dependency. When
> the direct trampoline is within BL range, the callsite branches
> straight to it and ftrace_caller is not involved. When it is out of
> range, ftrace_find_callable_addr() already falls back to
> ftrace_caller, and the DIRECT_CALLS machinery there
> (FREGS_DIRECT_TRAMP, ftrace_caller_direct_late) is gated on
> DIRECT_CALLS alone, not CALL_OPS: the ops dispatch invokes
> call_direct_funcs(), which stores the trampoline address in
> ftrace_regs, and ftrace_caller tail-calls it. s390 and loongarch use
> this same mechanism for HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS without
> having CALL_OPS at all, and DYNAMIC_FTRACE_WITH_ARGS without CALL_OPS
> is already a supported arm64 configuration (GCC builds with
> CC_OPTIMIZE_FOR_SIZE do not satisfy the CALL_OPS select condition).
>
> Drop the CALL_OPS requirement from the
> HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS select. Configurations that
> keep CALL_OPS (!CFI clang builds, and GCC builds without
> CC_OPTIMIZE_FOR_SIZE) are unchanged. CALL_OPS-less configurations
> take the ftrace_caller ops-dispatch path for out-of-range direct
> calls, trading the per-callsite fast path for working BPF
> trampolines; in-range attachments still branch directly with no
> overhead. GCC -Os builds also gain DIRECT_CALLS as a side effect.
> That is intended: s390 and loongarch already ship DIRECT_CALLS
> without any per-callsite fast path.
>
> Assisted-by: Claude:unspecified
> Signed-off-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
> ---
> arch/arm64/Kconfig | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index fe60738e5943b..2cd7d536671c9 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -188,7 +188,7 @@ config ARM64
> if (GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS || \
> CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS)
> select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS \
> - if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS
> + if DYNAMIC_FTRACE_WITH_ARGS
> select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \
> if (DYNAMIC_FTRACE_WITH_ARGS && !CFI && \
> (CC_IS_CLANG || !CC_OPTIMIZE_FOR_SIZE))
>
Acked-by: Xu Kuohai <xukuohai@huawei.com>
^ permalink raw reply
* Re: [PATCH v2] virt: arm-cca-guest: use raw variant of smp_processor_id() in arm_cca_report_new()
From: Kohei Enju @ 2026-06-11 4:12 UTC (permalink / raw)
To: Suzuki K Poulose
Cc: Will Deacon, Catalin Marinas, Sami Mujawar, Gavin Shan,
Steven Price, linux-arm-kernel, linux-kernel
In-Reply-To: <51a76d18-6db9-41f3-a1d4-60360088c442@arm.com>
On 06/09 14:44, Suzuki K Poulose wrote:
> On 09/06/2026 14:16, Kohei Enju wrote:
> > On 06/03 12:48, Will Deacon wrote:
> > > On Tue, Jun 02, 2026 at 04:48:43PM +0100, Suzuki K Poulose wrote:
> > > > On 02/06/2026 12:01, Will Deacon wrote:
> > > > > On Tue, May 19, 2026 at 07:12:08PM +0900, Kohei Enju wrote:
> > > > > > With CONFIG_DEBUG_PREEMPT=y, smp_processor_id() becomes an alias of
> > > > > > debug_smp_processor_id(). This debug function complains when certain
> > > > > > conditions that ensure CPU ID stability are not met, specifically when
> > > > > > it's called from a preemptible context.
> > > > > >
> > > > > > In arm_cca_report_new(), which runs in a preemptible context,
> > > > > > smp_processor_id() triggers a splat [0] due to this.
> > > > > >
> > > > > > However, the CPU ID obtained here is used as the target CPU for
> > > > > > smp_call_function_single() to designate a specific CPU for subsequent
> > > > > > operations, not to assert that the current thread will continue to
> > > > > > execute on the same CPU. Therefore, snapshotting the CPU ID itself is
> > > > > > correct, and thus there's no actual harm except for the splat.
> > > > > >
> > > > > > Use raw_smp_processor_id() instead, to directly retrieve the current CPU
> > > > > > ID without the debug checks, avoiding the unnecessary warning message
> > > > > > while preserving the correct functional behavior.
> > > > >
> > > > > That's pretty disgusting imo so I'd like to see some more justification
> > > > > for this approach.
> > > > >
> > > > > > Note that while migrate_disable() would pin the task to the current CPU,
> > > > > > this path should not block CPU hotplug events. Therefore, we snapshot
> > > > > > the current CPU ID and accept that smp_call_function_single() may fail
> > > > > > if the CPU goes offline.
> > > > >
> > > > > Why shouldn't it block CPU hotplug events? What happens if the CPU goes
> > > > > offline and comes back online again during the loop of continue calls?
> > > >
> > > > It need not. It can continue the calls. The RMM keeps track of the internal
> > > > progress in the "REC" object for this "VCPU". Hotplug ON/OFF
> > > > doesn't change the REC object in CCA Guest. So, a REC can come back and
> > > > execute it. But the Linux could fail the operation if the CPU isn't
> > > > available for fetching the report, after we do a RSI_ATTEST_TOKEN_INIT.
> > >
> > > I couldn't really shake that out of the RMM spec tbh:
> > > RSI_ATTESTATION_TOKEN_CONTINUE is allowed to return RSI_ERROR_UNKNOWN
> > > and I couldn't find anything about hotplug.
>
> Like I said, we are dealing with Virtual CPUs (RECs here) and the only
> condition that the RMM enforces is the _CONTINUE calls are issued on the
> same VCPU (REC). Hotplug doesn't change the REC (as a REC cannot be
> modified or added once the Realm is ACTIVE).
>
> > >
> > > But my main point, really, is why are we not using migrate_disable()
> > > here? I can't see the justification.
>
> There is no reason, why we couldn't use this. TBH, I wasn't aware of the
> helper ;-) at the time this was initially designed and we didn't want to
> block CPU hotplug. We could always request a new report, it is not like
> aborting a report generation has any side effects.
>
> >
> > Hi Will,
> > Sorry for the late reply.
> >
> > I agree that using migrate_disable() makes this path simpler and
> > clearer.
> >
> > I've reviewed the discussion where the original commit was introduced:
> > https://lore.kernel.org/linux-arm-kernel/7a83461d-40fd-4e61-8833-5dae2abaf82b@arm.com/
> > but I couldn't find a strong reason why we shouldn't block CPU hotplug
> > or use migrate_disable(), even though I can see the current design was
> > intentional.
> >
> > So I'm happy to rework the patch to use migrate_disable() and remove
> > the smp_call_function_single() calls if there are no objections.
>
> I am fine with removing with migrate_disable() approach.
Hi Suzuki,
Thank you for your clarification, and explanation in this discussion.
I'll work on v3 soon.
>
> Cheers
> Suzuki
>
> >
> > >
> > > Will
> > >
>
>
^ permalink raw reply
* Re: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
From: Marek Vasut @ 2026-06-10 16:31 UTC (permalink / raw)
To: Liu Ying
Cc: Piyush Patle, dri-devel, imx, linux-arm-kernel, linux-clk,
devicetree, Shawn Guo, Fabio Estevam, Peng Fan, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Lucas Stach, Laurent Pinchart,
Thomas Zimmermann, Abel Vesa, Pengutronix Kernel Team
In-Reply-To: <aifOQtaAi_7F9hXt@raspi>
On 6/9/26 10:26 AM, Liu Ying wrote:
Hello Liu,
>>>> I brought this series up on the i.MX95 15x15 FRDM (IT6263 LVDS-to-HDMI on
>>>> LVDS ch1). It mostly works, but I ran into a few issues around DI routing,
>>>> LVDS format handling, and DC enable sequencing which needed rework before
>>>> HDMI would come up reliably on the board.
>>>>
>>>> I don't see a v2 of the series and things seem to have been quiet since
>>>> November. Are you planning to post an updated version?
>>>
>>> My plan was to enable prefetch engine support[1] for i.MX8QXP display
>>> controller and add device tree for a whole i.MX8QXP LVDS display pipeline,
>>> before adding i.MX95 display controller support.
>>>
>>> Unfortunately, it seems that Marek is not a big fan of [1]
>>
>> I am fine with [1] as long as it can be isolated and does not affect every
>> SoC that might reuse this driver, which I think it can be done.
>
> How can it be isolated?
if (compatible("mx8q"))
something->prefetch_op = somefunction;
And then wherever is prefetch used, do
if (something->prefetch_op)
something->prefetch_op()
Or something along those lines ?
>>> and I'm busy
>>> with downstream development so the plan doesn't move forward well. I still
>>> think [1] makes sense(maybe I need to rebase it on latest drm-misc-next),
>>> so I'd like to see review comments on [1] and hopefully people think that
>>> the overall idea of [1] is ok.
>>
>> My only concern is, to keep it isolated to MX8Q, so this driver can be
>> reused by MX95.
>>
>>>> I've accumulated a fair amount of rework while getting this running on the
>>>> FRDM. If you're not planning a v2, I can clean things up and send one based
>>>> on the current series.
>>>
>>> I still think that i.MX95 display controller driver should be in a separate
>>> driver, rather than sharing the same driver with i.MX8QXP display controller
>>> like this patch series does, because the two display controllers are quite
>>> different as I mentioned in comments on this patch series and in discussion
>>> in [1]. Also, the common part between the two display controllers should
>>> be extracted to a common helper library as I mentioned there too.
>> Are they really? It seems this series adds support for the MX95 DC without
>> that many changes, so are the DCs really that different ? It seems the MX95
>> DC is simply a reuse/evolution of the MX8Q DC blocks, so duplicating the
>> code seems like the wrong direction, it will only lead to disparate sets of
>> bugs in two drivers, which isn't desired.
>
> I pointed out a lot of H/W differences between the two display controllers
> during the discussions for this patch series and my i.MX8QXP prefetch engine
> patch series[1]. Please take a look at [1], which clearly shows that the
> prefetch engine would considerably impact CRTC/plane atomic callback
> implementations.
Is the prefetch engine actually grown into the CRTC/DE or not ? I
suspect it is separate and instead part of the built-in DMA, right ?
> Display controller internal blocks would also impact
> the implementations, e.g., DomainBlend block in i.MX95 display controller
> doesn't present in i.MX8QXP display controller. It makes sense to use
> separate drivers for the two display controllers instead of adding 'if/else'
> checks to a single driver's atomic callbacks or introducing two pairs of
> atomic callbacks to that single driver. I mentioned before, the code to
> simply add a DRM driver(struct drm_driver) is fairly limited.
Can't we simply have two sets of ops (one for mx8q and one for mx95) for
those ops which are too complicated to implement as a single op with
if/else statements ?
> I also mentioned before that separate drivers make them easier to maintain:
> we don't have to test both i.MX8QXP and i.MX95 if only one display controller
> specific code is changed.
The downside is lack of code reuse, which leads to disparate sets of
bugs in these two drivers and code duplication. And it seems to me, that
large parts of the MX8Q and MX95 DC are effectively identical.
>> (I might not fully understand what you have in mind with the helper library
>> though?)
>
> I said this could be something like imx-ldb-helper.c and plus perhaps some
> callbacks like fg->dc_fg_cfg_videomode().
Do you perceive that the DC driver cannot be parametrized easily enough
that it has to be turned into a library like that ? When I look at this
patchset, esp. the first half which updates the various blocks, it does
not seem to me that way.
^ permalink raw reply
* Re: [PATCH v6 04/20] dma-pool: track decrypted atomic pools and select them via attrs
From: Aneesh Kumar K.V @ 2026-06-11 4:51 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Jiri Pirko,
Michael Kelley
In-Reply-To: <20260610164153.GQ2764304@ziepe.ca>
Jason Gunthorpe <jgg@ziepe.ca> writes:
> On Wed, Jun 10, 2026 at 01:37:26PM +0530, Aneesh Kumar K.V wrote:
>> Jason Gunthorpe <jgg@ziepe.ca> writes:
>>
>> > On Thu, Jun 04, 2026 at 02:09:43PM +0530, Aneesh Kumar K.V (Arm) wrote:
>> >> struct page *dma_alloc_from_pool(struct device *dev, size_t size,
>> >> - void **cpu_addr, gfp_t gfp,
>> >> + void **cpu_addr, gfp_t gfp, unsigned long attrs,
>> >> bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
>> >> {
>> >> - struct gen_pool *pool = NULL;
>> >> + struct dma_gen_pool *dma_pool = NULL;
>> >> struct page *page;
>> >> bool pool_found = false;
>> >>
>> >> - while ((pool = dma_guess_pool(pool, gfp))) {
>> >> + while ((dma_pool = dma_guess_pool(dma_pool, gfp))) {
>> >> +
>> >> + if (dma_pool->unencrypted != !!(attrs & DMA_ATTR_CC_SHARED))
>> >> + continue;
>> >
>> > I don't think you should be overloading DMA_ATTR_CC_SHARED like this.
>> >
>> > /*
>> > * DMA_ATTR_CC_SHARED is not a caller-visible dma_alloc_*()
>> > * attribute. The direct allocator uses it internally after it has
>> > * decided that the backing pages must be shared/decrypted, so the
>> > * rest of the allocation path can consistently select DMA addresses,
>> > * choose compatible pools and restore encryption on free.
>> > */
>> > if (attrs & DMA_ATTR_CC_SHARED)
>> > return NULL;
>> >
>> > if (force_dma_unencrypted(dev)) {
>> > attrs |= DMA_ATTR_CC_SHARED;
>> > mark_mem_decrypt = true;
>> > }
>> >
>> > It is fine to have a bit inside the attrs that is only used by the
>> > internal logic, but it needs to have a clearer name
>> > __DMA_ATTR_REQUIRE_CC_SHARED perhaps.
>> >
>>
>> Are you suggesting adding another attribute in addition to
>> DMA_ATTR_CC_SHARED?
>>
>> Is the idea that __DMA_ATTR_REQUIRE_CC_SHARED would be used in the
>> allocation path to request a CC_SHARED allocation, while
>> DMA_ATTR_CC_SHARED would be used in the mapping path to describe the
>> attribute of the address?
>
> Yeah, it is a thought at least
>
> Maybe a comment is good enough.
>
> I just find it hard to follow when we have this dual usage. Like the
> code above for dma_pool->unencrypted is completely wrong if it is an
> "attribute of an address". Easy to cut & paste that into the wrong
> context.
>
> Especially if you move things up higher.. having the alloc set both
> CC_SHARED and REQUIRE_CC_SHARED or maybe ALLOC_CC_SHARED would make it
> clearer that the alloc code lives under that callchain
>
> Jason
>
If we are adding DMA_ATTR_ALLOC_SHARED, should we also allow
dma_alloc_attrs() to take that attribute value?
Does this look okay?
(Note: Parts of the documentation text were updated using Codex.)
modified Documentation/core-api/dma-attributes.rst
@@ -179,3 +179,32 @@ interface when building their uAPIs, when possible.
It must never be used in an in-kernel driver that only works with
kernel memory.
+
+DMA_ATTR_CC_SHARED
+------------------
+
+This attribute indicates that a DMA mapping is shared, or decrypted, for
+confidential computing guests. For normal system memory, the caller must
+already have marked the memory decrypted with set_memory_decrypted(). CPU
+PTEs for the mapping must use pgprot_decrypted(), and the same shared
+semantic may be passed to a vIOMMU when it sets up the IOPTE.
+
+This attribute describes an existing mapping. It does not allocate shared
+backing pages and must not be passed to dma_alloc_attrs(). For MMIO, use
+this together with DMA_ATTR_MMIO to indicate shared MMIO. Unless
+DMA_ATTR_MMIO is provided, the mapping requires a struct page.
+
+DMA_ATTR_ALLOC_CC_SHARED
+------------------------
+
+This attribute indicates that a dma_alloc_attrs() allocation must use
+shared, or decrypted, backing pages for confidential computing guests.
+Allocation paths use this request when they select shared DMA pools,
+decrypt newly allocated pages or restore encryption on free.
+
+DMA_ATTR_ALLOC_CC_SHARED differs from DMA_ATTR_CC_SHARED in that it
+requests shared backing memory from the allocation path. DMA_ATTR_CC_SHARED
+describes an already-shared mapping and requires the caller to have
+prepared normal system memory before mapping it. Callers that need shared
+memory from dma_alloc_attrs() should request DMA_ATTR_ALLOC_CC_SHARED
+instead of DMA_ATTR_CC_SHARED.
modified include/linux/dma-mapping.h
@@ -103,6 +103,13 @@
*/
#define DMA_ATTR_CC_SHARED (1UL << 13)
+/*
+ * DMA_ATTR_ALLOC_CC_SHARED: Allocates DMA memory as shared (decrypted) for
+ * confidential computing guests. Unlike DMA_ATTR_CC_SHARED, this attribute
+ * is used by dma_alloc_attrs() paths that create shared backing pages;
+ * DMA_ATTR_CC_SHARED describes an already-shared mapping.
+ */
+#define DMA_ATTR_ALLOC_CC_SHARED (1UL << 14)
/*
* A dma_addr_t can hold any valid DMA or bus address for the platform. It can
* be given to a device to use as a DMA source or target. It is specific to a
^ permalink raw reply
* Re: [PATCH v18 6/7] coresight: ctcu: enable byte-cntr for TMC ETR devices
From: Jie Gan @ 2026-06-11 4:57 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Tingwei Zhang,
Bjorn Andersson, Konrad Dybcio
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
devicetree
In-Reply-To: <20260507-enable-byte-cntr-for-ctcu-v18-6-2b2d590463a3@oss.qualcomm.com>
On 5/7/2026 10:12 PM, Jie Gan wrote:
> The byte-cntr function provided by the CTCU device is used to transfer data
> from the ETR buffer to the userspace. An interrupt is triggered if the data
> size exceeds the threshold set in the BYTECNTRVAL register. The interrupt
> handler counts the number of triggered interruptions and the read function
> will read the data from the synced ETR buffer.
>
> Switching the sysfs_buf when current buffer is full or the timeout is
> triggered and resets rrp and rwp registers after switched the buffer.
> The synced buffer will become available for reading after the switch.
>
> Byte-cntr workflow:
> start -> ctcu_enable(ctcu_byte_cntr_start) -> tmc_enable_etr_sink ->
> tmc_read_prepare_etr(jump to tmc_read_prepare_byte_cntr) ->
> tmc_etr_get_sysfs_trace(jump to tmc_byte_cntr_get_data) ->
> tmc_disable_etr_sink -> ctcu_disable(ctcu_byte_cntr_stop) ->
> tmc_read_unprepare_etr(jump to tmc_read_unprepare_byte_cntr) -> finish
>
> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
> ---
> .../ABI/testing/sysfs-bus-coresight-devices-ctcu | 9 +
> drivers/hwtracing/coresight/Makefile | 2 +-
> .../hwtracing/coresight/coresight-ctcu-byte-cntr.c | 304 +++++++++++++++++++++
> drivers/hwtracing/coresight/coresight-ctcu-core.c | 127 ++++++++-
> drivers/hwtracing/coresight/coresight-ctcu.h | 79 +++++-
> drivers/hwtracing/coresight/coresight-tmc-core.c | 3 +-
> drivers/hwtracing/coresight/coresight-tmc-etr.c | 114 +++++++-
> drivers/hwtracing/coresight/coresight-tmc.h | 9 +
> 8 files changed, 622 insertions(+), 25 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu
> new file mode 100644
> index 000000000000..6e53a5197e53
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu
> @@ -0,0 +1,9 @@
> +What: /sys/bus/coresight/devices/<ctcu-name>/irq_enabled[0:1]
> +Date: May 2026
> +KernelVersion: 7.2
> +Contact: Tingwei Zhang <tingwei.zhang@oss.qualcomm.com>; Jinlong Mao <jinlong.mao@oss.qualcomm.com>; Jie Gan <jie.gan@oss.qualcomm.com>
> +Description:
> + (RW) Configure the flag to enable interrupt to count data during CTCU enablement.
> + An interrupt is generated when the data size exceeds the value set in the IRQ register.
> + 0 : disable
> + 1 : enable
> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> index ab16d06783a5..821a1b06b20c 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -55,5 +55,5 @@ coresight-cti-y := coresight-cti-core.o coresight-cti-platform.o \
> obj-$(CONFIG_ULTRASOC_SMB) += ultrasoc-smb.o
> obj-$(CONFIG_CORESIGHT_DUMMY) += coresight-dummy.o
> obj-$(CONFIG_CORESIGHT_CTCU) += coresight-ctcu.o
> -coresight-ctcu-y := coresight-ctcu-core.o
> +coresight-ctcu-y := coresight-ctcu-core.o coresight-ctcu-byte-cntr.o
> obj-$(CONFIG_CORESIGHT_KUNIT_TESTS) += coresight-kunit-tests.o
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c
> new file mode 100644
> index 000000000000..268194f35fd3
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c
> @@ -0,0 +1,304 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#include <linux/coresight.h>
> +#include <linux/device.h>
> +#include <linux/fs.h>
> +#include <linux/interrupt.h>
> +#include <linux/of_irq.h>
> +#include <linux/uaccess.h>
> +
> +#include "coresight-ctcu.h"
> +#include "coresight-priv.h"
> +#include "coresight-tmc.h"
> +
> +static irqreturn_t byte_cntr_handler(int irq, void *data)
> +{
> + struct ctcu_byte_cntr *byte_cntr_data = data;
> +
> + atomic_inc(&byte_cntr_data->irq_cnt);
> + wake_up(&byte_cntr_data->wq);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static void ctcu_cfg_byte_cntr_reg(struct ctcu_drvdata *drvdata, u32 val,
> + u32 offset)
> +{
> + /* A one value for IRQCTRL register represents 8 bytes */
> + ctcu_program_register(drvdata, val / 8, offset);
> +}
> +
> +static struct ctcu_byte_cntr *ctcu_get_byte_cntr(struct coresight_device *ctcu,
> + struct coresight_device *etr)
> +{
> + struct ctcu_drvdata *drvdata = dev_get_drvdata(ctcu->dev.parent);
> + int port;
> +
> + port = coresight_get_in_port(etr, ctcu);
> + if (port < 0 || port > 1)
> + return NULL;
> +
> + return &drvdata->byte_cntr_data[port];
> +}
> +
> +static bool ctcu_byte_cntr_switch_buffer(struct tmc_drvdata *etr_drvdata,
> + struct ctcu_byte_cntr *byte_cntr_data)
> +{
> + struct etr_buf_node *nd, *next, *curr_node = NULL, *picked_node = NULL;
> + struct etr_buf *curr_buf = etr_drvdata->sysfs_buf;
> + bool found_free_buf = false;
> +
> + if (WARN_ON(!etr_drvdata || !byte_cntr_data))
> + return false;
> +
> + /* Stop the ETR before initiating the switch */
> + if (coresight_get_mode(etr_drvdata->csdev) != CS_MODE_DISABLED)
> + tmc_etr_enable_disable_hw(etr_drvdata, false);
> +
> + list_for_each_entry_safe(nd, next, &etr_drvdata->etr_buf_list, link) {
> + /* curr_buf is free for next round */
> + if (nd->sysfs_buf == curr_buf) {
> + nd->is_free = true;
> + curr_node = nd;
> + } else if (!found_free_buf && nd->is_free) {
> + picked_node = nd;
> + found_free_buf = true;
> + }
> + }
> +
> + if (found_free_buf) {
> + curr_node->pos = 0;
> + curr_node->reading = true;
> + byte_cntr_data->buf_node = curr_node;
> + etr_drvdata->sysfs_buf = picked_node->sysfs_buf;
> + etr_drvdata->etr_buf = picked_node->sysfs_buf;
> + picked_node->is_free = false;
> + /* Reset irq_cnt for next etr_buf */
> + atomic_set(&byte_cntr_data->irq_cnt, 0);
> + /* Restart the ETR once a free buffer is available */
> + if (coresight_get_mode(etr_drvdata->csdev) != CS_MODE_DISABLED)
> + tmc_etr_enable_disable_hw(etr_drvdata, true);
> + }
> +
> + return found_free_buf;
> +}
> +
> +/*
> + * ctcu_byte_cntr_get_data() - reads data from the deactivated and filled buffer.
> + * The byte-cntr reading work reads data from the deactivated and filled buffer.
> + * The read operation waits for a buffer to become available, either filled or
> + * upon timeout, and then reads trace data from the synced buffer.
> + */
> +static ssize_t tmc_byte_cntr_get_data(struct tmc_drvdata *etr_drvdata, loff_t pos,
> + size_t len, char **bufpp)
> +{
> + struct coresight_device *ctcu = tmc_etr_get_ctcu_device(etr_drvdata);
> + struct device *dev = &etr_drvdata->csdev->dev;
> + struct ctcu_byte_cntr *byte_cntr_data;
> + struct etr_buf *sysfs_buf;
> + atomic_t *irq_cnt;
> + ssize_t actual;
> + int ret;
> +
> + byte_cntr_data = ctcu_get_byte_cntr(ctcu, etr_drvdata->csdev);
> + if (!byte_cntr_data || !byte_cntr_data->irq_enabled)
> + return -EINVAL;
> +
> + irq_cnt = &byte_cntr_data->irq_cnt;
> +
> +wait_buffer:
> + if (!byte_cntr_data->buf_node) {
> + ret = wait_event_interruptible_timeout(byte_cntr_data->wq,
> + (atomic_read(irq_cnt) >= MAX_IRQ_CNT - 1) ||
> + !byte_cntr_data->enable,
> + BYTE_CNTR_TIMEOUT);
> + if (ret < 0)
> + return ret;
> + /*
> + * The current etr_buf is almost full or timeout is triggered,
> + * so switch the buffer and mark the switched buffer as reading.
> + */
> + if (byte_cntr_data->enable) {
> + if (!ctcu_byte_cntr_switch_buffer(etr_drvdata, byte_cntr_data)) {
> + dev_err(dev, "Switch buffer failed for the byte-cntr\n");
> + return -ENOMEM;
> + }
> + } else {
> + /* Exit byte-cntr reading */
> + return 0;
> + }
> + }
> +
> + /* Check the status of current etr_buf */
> + if (atomic_read(irq_cnt) >= MAX_IRQ_CNT)
> + dev_warn(dev, "Data overwrite happened\n");
> +
> + pos = byte_cntr_data->buf_node->pos;
> + sysfs_buf = byte_cntr_data->buf_node->sysfs_buf;
> + actual = tmc_etr_read_sysfs_buf(sysfs_buf, pos, len, bufpp);
> + if (actual <= 0) {
> + /* Reset buf_node upon reading is finished or failed */
> + byte_cntr_data->buf_node->reading = false;
> + byte_cntr_data->buf_node = NULL;
> +
> + /*
> + * Nothing in the buffer, waiting for the next buffer
> + * to be filled.
> + */
> + if (actual == 0)
> + goto wait_buffer;
> + }
> +
> + return actual;
> +}
> +
> +static int tmc_read_prepare_byte_cntr(struct tmc_drvdata *etr_drvdata)
> +{
> + struct coresight_device *ctcu = tmc_etr_get_ctcu_device(etr_drvdata);
> + struct ctcu_byte_cntr *byte_cntr_data;
> + unsigned long flags;
> + int ret = 0;
> +
> + /* byte-cntr is operating with SYSFS mode being enabled only */
> + if (coresight_get_mode(etr_drvdata->csdev) != CS_MODE_SYSFS)
> + return -EINVAL;
> +
> + byte_cntr_data = ctcu_get_byte_cntr(ctcu, etr_drvdata->csdev);
> + if (!byte_cntr_data || !byte_cntr_data->irq_enabled)
> + return -EINVAL;
> +
> + raw_spin_lock_irqsave(&byte_cntr_data->spin_lock, flags);
> + if (byte_cntr_data->reading) {
> + raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
> + return -EBUSY;
> + }
> +
> + /* byte_cntr_data->enable may race with ctcu_platform_remove() */
> + if (!byte_cntr_data->enable) {
> + raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
> + return -ENODEV;
> + }
> +
> + byte_cntr_data->reading = true;
> + raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
> + /* Setup an available etr_buf_list for byte-cntr */
> + ret = tmc_create_etr_buf_list(etr_drvdata, 2);
> + if (ret) {
> + byte_cntr_data->reading = false;
> + return ret;
> + }
> +
> + guard(raw_spinlock_irqsave)(&byte_cntr_data->spin_lock);
> + atomic_set(&byte_cntr_data->irq_cnt, 0);
> + /*
> + * Configure the byte-cntr register to enable IRQ. The configured
> + * size is 5% of the buffer_size.
> + */
> + ctcu_cfg_byte_cntr_reg(byte_cntr_data->ctcu_drvdata,
> + etr_drvdata->size / MAX_IRQ_CNT,
> + byte_cntr_data->irq_ctrl_offset);
> + enable_irq_wake(byte_cntr_data->irq);
> + byte_cntr_data->buf_node = NULL;
> +
> + return 0;
> +}
> +
> +static int tmc_read_unprepare_byte_cntr(struct tmc_drvdata *etr_drvdata)
> +{
> + struct coresight_device *ctcu = tmc_etr_get_ctcu_device(etr_drvdata);
> + struct ctcu_byte_cntr *byte_cntr_data;
> +
> + byte_cntr_data = ctcu_get_byte_cntr(ctcu, etr_drvdata->csdev);
> + if (!byte_cntr_data || !byte_cntr_data->irq_enabled)
Found an issue here. Need add one more condition to address the issue:
if (!byte_cntr_data || !byte_cntr_data->irq_enabled ||
!byte_cntr_data->reading)
In tmc_read_prepare_etr(), when byte_cntr_sysfs_ops is set but
tmc_read_prepare_byte_cntr() returns an error, the code falls through
to the normal prepare path and sets drvdata->reading = true. In the
paired tmc_read_unprepare_etr(), if byte_cntr_ops is still set and
tmc_read_unprepare_byte_cntr() returns 0 (because irq_enabled=true, even
though byte_cntr_data->reading was never set), the function returns
early without clearing drvdata->reading.
Thanks,
Jie
> + return -EINVAL;
> +
> + tmc_clean_etr_buf_list(etr_drvdata);
> + scoped_guard(raw_spinlock_irqsave, &byte_cntr_data->spin_lock) {
> + /* Configure the byte-cntr register to disable IRQ */
> + ctcu_cfg_byte_cntr_reg(byte_cntr_data->ctcu_drvdata, 0,
> + byte_cntr_data->irq_ctrl_offset);
> + disable_irq_wake(byte_cntr_data->irq);
> + byte_cntr_data->buf_node = NULL;
> + byte_cntr_data->reading = false;
> + }
> + wake_up(&byte_cntr_data->wq);
> +
> + return 0;
> +}
> +
> +const struct tmc_sysfs_ops byte_cntr_sysfs_ops = {
> + .read_prepare = tmc_read_prepare_byte_cntr,
> + .read_unprepare = tmc_read_unprepare_byte_cntr,
> + .get_trace_data = tmc_byte_cntr_get_data,
> +};
> +
> +/* Start the byte-cntr function when the path is enabled. */
> +void ctcu_byte_cntr_start(struct coresight_device *csdev, struct coresight_path *path)
> +{
> + struct coresight_device *sink = coresight_get_sink(path);
> + struct ctcu_byte_cntr *byte_cntr_data;
> +
> + byte_cntr_data = ctcu_get_byte_cntr(csdev, sink);
> + if (!byte_cntr_data)
> + return;
> +
> + /* Don't start byte-cntr function when irq_enabled is not set. */
> + if (!byte_cntr_data->irq_enabled || byte_cntr_data->enable)
> + return;
> +
> + guard(raw_spinlock_irqsave)(&byte_cntr_data->spin_lock);
> + byte_cntr_data->enable = true;
> +}
> +
> +/* Stop the byte-cntr function when the path is disabled. */
> +void ctcu_byte_cntr_stop(struct coresight_device *csdev, struct coresight_path *path)
> +{
> + struct coresight_device *sink = coresight_get_sink(path);
> + struct ctcu_byte_cntr *byte_cntr_data;
> +
> + if (coresight_get_mode(sink) == CS_MODE_SYSFS)
> + return;
> +
> + byte_cntr_data = ctcu_get_byte_cntr(csdev, sink);
> + if (!byte_cntr_data)
> + return;
> +
> + guard(raw_spinlock_irqsave)(&byte_cntr_data->spin_lock);
> + byte_cntr_data->enable = false;
> +}
> +
> +void ctcu_byte_cntr_init(struct device *dev, struct ctcu_drvdata *drvdata, int etr_num)
> +{
> + struct ctcu_byte_cntr *byte_cntr_data;
> + struct device_node *nd = dev->of_node;
> + int irq_num, ret, i, irq_registered = 0;
> +
> + for (i = 0; i < etr_num; i++) {
> + byte_cntr_data = &drvdata->byte_cntr_data[i];
> + irq_num = of_irq_get(nd, i);
> + if (irq_num < 0) {
> + dev_err(dev, "Failed to get IRQ from DT for port%d\n", i);
> + continue;
> + }
> +
> + ret = devm_request_irq(dev, irq_num, byte_cntr_handler,
> + IRQF_TRIGGER_RISING | IRQF_SHARED,
> + dev_name(dev), byte_cntr_data);
> + if (ret) {
> + dev_err(dev, "Failed to register IRQ for port%d\n", i);
> + continue;
> + }
> +
> + byte_cntr_data->irq = irq_num;
> + byte_cntr_data->ctcu_drvdata = drvdata;
> + init_waitqueue_head(&byte_cntr_data->wq);
> + raw_spin_lock_init(&byte_cntr_data->spin_lock);
> + irq_registered++;
> + }
> +
> + if (irq_registered)
> + tmc_etr_set_byte_cntr_sysfs_ops(&byte_cntr_sysfs_ops);
> +}
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> index e8720026c9e3..2da1a6f3d29f 100644
> --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /*
> - * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2024-2026 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> */
>
> #include <linux/clk.h>
> @@ -18,6 +19,7 @@
>
> #include "coresight-ctcu.h"
> #include "coresight-priv.h"
> +#include "coresight-tmc.h"
>
> #define ctcu_writel(drvdata, val, offset) __raw_writel((val), drvdata->base + offset)
> #define ctcu_readl(drvdata, offset) __raw_readl(drvdata->base + offset)
> @@ -43,17 +45,21 @@
>
> #define CTCU_ATID_REG_BIT(traceid) (traceid % 32)
> #define CTCU_ATID_REG_SIZE 0x10
> +#define CTCU_ETR0_IRQCTRL 0x6c
> +#define CTCU_ETR1_IRQCTRL 0x70
> #define CTCU_ETR0_ATID0 0xf8
> #define CTCU_ETR1_ATID0 0x108
>
> static const struct ctcu_etr_config sa8775p_etr_cfgs[] = {
> {
> - .atid_offset = CTCU_ETR0_ATID0,
> - .port_num = 0,
> + .atid_offset = CTCU_ETR0_ATID0,
> + .irq_ctrl_offset = CTCU_ETR0_IRQCTRL,
> + .port_num = 0,
> },
> {
> - .atid_offset = CTCU_ETR1_ATID0,
> - .port_num = 1,
> + .atid_offset = CTCU_ETR1_ATID0,
> + .irq_ctrl_offset = CTCU_ETR1_IRQCTRL,
> + .port_num = 1,
> },
> };
>
> @@ -62,6 +68,85 @@ static const struct ctcu_config sa8775p_cfgs = {
> .num_etr_config = ARRAY_SIZE(sa8775p_etr_cfgs),
> };
>
> +void ctcu_program_register(struct ctcu_drvdata *drvdata, u32 val, u32 offset)
> +{
> + CS_UNLOCK(drvdata->base);
> + ctcu_writel(drvdata, val, offset);
> + CS_LOCK(drvdata->base);
> +}
> +
> +static ssize_t irq_enabled_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct ctcu_byte_cntr_irq_attribute *irq_attr =
> + container_of(attr, struct ctcu_byte_cntr_irq_attribute, attr);
> + struct ctcu_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + u8 port = irq_attr->port;
> +
> + if (!drvdata->byte_cntr_data[port].irq_ctrl_offset)
> + return -EINVAL;
> +
> + return sysfs_emit(buf, "%u\n",
> + (unsigned int)drvdata->byte_cntr_data[port].irq_enabled);
> +}
> +
> +static ssize_t irq_enabled_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf,
> + size_t size)
> +{
> + struct ctcu_byte_cntr_irq_attribute *irq_attr =
> + container_of(attr, struct ctcu_byte_cntr_irq_attribute, attr);
> + struct ctcu_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + u8 port = irq_attr->port;
> + unsigned long val;
> +
> + if (kstrtoul(buf, 0, &val))
> + return -EINVAL;
> +
> + guard(raw_spinlock_irqsave)(&drvdata->byte_cntr_data[port].spin_lock);
> + if (drvdata->byte_cntr_data[port].reading)
> + return -EBUSY;
> + else if (drvdata->byte_cntr_data[port].irq_ctrl_offset)
> + drvdata->byte_cntr_data[port].irq_enabled = !!val;
> +
> + return size;
> +}
> +
> +static umode_t irq_enabled_is_visible(struct kobject *kobj,
> + struct attribute *attr, int n)
> +{
> + struct device_attribute *dev_attr =
> + container_of(attr, struct device_attribute, attr);
> + struct ctcu_byte_cntr_irq_attribute *irq_attr =
> + container_of(dev_attr, struct ctcu_byte_cntr_irq_attribute, attr);
> + struct device *dev = kobj_to_dev(kobj);
> + struct ctcu_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + u8 port = irq_attr->port;
> +
> + if (drvdata && drvdata->byte_cntr_data[port].irq_ctrl_offset)
> + return attr->mode;
> +
> + return 0;
> +}
> +
> +static struct attribute *ctcu_attrs[] = {
> + ctcu_byte_cntr_irq_rw(0),
> + ctcu_byte_cntr_irq_rw(1),
> + NULL,
> +};
> +
> +static struct attribute_group ctcu_attr_grp = {
> + .attrs = ctcu_attrs,
> + .is_visible = irq_enabled_is_visible,
> +};
> +
> +static const struct attribute_group *ctcu_attr_grps[] = {
> + &ctcu_attr_grp,
> + NULL,
> +};
> +
> static void ctcu_program_atid_register(struct ctcu_drvdata *drvdata, u32 reg_offset,
> u8 bit, bool enable)
> {
> @@ -140,11 +225,15 @@ static int ctcu_set_etr_traceid(struct coresight_device *csdev, struct coresight
> static int ctcu_enable(struct coresight_device *csdev, enum cs_mode mode,
> struct coresight_path *path)
> {
> + ctcu_byte_cntr_start(csdev, path);
> +
> return ctcu_set_etr_traceid(csdev, path, true);
> }
>
> static int ctcu_disable(struct coresight_device *csdev, struct coresight_path *path)
> {
> + ctcu_byte_cntr_stop(csdev, path);
> +
> return ctcu_set_etr_traceid(csdev, path, false);
> }
>
> @@ -195,7 +284,10 @@ static int ctcu_probe(struct platform_device *pdev)
> for (i = 0; i < cfgs->num_etr_config; i++) {
> etr_cfg = &cfgs->etr_cfgs[i];
> drvdata->atid_offset[i] = etr_cfg->atid_offset;
> + drvdata->byte_cntr_data[i].irq_ctrl_offset =
> + etr_cfg->irq_ctrl_offset;
> }
> + ctcu_byte_cntr_init(dev, drvdata, cfgs->num_etr_config);
> }
> }
>
> @@ -209,6 +301,7 @@ static int ctcu_probe(struct platform_device *pdev)
> desc.dev = dev;
> desc.ops = &ctcu_ops;
> desc.access = CSDEV_ACCESS_IOMEM(base);
> + desc.groups = ctcu_attr_grps;
> raw_spin_lock_init(&drvdata->spin_lock);
>
> drvdata->csdev = coresight_register(&desc);
> @@ -244,10 +337,34 @@ static int ctcu_platform_probe(struct platform_device *pdev)
> static void ctcu_platform_remove(struct platform_device *pdev)
> {
> struct ctcu_drvdata *drvdata = platform_get_drvdata(pdev);
> + struct ctcu_byte_cntr *byte_cntr_data;
> + unsigned long flags;
> + int i;
>
> if (WARN_ON(!drvdata))
> return;
>
> + /*
> + * Signal all active byte-cntr readers to exit, then wait for them to
> + * finish before resetting the ops pointer and freeing driver data.
> + * Without this, a reader blocked in wait_event_interruptible_timeout()
> + * would access the freed ctcu_drvdata wait-queue head (use-after-free).
> + */
> + for (i = 0; i < ETR_MAX_NUM; i++) {
> + byte_cntr_data = &drvdata->byte_cntr_data[i];
> + raw_spin_lock_irqsave(&byte_cntr_data->spin_lock, flags);
> + /* Set enable=false for all ports to signal teardown to racing readers */
> + byte_cntr_data->enable = false;
> + if (!byte_cntr_data->reading) {
> + raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
> + continue;
> + }
> + raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
> + wake_up_all(&byte_cntr_data->wq);
> + wait_event(byte_cntr_data->wq, !byte_cntr_data->reading);
> + }
> +
> + tmc_etr_reset_byte_cntr_sysfs_ops();
> ctcu_remove(pdev);
> pm_runtime_disable(&pdev->dev);
> }
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu.h b/drivers/hwtracing/coresight/coresight-ctcu.h
> index e9594c38dd91..a2ae0a0d91d0 100644
> --- a/drivers/hwtracing/coresight/coresight-ctcu.h
> +++ b/drivers/hwtracing/coresight/coresight-ctcu.h
> @@ -1,23 +1,31 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> /*
> - * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2024-2026 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> */
>
> #ifndef _CORESIGHT_CTCU_H
> #define _CORESIGHT_CTCU_H
> +
> +#include <linux/time.h>
> #include "coresight-trace-id.h"
>
> /* Maximum number of supported ETR devices for a single CTCU. */
> #define ETR_MAX_NUM 2
>
> +#define BYTE_CNTR_TIMEOUT (3 * HZ)
> +#define MAX_IRQ_CNT 20
> +
> /**
> * struct ctcu_etr_config
> * @atid_offset: offset to the ATID0 Register.
> - * @port_num: in-port number of CTCU device that connected to ETR.
> + * @port_num: in-port number of the CTCU device that connected to ETR.
> + * @irq_ctrl_offset: offset to the BYTECNTRVAL register.
> */
> struct ctcu_etr_config {
> const u32 atid_offset;
> const u32 port_num;
> + const u32 irq_ctrl_offset;
> };
>
> struct ctcu_config {
> @@ -25,15 +33,68 @@ struct ctcu_config {
> int num_etr_config;
> };
>
> -struct ctcu_drvdata {
> - void __iomem *base;
> - struct clk *apb_clk;
> - struct device *dev;
> - struct coresight_device *csdev;
> +/**
> + * struct ctcu_byte_cntr
> + * @enable: indicates that byte_cntr function is enabled or not.
> + * @irq_enabled: indicates that the interruption is enabled.
> + * @reading: indicates that byte_cntr is reading.
> + * @irq: allocated number of the IRQ.
> + * @irq_cnt: IRQ count number of the triggered interruptions.
> + * @wq: waitqueue for reading data from ETR buffer.
> + * @spin_lock: spinlock of the byte_cntr_data.
> + * @irq_ctrl_offset: offset to the BYTECNTVAL Register.
> + * @ctcu_drvdata: drvdata of the CTCU device.
> + * @buf_node: etr_buf_node for reading.
> + */
> +struct ctcu_byte_cntr {
> + bool enable;
> + bool irq_enabled;
> + bool reading;
> + int irq;
> + atomic_t irq_cnt;
> + wait_queue_head_t wq;
> raw_spinlock_t spin_lock;
> - u32 atid_offset[ETR_MAX_NUM];
> + u32 irq_ctrl_offset;
> + struct ctcu_drvdata *ctcu_drvdata;
> + struct etr_buf_node *buf_node;
> +};
> +
> +struct ctcu_drvdata {
> + void __iomem *base;
> + struct clk *apb_clk;
> + struct device *dev;
> + struct coresight_device *csdev;
> + struct ctcu_byte_cntr byte_cntr_data[ETR_MAX_NUM];
> + raw_spinlock_t spin_lock;
> + u32 atid_offset[ETR_MAX_NUM];
> /* refcnt for each traceid of each sink */
> - u8 traceid_refcnt[ETR_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP];
> + u8 traceid_refcnt[ETR_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP];
> };
>
> +/**
> + * struct ctcu_byte_cntr_irq_attribute
> + * @attr: The device attribute.
> + * @port: port number.
> + */
> +struct ctcu_byte_cntr_irq_attribute {
> + struct device_attribute attr;
> + u8 port;
> +};
> +
> +#define ctcu_byte_cntr_irq_rw(port) \
> + (&((struct ctcu_byte_cntr_irq_attribute[]) { \
> + { \
> + __ATTR(irq_enabled##port, 0644, irq_enabled_show, \
> + irq_enabled_store), \
> + port, \
> + } \
> + })[0].attr.attr)
> +
> +void ctcu_program_register(struct ctcu_drvdata *drvdata, u32 val, u32 offset);
> +
> +/* Byte-cntr functions */
> +void ctcu_byte_cntr_start(struct coresight_device *csdev, struct coresight_path *path);
> +void ctcu_byte_cntr_stop(struct coresight_device *csdev, struct coresight_path *path);
> +void ctcu_byte_cntr_init(struct device *dev, struct ctcu_drvdata *drvdata, int port_num);
> +
> #endif
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index 110eedde077f..9f4fd86e8c32 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -293,7 +293,8 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
> return -EFAULT;
> }
>
> - *ppos += actual;
> + if (!tmc_etr_update_buf_node_pos(drvdata, actual))
> + *ppos += actual;
> dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual);
>
> return actual;
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index b0c5f3559085..54ca9616fa66 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -1168,6 +1168,8 @@ static int tmc_etr_enable_hw(struct tmc_drvdata *drvdata,
> return rc;
> }
>
> +static const struct tmc_sysfs_ops *byte_cntr_sysfs_ops;
> +
> /*
> * Return the available trace data in the buffer (starts at etr_buf->offset,
> * limited by etr_buf->len) from @pos, with a maximum limit of @len,
> @@ -1178,23 +1180,39 @@ static int tmc_etr_enable_hw(struct tmc_drvdata *drvdata,
> * We are protected here by drvdata->reading != 0, which ensures the
> * sysfs_buf stays alive.
> */
> -ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata,
> - loff_t pos, size_t len, char **bufpp)
> +ssize_t tmc_etr_read_sysfs_buf(struct etr_buf *sysfs_buf, loff_t pos,
> + size_t len, char **bufpp)
> {
> s64 offset;
> ssize_t actual = len;
> - struct etr_buf *etr_buf = drvdata->sysfs_buf;
>
> - if (pos + actual > etr_buf->len)
> - actual = etr_buf->len - pos;
> + if (pos + actual > sysfs_buf->len)
> + actual = sysfs_buf->len - pos;
> if (actual <= 0)
> return actual;
>
> /* Compute the offset from which we read the data */
> - offset = etr_buf->offset + pos;
> - if (offset >= etr_buf->size)
> - offset -= etr_buf->size;
> - return tmc_etr_buf_get_data(etr_buf, offset, actual, bufpp);
> + offset = sysfs_buf->offset + pos;
> + if (offset >= sysfs_buf->size)
> + offset -= sysfs_buf->size;
> + return tmc_etr_buf_get_data(sysfs_buf, offset, actual, bufpp);
> +}
> +EXPORT_SYMBOL_GPL(tmc_etr_read_sysfs_buf);
> +
> +ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata,
> + loff_t pos, size_t len, char **bufpp)
> +{
> + ssize_t ret;
> + const struct tmc_sysfs_ops *byte_cntr_ops = READ_ONCE(byte_cntr_sysfs_ops);
> +
> + if (byte_cntr_ops) {
> + ret = byte_cntr_ops->get_trace_data(drvdata, pos, len, bufpp);
> + /* Return the filled buffer */
> + if (ret > 0 || ret == -ENOMEM)
> + return ret;
> + }
> +
> + return tmc_etr_read_sysfs_buf(drvdata->sysfs_buf, pos, len, bufpp);
> }
>
> static struct etr_buf *
> @@ -1248,6 +1266,39 @@ static void __tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
>
> }
>
> +static void tmc_etr_reset_sysfs_buf(struct tmc_drvdata *drvdata)
> +{
> + u32 sts;
> +
> + CS_UNLOCK(drvdata->base);
> + tmc_write_rrp(drvdata, drvdata->sysfs_buf->hwaddr);
> + tmc_write_rwp(drvdata, drvdata->sysfs_buf->hwaddr);
> + sts = readl_relaxed(drvdata->base + TMC_STS) & ~TMC_STS_FULL;
> + writel_relaxed(sts, drvdata->base + TMC_STS);
> + CS_LOCK(drvdata->base);
> +}
> +
> +/**
> + * tmc_etr_enable_disable_hw - enable/disable the ETR hw.
> + * @drvdata: drvdata of the TMC device.
> + * @enable: indicates enable/disable.
> + */
> +void tmc_etr_enable_disable_hw(struct tmc_drvdata *drvdata, bool enable)
> +{
> + unsigned long flags;
> +
> + raw_spin_lock_irqsave(&drvdata->spinlock, flags);
> + if (enable) {
> + tmc_etr_reset_sysfs_buf(drvdata);
> + __tmc_etr_enable_hw(drvdata);
> + } else {
> + __tmc_etr_disable_hw(drvdata);
> + }
> +
> + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +}
> +EXPORT_SYMBOL_GPL(tmc_etr_enable_disable_hw);
> +
> void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
> {
> __tmc_etr_disable_hw(drvdata);
> @@ -2047,15 +2098,54 @@ int tmc_create_etr_buf_list(struct tmc_drvdata *drvdata, int num_nodes)
> }
> EXPORT_SYMBOL_GPL(tmc_create_etr_buf_list);
>
> +void tmc_etr_set_byte_cntr_sysfs_ops(const struct tmc_sysfs_ops *sysfs_ops)
> +{
> + WRITE_ONCE(byte_cntr_sysfs_ops, sysfs_ops);
> +}
> +EXPORT_SYMBOL_GPL(tmc_etr_set_byte_cntr_sysfs_ops);
> +
> +void tmc_etr_reset_byte_cntr_sysfs_ops(void)
> +{
> + WRITE_ONCE(byte_cntr_sysfs_ops, NULL);
> +}
> +EXPORT_SYMBOL_GPL(tmc_etr_reset_byte_cntr_sysfs_ops);
> +
> +bool tmc_etr_update_buf_node_pos(struct tmc_drvdata *drvdata, ssize_t size)
> +{
> + struct etr_buf_node *nd, *next;
> +
> + if (drvdata->config_type != TMC_CONFIG_TYPE_ETR)
> + return false;
> +
> + list_for_each_entry_safe(nd, next, &drvdata->etr_buf_list, link) {
> + if (nd && nd->reading) {
> + nd->pos += size;
> + return true;
> + }
> + }
> +
> + return false;
> +}
> +
> int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
> {
> int ret = 0;
> unsigned long flags;
> + const struct tmc_sysfs_ops *byte_cntr_ops;
>
> /* config types are set a boot time and never change */
> if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
> return -EINVAL;
>
> + byte_cntr_ops = READ_ONCE(byte_cntr_sysfs_ops);
> + if (byte_cntr_ops) {
> + ret = byte_cntr_ops->read_prepare(drvdata);
> + if (!ret || ret == -EBUSY)
> + return ret;
> +
> + ret = 0;
> + }
> +
> raw_spin_lock_irqsave(&drvdata->spinlock, flags);
> if (drvdata->reading) {
> ret = -EBUSY;
> @@ -2087,11 +2177,17 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
> {
> unsigned long flags;
> struct etr_buf *sysfs_buf = NULL;
> + const struct tmc_sysfs_ops *byte_cntr_ops;
>
> /* config types are set a boot time and never change */
> if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
> return -EINVAL;
>
> + byte_cntr_ops = READ_ONCE(byte_cntr_sysfs_ops);
> + if (byte_cntr_ops)
> + if (!byte_cntr_ops->read_unprepare(drvdata))
> + return 0;
> +
> raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
> /* RE-enable the TMC if need be */
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index fbb015079872..a15e2f93f16a 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -211,12 +211,15 @@ struct tmc_resrv_buf {
> /**
> * @sysfs_buf: Allocated sysfs_buf.
> * @is_free: Indicates whether the buffer is free to choose.
> + * @reading: Indicates byte_cntr is reading the buffer attached to
> + * the node.
> * @pos: Offset to the start of the buffer.
> * @link: list_head of the node.
> */
> struct etr_buf_node {
> struct etr_buf *sysfs_buf;
> bool is_free;
> + bool reading;
> loff_t pos;
> struct list_head link;
> };
> @@ -480,5 +483,11 @@ struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
> extern const struct attribute_group coresight_etr_group;
> void tmc_clean_etr_buf_list(struct tmc_drvdata *drvdata);
> int tmc_create_etr_buf_list(struct tmc_drvdata *drvdata, int num_nodes);
> +void tmc_etr_set_byte_cntr_sysfs_ops(const struct tmc_sysfs_ops *sysfs_ops);
> +void tmc_etr_reset_byte_cntr_sysfs_ops(void);
> +void tmc_etr_enable_disable_hw(struct tmc_drvdata *drvdata, bool enable);
> +bool tmc_etr_update_buf_node_pos(struct tmc_drvdata *drvdata, ssize_t size);
> +ssize_t tmc_etr_read_sysfs_buf(struct etr_buf *sysfs_buf, loff_t pos,
> + size_t len, char **bufpp);
>
> #endif
>
^ permalink raw reply
* Re: [PATCH RESEND v2 1/1] crypto: atmel-sha204a - fix heap info leak on I2C transfer failure
From: Herbert Xu @ 2026-06-11 4:58 UTC (permalink / raw)
To: Lothar Rubusch
Cc: thorsten.blum, davem, nicolas.ferre, alexandre.belloni,
claudiu.beznea, ardb, krzk+dt, linux-crypto, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260609094723.47237-1-l.rubusch@gmail.com>
On Tue, Jun 09, 2026 at 09:47:23AM +0000, Lothar Rubusch wrote:
>
> diff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c
> index 4c9af737b33a..20cd915ea8a3 100644
> --- a/drivers/crypto/atmel-sha204a.c
> +++ b/drivers/crypto/atmel-sha204a.c
> @@ -31,10 +31,15 @@ static void atmel_sha204a_rng_done(struct atmel_i2c_work_data *work_data,
> struct atmel_i2c_client_priv *i2c_priv = work_data->ctx;
> struct hwrng *rng = areq;
>
> - if (status)
> + if (status) {
> dev_warn_ratelimited(&i2c_priv->client->dev,
> "i2c transaction failed (%d)\n",
> status);
> + kfree(work_data);
> + rng->priv = 0;
Why is this necessary? It appears that rng_read_nonblocking already
zeroes rng->priv.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH] crypto: atmel-tdes - use scatterlist length before DMA mapping
From: Herbert Xu @ 2026-06-11 5:04 UTC (permalink / raw)
To: Thorsten Blum
Cc: David S. Miller, Nicolas Ferre, Alexandre Belloni, Claudiu Beznea,
Nicolas Royer, Eric Bénard, stable, linux-crypto,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260531204115.689052-3-thorsten.blum@linux.dev>
On Sun, May 31, 2026 at 10:41:17PM +0200, Thorsten Blum wrote:
> Using sg_dma_len() is only valid after mapping the scatterlist with
> dma_map_sg(). However, atmel_tdes_crypt_start() uses it before mapping
> to compare input/output lengths and to compute the transfer count.
>
> Use the original scatterlist lengths before DMA mapping to avoid reading
> stale or uninitialized DMA lengths when CONFIG_NEED_SG_DMA_LENGTH=y.
>
> Fixes: 13802005d8f2 ("crypto: atmel - add Atmel DES/TDES driver")
> Fixes: 1f858040c2f7 ("crypto: atmel-tdes - add support for latest release of the IP (0x700)")
> Cc: stable@vger.kernel.org
> Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
> ---
> drivers/crypto/atmel-tdes.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c
> index 643e507f9c02..0d62b24e9fc7 100644
> --- a/drivers/crypto/atmel-tdes.c
> +++ b/drivers/crypto/atmel-tdes.c
> @@ -463,14 +463,14 @@ static int atmel_tdes_crypt_start(struct atmel_tdes_dev *dd)
> IS_ALIGNED(dd->out_sg->length, dd->ctx->block_size);
> fast = in && out;
>
> - if (sg_dma_len(dd->in_sg) != sg_dma_len(dd->out_sg))
> + if (dd->in_sg->length != dd->out_sg->length)
> fast = 0;
> }
>
>
> if (fast) {
> - count = min_t(size_t, dd->total, sg_dma_len(dd->in_sg));
> - count = min_t(size_t, count, sg_dma_len(dd->out_sg));
> + count = min_t(size_t, dd->total, dd->in_sg->length);
> + count = min_t(size_t, count, dd->out_sg->length);
If fast == 1, then dd->in_sg->length must be equal to dd->out_sg->length,
so the second line is redundant.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v2] usb: gadget: aspeed_udc: check endpoint DMA allocation
From: Andrew Jeffery @ 2026-06-11 5:06 UTC (permalink / raw)
To: Ruoyu Wang, Neal Liu, Greg Kroah-Hartman
Cc: Joel Stanley, linux-aspeed, linux-usb, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260610121022.3-1-ruoyuw560@gmail.com>
On Wed, 2026-06-10 at 20:10 +0800, Ruoyu Wang wrote:
> ast_udc_probe() allocates a coherent DMA buffer used as the backing store
> for endpoint buffers. ast_udc_init_ep() derives per-endpoint buffer
> pointers from udc->ep0_buf, so a failed allocation is dereferenced during
> probe.
>
> Check the allocation before endpoint setup. The existing probe error path
> called ast_udc_remove(), which unregisters the gadget unconditionally and
> is not safe before usb_add_gadget_udc() succeeds. Add a local cleanup
> helper for probe failures so pre-registration failures only unwind the
> resources that were actually initialized.
>
> This was found by a local static analysis checker for unchecked allocator
> returns while scanning Linux 6.16. The change was checked by applying it
> to current mainline and by running checkpatch. I do not have access to
> Aspeed UDC hardware, so no runtime testing was performed.
>
> Fixes: 055276c13205 ("usb: gadget: add Aspeed ast2600 udc driver")
> Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Reviewed-by: Andrew Jeffery <andrew@codeconstruct.com.au>
^ permalink raw reply
* Re: [PATCH v6 2/2] ARM: dts: aspeed: ventura2: Add Meta ventura2 BMC
From: Kyle Hsieh @ 2026-06-11 5:24 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
devicetree, linux-arm-kernel, linux-aspeed, linux-kernel
In-Reply-To: <a8cdc7c23166823a8e1969408c667e6a8d758fe7.camel@codeconstruct.com.au>
On Wed, Jun 10, 2026 at 7:22 PM Andrew Jeffery
<andrew@codeconstruct.com.au> wrote:
>
> Hi Kyle,
>
> On Wed, 2026-06-10 at 09:22 +0800, Kyle Hsieh wrote:
> > Add linux device tree entry related to the Meta(Facebook) rmc-node.
> > The system uses an AT2600 BMC.
> > This node is named "ventura2".
> >
> > Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
>
> I have some comments on v5 that are applicable here too.
>
> https://lore.kernel.org/all/3d56889c004fc2d11b76ace6033c7ccfb8a37d03.camel@codeconstruct.com.au/
>
Hi Andrew,
Thanks for the review and suggestions!
To briefly answer your question: Ventura2 is Rack Management
Controller. It is a modular device primarily designed to manage liquid
cooling systems and monitor rack-level hardware states. Its key
hardware features include an extensive I2C/GPIO topology for
tray-level and rack-level liquid leakage detection, as well as MCTP
over I2C support for asynchronous device communications.
I will remove the redundant sentence and include this detailed
description of the platform's purpose and architecture in the commit
message for v7.
Also, the Sashiko AI bot just caught a missing `idle-state`
configuration for the MCTP I2C mux, so I will include that fix in v7
as well.
I will send out the v7 patch shortly.
Best regards,
Kyle Hsieh
> Andrew
^ permalink raw reply
* Re: [PATCH v6 04/20] dma-pool: track decrypted atomic pools and select them via attrs
From: Aneesh Kumar K.V @ 2026-06-11 5:25 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Jiri Pirko,
Michael Kelley
In-Reply-To: <20260609143242.GK2764304@ziepe.ca>
Jason Gunthorpe <jgg@ziepe.ca> writes:
> The sashiko note does look legit though:
>
> if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
> !gfpflags_allow_blocking(gfp) && !coherent) {
> page = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &cpu_addr,
> gfp, attrs, NULL);
> if (!page)
> return NULL;
>
> I don't see anything doing the force_dma_unencrypted test along this
> callchain..
>
> I guess it should be done one step up in dma_alloc_attrs() instead of
> in dma_direct_alloc()?
>
I think we should do something similar to what dma_map_phys() does here,
considering that we only support DMA direct with DMA_ATTR_CC_SHARED/DMA_ATTR_ALLOC_CC_SHARED.
@@ -637,6 +637,7 @@ void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
{
const struct dma_map_ops *ops = get_dma_ops(dev);
void *cpu_addr;
+ bool is_cc_shared;
WARN_ON_ONCE(!dev->coherent_dma_mask);
@@ -657,8 +658,17 @@ void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
/* let the implementation decide on the zone to allocate from: */
flag &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
+ if (force_dma_unencrypted(dev))
+ attrs |= DMA_ATTR_ALLOC_CC_SHARED;
+
+ is_cc_shared = attrs & DMA_ATTR_CC_SHARED;
+
if (dma_alloc_direct(dev, ops) || arch_dma_alloc_direct(dev)) {
cpu_addr = dma_direct_alloc(dev, size, dma_handle, flag, attrs);
+ } else if (is_cc_shared) {
+ trace_dma_alloc(dev, NULL, 0, size, DMA_BIDIRECTIONAL, flag,
+ attrs);
+ return NULL;
} else if (use_dma_iommu(dev)) {
cpu_addr = iommu_dma_alloc(dev, size, dma_handle, flag, attrs);
} else if (ops->alloc) {
-aneesh
^ permalink raw reply
* RE: [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART
From: Jason Li @ 2026-06-11 5:25 UTC (permalink / raw)
To: Krzysztof Kozlowski, Jason Li, Greg Kroah-Hartman, Jiri Slaby
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
Will Deacon, Arnd Bergmann, linux-serial@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <068a7ba8-5b1e-46e3-9388-ba288163eb10@kernel.org>
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Wednesday, June 10, 2026 7:47 PM
> To: Jason Li <jason.lee651024@gmail.com>; Jason Li
> <jason.li@cortina-access.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Jiri Slaby <jirislaby@kernel.org>
> Cc: Rob Herring <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>;
> Conor Dooley <conor+dt@kernel.org>; Catalin Marinas
> <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>; Arnd Bergmann
> <arnd@arndb.de>; linux-serial@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; devicetree@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access
> UART
>
> External mail :
> This email originated from outside the organization. Do not reply, click links, or
> open attachments unless you recognize the sender and know the content is
> safe.
>
> On 10/06/2026 13:28, Jason Li wrote:
> > Add DT binding schema for the Cortina-Access UART controller.
> > This IP is integrated into most CAXXXX SoC family members.
> >
> > Also add the vendor prefix for Cortina Access, Inc. and the top-level
> > ARM board binding document for the CA8289 (Venus) SoC.
> >
> > Signed-off-by: Jason Li <jason.li@cortina-access.com>
> > Assisted-by: Claude:claude-opus-4-8
> > ---
> > .../bindings/arm/cortina-access.yaml | 29 ++++++++++++
> > .../serial/cortina-access,serial.yaml | 46 +++++++++++++++++++
> > .../devicetree/bindings/vendor-prefixes.yaml | 2 +
> > MAINTAINERS | 7 +++
>
> This is somehow complete mess. serial and arm together?
>
> Please carefully read submitting patches (both documents!) and don't send
> AI-assisted slop.
>
> You must not combine independent works together.
>
>
Thank you, I'll separate patch for different yaml
> > 4 files changed, 84 insertions(+)
> > create mode 100644
> > Documentation/devicetree/bindings/arm/cortina-access.yaml
> > create mode 100644
> > Documentation/devicetree/bindings/serial/cortina-access,serial.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/arm/cortina-access.yaml
> > b/Documentation/devicetree/bindings/arm/cortina-access.yaml
> > new file mode 100644
> > index 000000000000..ec0320ed0c0b
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/cortina-access.yaml
> > @@ -0,0 +1,29 @@
> > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause %YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/arm/cortina-access.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Cortina-Access SoC boards
> > +
> > +maintainers:
> > + - Jason Li <jason.li@cortina-access.com>
> > +
> > +description:
> > + Boards based on Cortina-Access ARMv8 SoCs targeting networking and
> > + access applications.
> > +
> > +properties:
> > + $nodename:
> > + const: /
> > + compatible:
> > + oneOf:
> > + - description: Cortina-Access CA8289 (Venus) engineering board
> > + const: cortina-access,ca8289-engboard
> > +
> > + - description: Cortina-Access CA8289 (Venus) reference board
> > + const: cortina-access,ca8289-refboard
>
>
> Where is the SoC? This looks like very poor contribution. If you opened any
> existing recent board binding you would see it is done differently.
>
Thanks, I'll refer more exist examples to fix.
> Best regards,
> Krzysztof
Thanks,
Jason
^ permalink raw reply
* RE: [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board
From: Jason Li @ 2026-06-11 5:26 UTC (permalink / raw)
To: Krzysztof Kozlowski, Jason Li, Greg Kroah-Hartman, Jiri Slaby
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
Will Deacon, Arnd Bergmann, linux-serial@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <2fd7077e-1180-47eb-9d13-5a570b0959a4@kernel.org>
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Wednesday, June 10, 2026 7:50 PM
> To: Jason Li <jason.lee651024@gmail.com>; Jason Li
> <jason.li@cortina-access.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Jiri Slaby <jirislaby@kernel.org>
> Cc: Rob Herring <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>;
> Conor Dooley <conor+dt@kernel.org>; Catalin Marinas
> <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>; Arnd Bergmann
> <arnd@arndb.de>; linux-serial@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; devicetree@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC
> and Venus board
>
> External mail :
> This email originated from outside the organization. Do not reply, click links, or
> open attachments unless you recognize the sender and know the content is
> safe.
>
> On 10/06/2026 13:28, Jason Li wrote:
> > Add SoC DTSI for the Cortina-Access CA8289 (Venus) and a board DTS for
> > the Venus engineering board. The description covers the minimum set of
> > hardware nodes needed to boot a kernel with an INITRD rootfs: CPUs,
> > GIC, timer, PSCI, fixed clock and UART.
> >
> > Signed-off-by: Jason Li <jason.li@cortina-access.com>
> > Assisted-by: Claude:claude-opus-4-8
>
> SoB should be the last tag.
>
> Also, it does not match From field.
>
> > ---
> > MAINTAINERS | 1 +
> > arch/arm64/Kconfig.platforms | 10 ++
> > arch/arm64/boot/dts/Makefile | 1 +
> > arch/arm64/boot/dts/cortina-access/Makefile | 2 +
> > .../dts/cortina-access/ca8289-engboard.dts | 31 +++++
> > .../boot/dts/cortina-access/ca8289-soc.dtsi | 118 ++++++++++++++++++
> > 6 files changed, 163 insertions(+)
> > create mode 100644 arch/arm64/boot/dts/cortina-access/Makefile
> > create mode 100644
> > arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts
> > create mode 100644 arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS index
> > 515d89d96472..ebfdb9c267cc 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2826,6 +2826,7 @@ L: linux-arm-kernel@lists.infradead.org
> (moderated for non-subscribers)
> > S: Maintained
> > F: Documentation/devicetree/bindings/arm/cortina-access.yaml
> > F: Documentation/devicetree/bindings/serial/cortina-access,serial.yaml
> > +F: arch/arm64/boot/dts/cortina-access/
> >
> > ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE
> > M: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> > diff --git a/arch/arm64/Kconfig.platforms
> > b/arch/arm64/Kconfig.platforms index dc995a732117..ba6dda0660c3
> 100644
> > --- a/arch/arm64/Kconfig.platforms
> > +++ b/arch/arm64/Kconfig.platforms
> > @@ -134,6 +134,16 @@ config ARCH_CIX
> > This enables support for the Cixtech SoC family,
> > like P1(sky1).
> >
> > +config ARCH_CORTINA_ACCESS
> > + bool "Cortina-Access SoC Family"
> > + select GPIOLIB
> > + select PINCTRL
> > + help
> > + This enables support for Cortina-Access SoCs. The family
> > + includes ARMv8-based devices targeting networking and access
> > + applications.
> > + If you have a Cortina-Access board, say Y here.
> > +
> > config ARCH_EXYNOS
> > bool "Samsung Exynos SoC family"
> > select COMMON_CLK_SAMSUNG
> > diff --git a/arch/arm64/boot/dts/Makefile
> > b/arch/arm64/boot/dts/Makefile index 98ec8f1b76e4..a599f525fb9a 100644
> > --- a/arch/arm64/boot/dts/Makefile
> > +++ b/arch/arm64/boot/dts/Makefile
> > @@ -16,6 +16,7 @@ subdir-y += broadcom subdir-y += bst subdir-y +=
> > cavium subdir-y += cix
> > +subdir-y += cortina-access
> > subdir-y += exynos
> > subdir-y += freescale
> > subdir-y += hisilicon
> > diff --git a/arch/arm64/boot/dts/cortina-access/Makefile
> > b/arch/arm64/boot/dts/cortina-access/Makefile
> > new file mode 100644
> > index 000000000000..554893f381fe
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/cortina-access/Makefile
> > @@ -0,0 +1,2 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +dtb-$(CONFIG_ARCH_CORTINA_ACCESS) += ca8289-engboard.dtb
> > diff --git a/arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts
> > b/arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts
> > new file mode 100644
> > index 000000000000..c8289a0f8269
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts
> > @@ -0,0 +1,31 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * dts file for Cortina Access Venus Engineering Board
> > + *
> > + * Copyright (C) 2026, Cortina Access Inc.
> > + *
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "ca8289-soc.dtsi"
> > +
> > +/ {
> > + model = "Cortina Access Venus Engineering Board";
> > + compatible = "cortina-access,ca8289-engboard";
> > + #address-cells = <2>;
> > + #size-cells = <2>;
> > +
> > + aliases {
> > + serial0 = &uart0;
> > + };
> > +
> > + chosen {
> > + stdout-path = "serial0:115200n8";
> > + };
> > +
> > + memory@0 { /* 512MB */
> > + device_type = "memory";
> > + reg = <0x00000000 0x00000000 0x0 0x20000000>;
> > + };
> > +};
> > diff --git a/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi
> > b/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi
> > new file mode 100644
> > index 000000000000..8e7ffcf4ccab
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi
> > @@ -0,0 +1,118 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * dts file for Cortina Access CA8289 SoC
> > + *
> > + * Copyright (C) 2026, Cortina Access Inc.
> > + */
> > +
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/interrupt-controller/irq.h>
> > +
> > +/ {
> > + cpus {
> > + #address-cells = <2>;
> > + #size-cells = <0>;
> > +
> > + cpu0: cpu@0 {
> > + compatible = "arm,cortex-a55", "arm,armv8";
> > + device_type = "cpu";
> > + reg = <0x0 0x0>;
> > + enable-method = "psci";
> > + };
>
> Missing blank lines. Look at existing code how this is supposed to look like.
OK
> > + cpu1: cpu@100 {
> > + compatible = "arm,cortex-a55", "arm,armv8";
> > + device_type = "cpu";
> > + reg = <0x0 0x100>;
> > + enable-method = "psci";
> > + };
> > + cpu2: cpu@200 {
> > + compatible = "arm,cortex-a55", "arm,armv8";
> > + device_type = "cpu";
> > + reg = <0x0 0x200>;
> > + enable-method = "psci";
> > + };
> > + cpu3: cpu@300 {
> > + compatible = "arm,cortex-a55", "arm,armv8";
> > + device_type = "cpu";
> > + reg = <0x0 0x300>;
> > + enable-method = "psci";
> > + };
> > + cpu-map {
> > + cluster0 {
> > + core0 {
> > + cpu = <&cpu0>;
> > + };
> > + core1 {
> > + cpu = <&cpu1>;
> > + };
> > + core2 {
> > + cpu = <&cpu2>;
> > + };
> > + core3 {
> > + cpu = <&cpu3>;
> > + };
> > + };
> > + };
> > + };
> > +
> > + psci {
> > + compatible = "arm,psci-0.2";
> > + method = "smc";
> > + };
> > +
> > + gic: interrupt-controller@4f8000000 {
>
> And now you repeat basic mistakes:
> 1. Pointed out by W=1 dtbs_check build
> 2. Fixed long time in every source
> 3. Explicitly documented in writing bindings and DTS coding style
I'll revisit document and use dtbs_check to check that.
>
> > + compatible = "arm,gic-v3";
> > + #interrupt-cells = <3>;
> > + interrupt-controller;
> > + #redistributor-regions = <1>;
> > + reg = <0x00000004 0xF8000000 0 0x10000>,
> > + <0x00000004 0xF8040000 0 0x80000>;
>
> Read DTS coding style.
>
> > + };
> > +
> > + apb_pclk: apb-pclk {
>
> Nope, drop entire node.
>
> > + compatible = "fixed-clock";
> > + #clock-cells = <0>;
> > + clock-frequency = <125000000>;
> > + };
> > +
> > + reserved-memory {
> > + #address-cells = <2>;
> > + #size-cells = <2>;
> > + ranges;
> > +
> > + /* TrustZone reserved region; must not be mapped by the
> kernel */
> > + tz_pool: tz-buffer@f000000 {
> > + reg = <0x0 0x0F000000 0x0 0x1000000>;
> > + no-map;
> > + };
> > + };
> > +
> > + /* See
> Documentation/devicetree/bindings/timer/arm,arch_timer.yaml */
> > + timer {
> > + compatible = "arm,armv8-timer";
> > + interrupt-parent = <&gic>;
> > + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
> > + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> > + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> > + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> > + clock-frequency = <25000000>;
> > + };
> > +
> > + uart0: serial@f4329188 {
> > + device_type = "serial";
> > + compatible = "cortina-access,serial";
> > + reg = <0x00000000 0xf4329188 0x0 0x30>;
>
> This is AI slop. Whatever Claude convinced you to do, it is nothing like
> upstream kernel source.
>
> Best regards,
> Krzysztof
Thanks,
Jason
^ permalink raw reply
* RE: [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART
From: Jason Li @ 2026-06-11 5:26 UTC (permalink / raw)
To: Krzysztof Kozlowski, Jason Li, Greg Kroah-Hartman, Jiri Slaby
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
Will Deacon, Arnd Bergmann, linux-serial@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <021d5cb7-51bf-4221-8b58-0e8a777cb97c@kernel.org>
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Wednesday, June 10, 2026 7:51 PM
> To: Jason Li <jason.lee651024@gmail.com>; Jason Li
> <jason.li@cortina-access.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Jiri Slaby <jirislaby@kernel.org>
> Cc: Rob Herring <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>;
> Conor Dooley <conor+dt@kernel.org>; Catalin Marinas
> <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>; Arnd Bergmann
> <arnd@arndb.de>; linux-serial@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; devicetree@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access
> UART
>
> External mail :
> This email originated from outside the organization. Do not reply, click links, or
> open attachments unless you recognize the sender and know the content is
> safe.
>
> On 10/06/2026 13:28, Jason Li wrote:
> > +
> > +allOf:
> > + - $ref: serial.yaml#
> > +
> > +properties:
> > + compatible:
> > + const: cortina-access,serial
>
> Aren't writing bindings very clear about that? Please, take your time to read
> through the docs, so we will not need to repeat basic guidance. It is
> documented there on purpose.
>
Appreciate for your time on reviewing.
>
> Best regards,
> Krzysztof
Thanks,
Jason
^ permalink raw reply
* RE: [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support
From: Jason Li @ 2026-06-11 5:27 UTC (permalink / raw)
To: Arnd Bergmann, Jason Li, Greg Kroah-Hartman, Jiri Slaby
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
Will Deacon, linux-serial@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <7dcc8386-a0e0-4c79-a9f7-f63188bb997e@app.fastmail.com>
Hi Arnd,
Your memory is truly amazing; you even remember a submission from a few years ago.
Since the last sumbission was drop so I though restart a new one this time.
OK, I'll review all feedback and fix them for the next V6 submission.
Yes, we expect actual end-user products based on these SoCs, and our intention is to provide complete upstream support over time. The UART driver and DTS support submitted in this series are the first step in that effort.
Cortina-System and Cortina-Access are now totally different company.
Current aarch64 chipset are totally different with legacy gemini processor.
Realtek has many business unit, different BU may have upstream plan but they are individual.
Although Cortina-Access is a wholly-owned subsidiary of Realtek, our product development is entirely independent.
Thanks,
Jason
> -----Original Message-----
> From: Arnd Bergmann <arnd@arndb.de>
> Sent: Wednesday, June 10, 2026 8:51 PM
> To: Jason Li <jason.lee651024@gmail.com>; Jason Li
> <jason.li@cortina-access.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Jiri Slaby <jirislaby@kernel.org>
> Cc: Rob Herring <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>;
> Conor Dooley <conor+dt@kernel.org>; Catalin Marinas
> <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>;
> linux-serial@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and
> platform support
>
> External mail :
> This email originated from outside the organization. Do not reply, click links, or
> open attachments unless you recognize the sender and know the content is
> safe.
>
> On Wed, Jun 10, 2026, at 13:28, Jason Li wrote:
> > This series adds Linux kernel support for the UART controller
> > integrated in Cortina-Access SoCs, with CA8289 (Venus) as the first supported
> device.
>
> Hi Jason,
>
> Thanks a lot for your submission!
>
> I'm glad to see Cortina Access is getting back to upstreaming this support, I see
> that you first tries this in 2021 but didn't get very far at the time. The last
> submission was v4, so it would make sense to cound this one as v5 and
> continue with v6 next time.
>
> You have already received a number of comments, so I'll skip looking at the
> details for the moment and let you work through them.
>
> Regarding how to split up the patch series between uart and soc, I think
> sending them together during the review phase as you do here makes sense,
> but as they are loosely coupled, I think we will likely merge them separately.
> For simplicity, I would then just put the MAINTAINERS entry and the bindings
> for the vendor and board into the series for the soc tree.
>
> It would also help me if you could add some more context about the SoC into
> the patch description for the patch that adds the arm64 platform, in particular:
>
> - is this the only one you are planning to upstream at this
> point, or do you already have plans for other SoCs in this
> family?
>
> - do you expect to see full support for actual end-user
> products using these chips?
>
> - is there any shared lineage with the cortina-systems
> (storlink/storm, now marvell) gemini 32-bit chips that we
> already support, or with any of the Realtek SoCs that
> are also being upstreamed now?
>
> Arnd
^ permalink raw reply
* Re: [PATCH] crypto: atmel-ecc - remove stale comments in atmel_ecc_remove
From: Herbert Xu @ 2026-06-11 5:29 UTC (permalink / raw)
To: Thorsten Blum
Cc: David S. Miller, Nicolas Ferre, Alexandre Belloni, Claudiu Beznea,
linux-crypto, linux-arm-kernel, linux-kernel
In-Reply-To: <20260602165247.977197-3-thorsten.blum@linux.dev>
On Tue, Jun 02, 2026 at 06:52:49PM +0200, Thorsten Blum wrote:
> atmel_ecc_remove() no longer returns -EBUSY since commit 7df7563b16aa
> ("crypto: atmel-ecc - Remove duplicated error reporting in .remove()")
> and is a void function since commit ed5c2f5fd10d ("i2c: Make remove
> callback return void").
>
> Remove and update the outdated comments.
>
> Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
> ---
> drivers/crypto/atmel-ecc.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c
> index 9c380351d2f9..e6068dc0a0c1 100644
> --- a/drivers/crypto/atmel-ecc.c
> +++ b/drivers/crypto/atmel-ecc.c
> @@ -347,13 +347,11 @@ static void atmel_ecc_remove(struct i2c_client *client)
> {
> struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);
>
> - /* Return EBUSY if i2c client already allocated. */
> if (atomic_read(&i2c_priv->tfm_count)) {
> /*
> * After we return here, the memory backing the device is freed.
> - * That happens no matter what the return value of this function
> - * is because in the Linux device model there is no error
> - * handling for unbinding a driver.
> + * That happens because in the Linux device model there is no
> + * error handling for unbinding a driver.
> * If there is still some action pending, it probably involves
> * accessing the freed memory.
> */
Please fix this properly rather than fiddling with the comments.
Drivers should always fail gracefully if the hardware disappears.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH v3] media: bcm2835-unicam: Fix log status runtime access
From: Eugen Hristev @ 2026-06-11 5:29 UTC (permalink / raw)
To: Raspberry Pi Kernel Maintenance, Mauro Carvalho Chehab,
Florian Fainelli, Broadcom internal kernel review list, Ray Jui,
Scott Branden, Dave Stevenson, Hans Verkuil, Laurent Pinchart,
Sakari Ailus, Jean-Michel Hautbois
Cc: Naushir Patuck, linux-media, linux-rpi-kernel, linux-arm-kernel,
linux-kernel, Eugen Hristev
When requesting log status, the block might be powered off, but registers
are being read.
Avoid reading the registers if the device is not resumed, thus also avoid
powering up the device just for log status.
Fixes: 392cd78d495f ("media: bcm2835-unicam: Add support for CCP2/CSI2 camera interface")
Signed-off-by: Eugen Hristev <ehristev@kernel.org>
---
Changes in v3:
- Changed to check return value of pm_runtime_get_if_active() and only call
pm_runtime_put() if the device is active.
- Link to v2: https://patch.msgid.link/20260522-bcmpipm-v2-1-a3da66cbc9f0@kernel.org
Changes in v2:
- changed to use pm_runtime_get_if_active()
- add corresponding put()
- Link to v1: https://patch.msgid.link/20260521-bcmpipm-v1-1-3eba88d88045@kernel.org
To: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
To: Mauro Carvalho Chehab <mchehab@kernel.org>
To: Florian Fainelli <florian.fainelli@broadcom.com>
To: Ray Jui <rjui@broadcom.com>
To: Scott Branden <sbranden@broadcom.com>
To: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
To: Sakari Ailus <sakari.ailus@linux.intel.com>
To: Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Hans Verkuil <hverkuil@kernel.org>
To: Naushir Patuck <naush@raspberrypi.com>
Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
Cc: linux-media@vger.kernel.org
Cc: linux-rpi-kernel@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
drivers/media/platform/broadcom/bcm2835-unicam.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/media/platform/broadcom/bcm2835-unicam.c b/drivers/media/platform/broadcom/bcm2835-unicam.c
index 8d28ba0b59a3..96b51e29bba4 100644
--- a/drivers/media/platform/broadcom/bcm2835-unicam.c
+++ b/drivers/media/platform/broadcom/bcm2835-unicam.c
@@ -2043,6 +2043,7 @@ static int unicam_log_status(struct file *file, void *fh)
struct unicam_node *node = video_drvdata(file);
struct unicam_device *unicam = node->dev;
u32 reg;
+ int pm_active;
/* status for sub devices */
v4l2_device_call_all(&unicam->v4l2_dev, 0, core, log_status);
@@ -2052,6 +2053,14 @@ static int unicam_log_status(struct file *file, void *fh)
node->fmt.fmt.pix.width, node->fmt.fmt.pix.height);
dev_info(unicam->dev, "V4L2 format: %08x\n",
node->fmt.fmt.pix.pixelformat);
+
+ pm_active = pm_runtime_get_if_active(unicam->dev);
+ if (!pm_active) {
+ dev_info(unicam->dev,
+ "Live data N/A due to device inactive\n");
+ return 0;
+ }
+
reg = unicam_reg_read(unicam, UNICAM_IPIPE);
dev_info(unicam->dev, "Unpacking/packing: %u / %u\n",
unicam_get_field(reg, UNICAM_PUM_MASK),
@@ -2065,6 +2074,9 @@ static int unicam_log_status(struct file *file, void *fh)
dev_info(unicam->dev, "Write pointer: %08x\n",
unicam_reg_read(unicam, UNICAM_IBWP));
+ if (pm_active == 1)
+ pm_runtime_put(unicam->dev);
+
return 0;
}
---
base-commit: e98d21c170b01ddef366f023bbfcf6b31509fa83
change-id: 20260521-bcmpipm-6c578e73239c
Best regards,
--
Eugen Hristev <ehristev@kernel.org>
^ permalink raw reply related
* [PATCH v32 0/5] Add ASPEED AST2600 I2C controller driver
From: Ryan Chen @ 2026-06-11 5:31 UTC (permalink / raw)
To: jk, andriy.shevchenko, Andi Shyti, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Andrew Jeffery,
Benjamin Herrenschmidt, Rayn Chen, Philipp Zabel
Cc: linux-i2c, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, openbmc, Ryan Chen, Conor Dooley
This series adds support for the AST2600 I2C controller “new register
set” implementation.
The AST2600 I2C controller introduces a revised register layout which
separates controller and target functionality into distinct register
blocks, and extends clock divider configuration and packet-based
transfer support compared to the legacy mixed register layout used on
earlier ASPEED SoCs.
The current driver implementation for the AST2600 I2C peripheral is
through the hardware's "compatibility mode", which exposes a register
set that matches the previous generation hardware (AST2500 and earlier).
Instead, add a driver that works in new-register-set mode, to allow the
new features, and will provide support for future hardware that will
not implement compatibility mode.
In order to support the new mode, we need a DT binding change to
reflect the reference to the global register set. Since the binding
still represents the same (AST2600 SoC) physical hardware, we continue
to use the existing compatible string of "aspeed,ast2600-i2c-bus".
However: since we're changing semantics for an existing binding, we
allow backwards compatibility by selecting on presence/absence of the
newly-added properties, and fall back to the old driver (ie., in
compatibility mode) when we detect a DT using the old binding spec.
Specifically:
- ast2600-i2c-bus nodes that provide the `aspeed,global-regs` property
(present in the new binding and absent in the legacy binding) will be
successfully probed by the new driver
- ast2600-i2c-bus nodes without `aspeed,global-regs` continue to use the
existing driver (in legacy register mode), ensuring that platforms
with the current DTBs remain functional
Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
Changes in v32:
- 1/5: add MAINTAINERS entry for aspeed,ast2600-i2c.yaml in the same
patch that creates the file.
- 3/5: add if/then conditional schema: when aspeed,global-regs is
present, require reg to have at least two items. The new driver
unconditionally maps resource index 1 (the buffer SRAM region); a DT
with one reg entry and aspeed,global-regs passes schema validation but
fails probe. The constraint makes the schema consistent with driver
behaviour.
- 4/5: address follow-on code review issues:
- add MAINTAINERS entry for drivers/i2c/busses/i2c-ast2600.c.
- fix interrupt storm when msgs is NULL: clear PKT_DONE in the IRQ
handler; per the datasheet this auto-clears all associated status
bits.
- fix out-of-bounds: guard msgs_index against msgs_count before
indexing msgs array in ast2600_i2c_controller_packet_irq().
- fix use-after-free: WRITE_ONCE() null msgs before complete() in
all IRQ completion paths so trailing IRQs bail out immediately.
- fix race in timeout path: null msgs before re-enabling IER so a
late IRQ cannot access the caller's freed message buffer.
- fix 0-length SMBus block read hanging the bus: issue STOP via
CONTROLLER_TRIGGER_LAST_STOP, set stop_pending, poll for NORMAL_STOP.
- initialise clk_div_reg to I2CCG_DIV_CTRL and global_ctrl to 0
to avoid uninitialized values if regmap_read() fails.
- guard against clock-frequency = <0> in DT; default to 100 kHz
to prevent divide-by-zero in ast2600_i2c_ac_timing_config().
- remove AST2600_I2CM_BUS_RECOVER_FAIL from IER writes; bit 15 is
Reserved in I2CM10 (IER) and only exists as a status bit in I2CM14.
- 5/5: address follow-on code review issues:
- fix target RX data loss in master-abort path: remove BUFF_CTRL
zeroing that discarded pending target RX data stored in bits [29:24].
- fix use-after-free in master-abort path: null msgs and re-enable
IER before complete(), not after, preventing stale IRQ from touching
the newly-installed msgs of the next transfer.
- fix shared-buffer corruption on coalesced STOP+SLAVE_MATCH IRQ:
restore the SLAVE_PENDING guard on target_active = false. SLAVE_PENDING
(bit 29) is set when a new address-match is queued before the previous
DMA receive completes; clearing target_active in that case allows the
controller to overwrite the shared Tx/Rx buffer.
- use READ_ONCE() for all process-context reads of target_active;
the IRQ path writes it with WRITE_ONCE() and plain loads allow the
compiler to cache a stale value across the IER-disable window.
- Link to v31: https://lore.kernel.org/r/20260603-upstream_i2c-v31-0-ba7a02714f22@aspeedtech.com
Changes in v31:
- 1/5: clarify in the commit message that the second reg region is
optional (minItems: 1), matching the schema change from v30.
- 2/5: zero-initialise struct i2c_timings so the bus-frequency fallback
correctly triggers when clock-frequency is absent in the DT.
- 4/5: fix zero-length RX: ast2600_i2c_setup_buff_rx() now returns
-EINVAL for xfer_len <= 0, propagated through the controller packet
IRQ handler to abort the transfer instead of hanging until SW timeout.
- 4/5: address follow-on code review issues:
- Guard controller_packet_irq() against NULL msgs (post-timeout UAF).
- Clamp HW-reported xfer_len via ast2600_i2c_clamp_len() in TX_ACK
and RX_DONE to prevent out-of-bounds writes on HW length glitches.
- Use regmap_update_bits() for I2CG_CTRL to avoid clobbering shared
global bits across parallel bus probes (TOCTOU fix).
- Fix SMBus block read with recv_len == 0: set controller_xfer_cnt =
msg->len to satisfy the "msg done" check without an extra 1-byte RX.
- Mirror the controller timeout sequence in recover_bus() timeout path
(disable IER, synchronize_irq(), W1C ISR, reset master, restore IER).
- Remove unused #include <linux/of_device.h>.
- Remove dead adap.algo_data assignment in probe().
- 5/5: address follow-on target-mode code review issues:
- Clear target_active on any STOP (not just STOP without SLAVE_PENDING),
fixing a deadlock under coalesced IRQ events.
- Enable target IER in reg_target() rather than unconditionally in
probe(), matching the disable in unreg_target().
- Re-arm HW in SLAVE_PENDING|RX_DONE|WAIT_TX_DMA|STOP ISR case
(missing CMD_STS write left bus SCL-stretched until INACTIVE_TO).
- Default target ISR case: write TARGET_TRIGGER_CMD instead of
silently breaking, preventing bus hang on unhandled states.
- W1C-clear ADDR1/2/3_NAK bits in HW in target_irq() to prevent
stale NAK bits from bouncing controller transfers with -EBUSY.
- unreg_target(): write 0 to ADDR_CTRL instead of masking with
ADDR1_MASK, which left ADDR1_ENABLE (BIT(7)) set after unregister.
- Link to v30: https://lore.kernel.org/r/20260528-upstream_i2c-v30-0-5d4f9adc3530@aspeedtech.com
Changes in v30:
- 1/5: aspeed,ast2600-i2c.yaml: keep backward compatibility for
existing in-tree AST2600 device trees (Sashiko AI review).
- reg: add minItems: 1 so legacy single-reg DTs still validate.
- retain bus-frequency as a deprecated property so DTs that still
use it are not rejected by unevaluatedProperties: false.
- 2/5: new patch "i2c: aspeed: Read clock-frequency via
i2c_parse_fw_timings()". The legacy i2c-aspeed driver now reads
the standard clock-frequency property first and falls back to
bus-frequency, avoiding a silent 100 kHz downgrade when a DT
follows the updated binding but still binds to the legacy
driver (Sashiko AI review).
- 4/5: address Sashiko AI code review feedback:
- Use manual i2c_add_adapter() / i2c_del_adapter() instead of
devm_i2c_add_adapter() so the adapter is torn down before the
hardware is disabled in remove(); otherwise client .remove()
callbacks can fail or hang after FUN_CTRL/IER have been cleared.
- synchronize_irq() and clear pending IRQ status on the controller
timeout path to avoid the ISR racing with the next transfer and
touching freed msgs.
- Use clamp_t() for AC TIMING divisor / scl_low / scl_high so
extreme clock-frequency values cannot underflow into the unsigned
domain and corrupt the AC TIMING register.
- Derive the RX buffer offset from buf_size instead of hardcoding
0x10, since the dual-pool split is configurable.
- Clamp i2c-scl-clk-low-timeout-us to the TTIMEOUT field's 5-bit
range (max 31 * 1024us) and emit a dev_warn() instead of letting
AST2600_I2CC_TTIMEOUT()'s mask silently truncate larger values.
- Return -EBUSY (not -ENOMEM) for every ast2600_i2c_do_start()
failure path in the controller packet IRQ handler (NORMAL_STOP,
TX_ACK, and RX_DONE branches).
- Advertise I2C_AQ_NO_ZERO_LEN_READ via i2c_adapter_quirks so the
i2c-core rejects zero-byte reads before they reach the driver.
The AST2600 packet engine cannot encode a zero-length RX command
and would otherwise stall waiting for an RX_DONE that never
arrives.
- 5/5: address Sashiko AI code review feedback:
- Force-stop path (target IRQ aborting an in-flight controller
transfer): disable the controller IER and W1C-clear pending ISR
before calling complete(), then restore the IER after the
wake-up. Without the disable/clear sequence the controller IRQ
handler can race with the target abort path and double-complete
or touch freed msgs.
- unreg_target() teardown ordering: disable the target IER first,
then disable SLAVE_EN / clear ADDR_CTRL, synchronize_irq(), W1C
pending ISR, and only then NULL i2c_bus->target and clear
target_active. The old order left IER enabled while target was
being cleared, allowing an in-flight handler to dereference a
target pointer the caller had already freed.
- reg_target() bring-up ordering: assign i2c_bus->target before
enabling SLAVE_EN. Otherwise an IRQ that fires after SLAVE_EN
is set but before the pointer is stored finds target == NULL,
exits without clearing the ISR, and the unmasked event re-fires
as an IRQ storm.
- Use writel() instead of writeb() when staging a TX byte into
the target buffer. The AST2600 buffer SRAM only supports 32-bit
accesses; byte writes are silently dropped (or, on some
revisions, raise a bus fault), so a SLAVE_READ_REQUESTED reply
never reaches the master.
- reg_target() rejects 10-bit client addresses with
-EAFNOSUPPORT. AST2600_I2CS_ADDR1 is only a 7-bit field;
without the check, the high bits of a 10-bit address overflow
into the adjacent ADDR2 field and silently corrupt a second
target slot.
- Initialise the local `u8 value` to 0 in the target packet IRQ
handler. Its address is passed to i2c_slave_event() for events
such as I2C_SLAVE_STOP / I2C_SLAVE_READ_REQUESTED; a slave
backend that reads the byte before writing would otherwise leak
uninitialised kernel stack.
- Link to v29: https://lore.kernel.org/r/20260415-upstream_i2c-v29-0-317c1a905ae1@aspeedtech.com
Changes in v29:
- 2/4: remove aspeed,enable-dma properties.
- 3/4: update commit message remove transfer mode selection.
- 3/4: remove sysfs file.
- 3/4: remove define I2C_TARGET_MSG_BUF_SIZE and AST2600_I2C_DMA_SIZE.
- 3/4: remove buf_index in struct ast2600_i2c_bus.
- 3/4, 4/4: remove dma/byte mode, use buffer mode only.
- 4/4: fix race between unreg_target and IRQ handler.
- 4/4: move i2cs ier enable from ast2600_i2c_init to probe after master ier enable.
- Link to v28: https://lore.kernel.org/r/20260330-upstream_i2c-v28-0-17bdae39c5cb@aspeedtech.com
Changes in v28:
- 2/4: update commit message correspond with aspeed,enable-dma.
- 2/4: remove aspeed,transfer-mode and add aspeed,enable-dma property
and description.
- 2/4: Fix aspeed,enable-dma description to reflect hardware capability
rather than software behavior.
- 3/4: Separate xfer_mode_store into distinct parse and availability-check
steps by introducing ast2600_i2c_xfer_mode_check().
- 3/4: fix tx dma memcpy source point address.
- 3/4: Use a temporary variable for devm_platform_get_and_ioremap_resource()
to avoid storing an ERR_PTR in i2c_bus->buf_base; drop the redundant
NULL assignment in the error path since i2c_bus is kzalloc()ed.
- 3/4: Add ABI documentation file
Documentation/ABI/testing/sysfs-driver-ast2600-i2c.
- 4/4: fix typo condication -> condition.
- 4/4: fix compile error, when disable CONFIG_I2C_SLAVE.
- Link to v27: https://lore.kernel.org/r/20260324-upstream_i2c-v27-0-f19b511c8c28@aspeedtech.com
Changes in v27:
- 1/4 use aspeed,enable-dma instead aspeed,transfer-mode.
- 2/4 remove aspeed,transfer-mode selection instad aspeed,transfer-mode
- 2/4 add sysfs for xfer mode.
- Link to v26: https://lore.kernel.org/r/20260309-upstream_i2c-v26-0-5fedcff8ffe8@aspeedtech.com
Changes in v26:
- 1/4: binding reworks based on review feedback
- Link to v25: https://lore.kernel.org/r/20260225-upstream_i2c-v25-0-9f4bdd954f3f@aspeedtech.com
Changes in v25:
- Use b4 to send series.
- Rebase on v7.0-rc1.
- Clarify cover letter and commit logs based on review feedback.
- Remove the i2c-aspeed-core multiplexer infrastructure and
implement driver selection via conditional -ENODEV handling
in individual probe() functions.
- 3/4: incorporate review feedback and refactor new driver
- Link to v24: https://lore.kernel.org/r/20251118014034.820988-1-ryan_chen@aspeedtech.com
Changes in v24:
- aspeed,ast2600-i2c.yaml
- fix make dt_binding_check blank warning.
- Link to v23: https://lore.kernel.org/all/20251117025040.3622984-1-ryan_chen@aspeedtech.com/
Changes in v23:
- update typo patch (1/4) commit message.
- aspeed,ast2600-i2c.yaml
- update reg and description.
- i2c-ast2600.c controller
- replace ast2600_select_i2c_clock to ast2600_i2c_ac_timing_config.
- i2c-ast2600.c target
- I2C_TARGET_MSG_BUF_SIZE 256 to 4096
- remove blank line.
- refine Master comment description to controller
- Link to v22: https://lore.kernel.org/all/20251112085649.1903631-1-ryan_chen@aspeedtech.com/
Changes in v22:
- update patch (1/4) commit message add dts example reason.
- aspeed,ast2600-i2c.yaml @patch (1/4)
- rename ast2600-i2c.yaml to aspeed,ast2600-i2c.yaml.
- update reg, clock-frequency description.
- aspeed,ast2600-i2c.yaml @patch (2/4)
- aspeed,transfer-mode, aspeed,transfer-mode add for ast2600.
- i2c-aspeed-core.c,h @patch (3/4)
- add i2c-aspeed-core allow both old and new device trees using the
same compatible string "aspeed,ast2600-i2c-bus".
- Link to v21: https://lore.kernel.org/all/20251027061240.3427875-1-ryan_chen@aspeedtech.com/
Changes in v21:
- update patch (1/4) commit message
- i2c-ast2600.c
- move rst to local variable in ast2600_i2c_probe().
- Link to v20: https://lore.kernel.org/all/20251021013548.2375190-1-ryan_chen@aspeedtech.com/
Changes in v20:
- ast2600-i2c.yaml
- fix warning at make dt_binding_check.
- Link to v19: https://lore.kernel.org/all/20251020013200.1858325-1-ryan_chen@aspeedtech.com/
Changes in v19:
- Split AST2600 binding into its own YAML file
- Removed `aspeed,ast2600-i2c-bus` from `aspeed,i2c.yaml`
- Added `aspeed,global-regs` and `aspeed,transfer-mode` to AST2600 binding
- Link to v18: https://lore.kernel.org/all/20250820051832.3605405-1-ryan_chen@aspeedtech.com/
Changes in v18:
- refine patch (1/3) commit message (reason for commit not list.)
- i2c-ast2600.c
- remove redundant reset_control_deassert in driver probe.
- remove reset_control_assert(i2c_bus->rst) in driver remove.
- Link to v17: https://lore.kernel.org/all/20250814084156.1650432-1-ryan_chen@aspeedtech.com/
Changes in v17:
- move i2c new mode register and feature into driver commit message.
- aspeed,i2c.yaml
- remove multi-master properties.
- use aspeed,transfer-mode properties for aspeed,enable-byte/enable-dma.
-i2c-ast2600.c
- rename dma_safe_buf to controller_dma_safe_buf.
- fix ast2600_i2c_recover_bus return overflow warnings.
- add ast2600_i2c_target_packet_buff_irq unhandle case.
- add parameter "cmd" in ast2600_i2c_setup_dma_rx,
ast2600_i2c_setup_buff_rx, ast2600_i2c_setup_byte_rx
- use reset_control_deassert replace
devm_reset_control_get_shared_deasserted.
- useaspeed,transfer-mode properties for transfer mode setting.
- change compatible = "aspeed,ast2600-i2cv2" to "aspeed,ast2600-i2c-bus".
- Link to v16: https://lore.kernel.org/all/20250224055936.1804279-1-ryan_chen@aspeedtech.com/
Changes in v16:
- aspeed,i2c.yaml: add aspeed,enable-byte properties for force byte mode.
- i2c-ast2600.c
- change include asm/unaligned.h to linux/unaligned.h.
- add reset timeout councter when slave active timeout.
- modify issue i2c_recovery_bus before slave re-enable.
- add aspeed,enable-byte properties.
- Link to v15: https://lore.kernel.org/all/20241007035235.2254138-1-ryan_chen@aspeedtech.com/
Changes in v15:
- i2c-ast2600.c
- add include unaligned.h
- rename all master -> controller, slave -> target.
- keep multi-master to align property.
- remove no used element in ast2600_i2c_bus.
- Link to v14: https://lore.kernel.org/all/20241002070213.1165263-1-ryan_chen@aspeedtech.com/
Changes in v14:
- aspeed,i2c.yaml
- v13 change people reviewed-by tag, v14 fixed to original people tag,
modify to Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
- struct ast2600_i2c_bus layout optimal.
- ast2600_select_i2c_clock refine.
- ast2600_i2c_recover_bus overridden fix.
- dma_mapping_error() returned error code shadowed modify.
- buffer register in a 4-byte aligned simplified
- remove smbus alert
- Link to v13: https://lore.kernel.org/all/20240819092850.1590758-1-ryan_chen@aspeedtech.com/
Changes in v13:
- separate i2c master and slave driver to be two patchs.
- modify include header list, add bits.h include. remove of*.h
- modify (((x) >> 24) & GENMASK(5, 0)) to (((x) & GENMASK(29, 24)) >> 24)
- modify ast2600_select_i2c_clock function implement.
- modify ast2600_i2c_recover_bus function u32 claim to
u32 state = readl(i2c_bus->reg_base + AST2600_I2CC_STS_AND_BUFF);
- Link to v12: https://lore.kernel.org/all/20230714074522.23827-1-ryan_chen@aspeedtech.com/
Changes in v12:
- aspeed,i2c.yaml
- add Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
- i2c-ast2600.c
- update include by alphabetical order
- make just a one TAB and put the last two lines on the single one
- remove no used timing_table structre
- remove enum explicit assinment
- rewritten to avoid this and using loop in ast2600_select_i2c_clock
- use GENMASK for most 0xffff
- remove too many parentheses
- use str_read_write replace read write string
- remove redundant blank line after ast2600_i2c_bus_of_table
- fix wrong multi-line style of the comment
- use macro for i2c standard speeds
- remove useless noise dev_info
- Link to v11: https://lore.kernel.org/all/20230430041712.3247998-1-ryan_chen@aspeedtech.com/
Changes in v11:
- aspeed,i2c.yaml
- no change, the same with v10.
- i2c-ast2600.c
- modify alert_enable from int -> boolean.
- modify dbg string recovery -> recover.
- remove no need to init 0.
- remove new line after break.
- remove unneeded empty line.
- modify dma_alloc_coherent to dmam_alloc_coherent
- modify probe nomem return dev_err_probe
- modify i2c_add_adapter to devm_i2c_adapter
- modify checkpatch: Alignment should match open parenthesis
- modify checkpatch: braces {} should be used on all arms of this statement
- modify checkpatch: Unbalanced braces around else statement
- Link to v10: https://lore.kernel.org/all/20230415012848.1777768-1-ryan_chen@aspeedtech.com/
Changes in v10:
- aspeed,i2c.yaml
- move unevaluatedProperties after allOf.
- remove extra one blank line.
- i2c-ast2600.c
- no change, the same with v8.
- Link to v9: https://lore.kernel.org/all/20230405022825.333246-1-ryan_chen@aspeedtech.com/
Changes in v9:
- aspeed,i2c.yaml
- backoff to v7.
- no fix typo in maintainer's name and email. this would be another patch.
- no remove address-cells, size-cells, this would be another patch.
- use aspeed,enable-dma property instead of aspeed,xfer-mode selection.
- fix allOf and else false properties for aspeed,ast2600-i2cv2.
- i2c-ast2600.c
- no change, the same with v8
- Link to v8: https://lore.kernel.org/all/20230330073259.485606-1-ryan_chen@aspeedtech.com/
Changes in v8:
- aspeed,i2c.yaml
- modify commit message.
- Fix typo in maintainer's name and email.
- remove address-cells, size-cells.
- i2c-ast2600.c
- move "i2c timeout counter" comment description before property_read.
- remove redundant code "return ret" in probe end.
- Link to v7: https://lore.kernel.org/all/20230327092524.3916389-1-ryan_chen@aspeedtech.com/
Changes in v7:
- aspeed,i2c.yaml
- Update ASPEED I2C maintainers email.
- use aspeed,enable-dma property instead of aspeed,xfer-mode selection.
- fix allOf and else false properties for aspeed,ast2600-i2cv2.
- i2c-ast2600.c
- remove aspeed,xfer-mode instead of aspeed,enable-dma mode. buffer mode
is default.
- remove aspeed,timeout instead of i2c-scl-clk-low-timeout-us for
timeout setting.
- Link to v6: https://lore.kernel.org/all/20230226031321.3126756-1-ryan_chen@aspeedtech.com/
Changes in v6:
- remove aspeed,i2cv2.yaml, merge to aspeed,i2c.yaml -add support for
i2cv2 properites.
- i2c-ast2600.c
- fix ast2600_i2c_remove ordering.
- remove ast2600_i2c_probe goto labels, and add dev_err_probe -remove
redundant deb_dbg debug message.
- rename gr_regmap -> global_regs
- Link to v5: https://lore.kernel.org/all/20230220061745.1973981-1-ryan_chen@aspeedtech.com/
Changes in v5:
- remove ast2600-i2c-global.yaml, i2c-ast2600-global.c.
- i2c-ast2600.c
- remove legacy clock divide, all go for new clock divide.
- remove duplicated read isr.
- remove no used driver match
- fix probe return for each labels return.
- global use mfd driver, driver use phandle to regmap read/write.
- rename aspeed,i2c-ast2600.yaml to aspeed,i2cv2.yaml -remove bus-frequency.
- add required aspeed,gr
- add timeout, byte-mode, buff-mode properites.
- Link to v4: https://lore.kernel.org/all/20230201103359.1742140-1-ryan_chen@aspeedtech.com/
Changes in v4:
- fix i2c-ast2600.c driver buffer mode use single buffer conflit in
master slave mode both enable.
- fix kmemleak issue when use dma mode.
- fix typo aspeed,i2c-ast2600.yaml compatible is "aspeed,ast2600-i2c"
- fix typo aspeed,i2c-ast2600.ymal to aspeed,i2c-ast2600.yaml
- Link to v3: https://lore.kernel.org/all/20220516064900.30517-1-ryan_chen@aspeedtech.com/
Changes in v3:
- fix i2c global clock divide default value.
- remove i2c slave no used dev_dbg info.
- Link to v2: https://lore.kernel.org/all/20220413101735.27678-1-ryan_chen@aspeedtech.com/
Changes in v2:
- add i2c global ymal file commit.
- rename file name from new to ast2600.
aspeed-i2c-new-global.c -> i2c-ast2600-global.c
aspeed-i2c-new-global.h -> i2c-ast2600-global.h
i2c-new-aspeed.c -> i2c-ast2600.c
- rename all driver function name to ast2600.
- Link to v1: https://lore.kernel.org/all/20220323004009.943298-1-ryan_chen@aspeedtech.com/
---
Ryan Chen (5):
dt-bindings: i2c: Split AST2600 binding into a new YAML
i2c: aspeed: Read clock-frequency via i2c_parse_fw_timings()
dt-bindings: i2c: ast2600-i2c.yaml: Add global-regs properties
i2c: ast2600: Add controller driver for AST2600 new register set
i2c: ast2600: Add target mode support
.../bindings/i2c/aspeed,ast2600-i2c.yaml | 88 ++
.../devicetree/bindings/i2c/aspeed,i2c.yaml | 3 +-
MAINTAINERS | 2 +
drivers/i2c/busses/Makefile | 2 +-
drivers/i2c/busses/i2c-aspeed.c | 24 +-
drivers/i2c/busses/i2c-ast2600.c | 1290 ++++++++++++++++++++
6 files changed, 1400 insertions(+), 9 deletions(-)
---
base-commit: a293ec25d59dd96309058c70df5a4dd0f889a1e4
change-id: 20260223-upstream_i2c-ebd07f89739c
Best regards,
--
Ryan Chen <ryan_chen@aspeedtech.com>
^ permalink raw reply
* [PATCH v32 1/5] dt-bindings: i2c: Split AST2600 binding into a new YAML
From: Ryan Chen @ 2026-06-11 5:31 UTC (permalink / raw)
To: jk, andriy.shevchenko, Andi Shyti, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Andrew Jeffery,
Benjamin Herrenschmidt, Rayn Chen, Philipp Zabel
Cc: linux-i2c, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, openbmc, Ryan Chen, Conor Dooley
In-Reply-To: <20260611-upstream_i2c-v32-0-b66eba921d01@aspeedtech.com>
The AST2600 I2C controller introduces a completely new register layout
with separate controller and target register blocks, unlike the mixed
register layout used by AST2400/AST2500.
Move AST2600 I2C binding from aspeed,i2c.yaml to a dedicated
aspeed,ast2600-i2c.yaml schema.
Besides the split, this also adjusts for AST2600-specific requirements.
- describe two reg regions (controller register block + buffer block);
the second region is optional (minItems: 1) so existing AST2600 DTs
that only declare the controller register block continue to validate
- use clock-frequency for bus speed description
- interrupts are required on AST2600
- use correct DTS coding style in example
No compatible strings are changed.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
Changes in v31:
- Commit message body: clarify that the second reg region is optional
(minItems: 1) rather than required, matching the schema and the v30
backward-compatibility fix (Sashiko AI review).
Changes in v30:
- Add minItems: 1 to reg so existing AST2600 DTs with a single reg
region continue to validate (Sashiko AI review)
- Retain bus-frequency as a deprecated property to avoid breaking
existing AST2600 DTs under unevaluatedProperties: false
(Sashiko AI review)
Changes in v26:
- commit message: include details of changes from original binding
- fix example property ordering to follow DTS coding style
- use consistent "AST2600" naming
---
.../bindings/i2c/aspeed,ast2600-i2c.yaml | 73 ++++++++++++++++++++++
.../devicetree/bindings/i2c/aspeed,i2c.yaml | 3 +-
MAINTAINERS | 1 +
3 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml b/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
new file mode 100644
index 000000000000..abc614315dff
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/aspeed,ast2600-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED I2C on the AST2600 SoCs
+
+maintainers:
+ - Ryan Chen <ryan_chen@aspeedtech.com>
+
+allOf:
+ - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+ compatible:
+ enum:
+ - aspeed,ast2600-i2c-bus
+
+ reg:
+ minItems: 1
+ items:
+ - description: controller registers
+ - description: controller buffer space
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-frequency:
+ description: Desired operating frequency of the I2C bus in Hz.
+ minimum: 500
+ maximum: 4000000
+ default: 100000
+
+ bus-frequency:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ deprecated: true
+ description:
+ Legacy name for clock-frequency. Existing AST2600 device trees
+ used this before the binding was split out. New device trees
+ should use the standard clock-frequency property instead.
+ minimum: 500
+ maximum: 4000000
+
+ resets:
+ maxItems: 1
+
+required:
+ - reg
+ - compatible
+ - clocks
+ - resets
+ - interrupts
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/aspeed-clock.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ i2c@80 {
+ compatible = "aspeed,ast2600-i2c-bus";
+ reg = <0x80 0x80>, <0xc00 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&syscon ASPEED_CLK_APB>;
+ resets = <&syscon ASPEED_RESET_I2C>;
+ clock-frequency = <100000>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ };
diff --git a/Documentation/devicetree/bindings/i2c/aspeed,i2c.yaml b/Documentation/devicetree/bindings/i2c/aspeed,i2c.yaml
index 5b9bd2feda3b..d4e4f412feba 100644
--- a/Documentation/devicetree/bindings/i2c/aspeed,i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/aspeed,i2c.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/i2c/aspeed,i2c.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: ASPEED I2C on the AST24XX, AST25XX, and AST26XX SoCs
+title: ASPEED I2C on the AST24XX, AST25XX SoCs
maintainers:
- Rayn Chen <rayn_chen@aspeedtech.com>
@@ -17,7 +17,6 @@ properties:
enum:
- aspeed,ast2400-i2c-bus
- aspeed,ast2500-i2c-bus
- - aspeed,ast2600-i2c-bus
reg:
minItems: 1
diff --git a/MAINTAINERS b/MAINTAINERS
index 882214b0e7db..f9c929e86e64 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2596,6 +2596,7 @@ R: Joel Stanley <joel@jms.id.au>
L: linux-i2c@vger.kernel.org
L: openbmc@lists.ozlabs.org (moderated for non-subscribers)
S: Maintained
+F: Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
F: Documentation/devicetree/bindings/i2c/aspeed,i2c.yaml
F: Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2400-i2c-ic.yaml
F: drivers/i2c/busses/i2c-aspeed.c
--
2.34.1
^ 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