Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 1/6] dt-bindings: arm: zte: Add D-Link DWR932M board based on zx297520v3 SoC
From: Stefan Dösinger @ 2026-04-26 11:54 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
	Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
	Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
	linux-serial, Stefan Dösinger
In-Reply-To: <20260426-send-v6-0-d49efa72bb09@gmail.com>

This adds a new binding file for ZTE, containing their zx297520v3 SoC
and one board (D-Link DWR-932M) based on it.

Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>

---

Changelog:

v6:
Removed extra boards, I'll add them when submitting their individual
DTS files. Rephrase the subject to add "zte" and remove the redundant
use of "binding".

Moved the devicetree bindings patch ahead of the implementation patches.

Moved the MAINTAINERS section from "ZX29" to "ARM/ZTE".
---
 Documentation/devicetree/bindings/arm/zte.yaml | 26 ++++++++++++++++++++++++++
 MAINTAINERS                                    |  4 ++++
 2 files changed, 30 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/zte.yaml b/Documentation/devicetree/bindings/arm/zte.yaml
new file mode 100644
index 000000000000..f028d2cec7ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/zte.yaml
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/zte.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ZTE zx platforms
+
+maintainers:
+  - Stefan Dösinger <stefandoesinger@gmail.com>
+
+description: |
+  ARM platforms using SoCs designed by ZTE. Currently this supports devices
+  based on the zx297520v3 SoC which is found in LTE routers.
+
+properties:
+  $nodename:
+    const: "/"
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - dlink,dwr932m
+          - const: zte,zx297520v3
+
+additionalProperties: true
diff --git a/MAINTAINERS b/MAINTAINERS
index d1cc0e12fe1f..b768b9da37a4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3772,6 +3772,10 @@ F:	drivers/video/fbdev/vt8500lcdfb.*
 F:	drivers/video/fbdev/wm8505fb*
 F:	drivers/video/fbdev/wmt_ge_rops.*
 
+ARM/ZTE ZX29 SOC SUPPORT
+M:	Stefan Dösinger <stefandoesinger@gmail.com>
+F:	Documentation/devicetree/bindings/arm/zte.yaml
+
 ARM/ZYNQ ARCHITECTURE
 M:	Michal Simek <michal.simek@amd.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)

-- 
2.53.0



^ permalink raw reply related

* [PATCH v6 0/6] Add support for ZTE zx297520v3
From: Stefan Dösinger @ 2026-04-26 11:54 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
	Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
	Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
	linux-serial, Stefan Dösinger

Hi,

This is a follow-up on my RFC patches from January [0] for ZTE's 
zx297520v3 chipset. This chipset is popular in cheap LTE-to-wifi routers
sold in developing countries. My goal is to run OpenWRT on them. I made 
more progress in more work on this SoC and it is time to get serious 
about code review and upstreaming.

Since my version in January I managed to get more hardware running: SPI, 
I2C, PMIC with real time clock and voltage regulators, Watchdog. LTE is 
not working yet, but I am able to start the coprocessor that handles it 
and talk to it via mailbox + shared memory. Wifi is working on a few 
more devices. Since WiFi, USB and Ethernet are working, the devices can 
have actual use with OpenWRT even without LTE.

Another hacker created a free software program to talk to the USB loader 
[1] and boot U-Boot and Linux without modifying the on disk files. At 
the moment it needs a proprietary blob, so my documentation is 
emphasising booting with the on-device U-Boot.

This patchset here is mostly unmodified from the version I sent in 
January. It is the bare minimum to get an interactive shell working on 
the UART. Future patches can be found on my git repository [2] for those 
curious to peek ahead. The first 30 patches are in reasonable shape, but 
the further you go the more cleanup is necessary. I expect all of the 
patches go require a few rounds of feedback though.

My plan for upstreaming is largly this:

1) This bare minimum boot patchset
2) Add clock and pinctrl drivers
3) Add standard hardware to the device tree
4) Add zx29 specific drivers one by one: Watchdog, spi, i2c, DMA, PMIC, 
battery
5) SDIO backend for rtl8xxxu
6) rproc, mailbox and rpmsg

I am willing to maintain support for the SoC within reason. My patches 
add myself as maintainer. This is a hobby project for me though, keep 
that in mind if you want to ship a commercial product with these SoCs 
and upstreaming Linux.

Cheers,
Stefan

0: https://lists.infradead.org/pipermail/linux-arm-kernel/2026-January/1099306.html
1: https://github.com/zx297520v3-mainline/zx297520v3-loader
2: https://gitlab.com/stefandoesinger/zx297520-kernel/

Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
---
Patch changelog:

Changes in v6:
Squashed DT commits into one
Removed for-now unused board DT bindings
Add "zte" to DT patch subject
Regenerate the defconfig with make savedefconfig
- Link to v5: https://lore.kernel.org/r/20260421-send-v5-0-ace038e63515@gmail.com

v5:
Spelling fixes
Renamed dlink-dwr-932m.dts to zx297520v3-dlink-dwr932m.dts
DT binding indentation fixes
Use a manufacturer 0x8b for the UART, fix patch prefix
Declare all UARTs, remove uart aliases for now
Consistent license declarations. I made every new file except the DT 
binding GPL-2.0-only but I don't particularly mind GPL-2.0-or-later 
either.
- Link to v4: https://lore.kernel.org/r/20260416-send-v4-0-e19d02b944ec@gmail.com

v4: rename zx29.yaml to zte.yaml and add board enums
v3: Remove [RFC] tag, add defconfig
v2: checkpatch.pl fixes

---
Stefan Dösinger (6):
      dt-bindings: arm: zte: Add D-Link DWR932M board based on zx297520v3 SoC
      ARM: zte: Add zx297520v3 platform support
      ARM: zte: Add support for zx29 low level debug
      amba/serial: amba-pl011: Bring back zx29 UART support
      ARM: dts: zte: Add D-Link DWR-932M support
      ARM: zte: defconfig: Add a zx29 defconfig file

 Documentation/arch/arm/zte/zx297520v3.rst          | 158 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/zte.yaml     |  26 ++++
 MAINTAINERS                                        |   7 +
 arch/arm/Kconfig                                   |   2 +
 arch/arm/Kconfig.debug                             |  12 ++
 arch/arm/Makefile                                  |   1 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/zte/Makefile                     |   3 +
 arch/arm/boot/dts/zte/zx297520v3-dlink-dwr932m.dts |  22 +++
 arch/arm/boot/dts/zte/zx297520v3.dtsi              | 103 ++++++++++++++
 arch/arm/configs/zx29_defconfig                    |  54 +++++++
 arch/arm/include/debug/pl01x.S                     |   7 +
 arch/arm/mach-zte/Kconfig                          |  26 ++++
 arch/arm/mach-zte/Makefile                         |   2 +
 arch/arm/mach-zte/zx297520v3.c                     |  19 +++
 drivers/tty/serial/amba-pl011.c                    |  42 ++++++
 16 files changed, 485 insertions(+)
---
base-commit: 028ef9c96e96197026887c0f092424679298aae8
change-id: 20260416-send-5c08e095e5c9

Best regards,
-- 
Stefan Dösinger <stefandoesinger@gmail.com>



^ permalink raw reply

* Re: [PATCH v5 4/6] counter: Add rockchip-pwm-capture driver
From: Damon Ding @ 2026-04-26 10:55 UTC (permalink / raw)
  To: Nicolas Frattaroli, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Lee Jones,
	William Breathitt Gray
  Cc: kernel, Jonas Karlman, Alexey Charkov, linux-rockchip, linux-pwm,
	devicetree, linux-arm-kernel, linux-kernel, linux-iio
In-Reply-To: <20260420-rk3576-pwm-v5-4-ae7cfbbe5427@collabora.com>

Hi Nicolas,

On 4/20/2026 9:52 PM, Nicolas Frattaroli wrote:
> Among many other things, Rockchip's new PWMv4 IP in the RK3576 supports
> PWM capture functionality.
> 
> Add a basic driver for this that works to expose HPC/LPC counts and
> state change events to userspace through the counter framework. It's
> quite basic, but works well enough to demonstrate the device function
> exclusion stuff that mfpwm does, in order to eventually support all the
> functions of this device in drivers within their appropriate subsystems,
> without them interfering with each other.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> ---
>   MAINTAINERS                            |   1 +
>   drivers/counter/Kconfig                |  11 ++
>   drivers/counter/Makefile               |   1 +
>   drivers/counter/rockchip-pwm-capture.c | 307 +++++++++++++++++++++++++++++++++
>   4 files changed, 320 insertions(+)
> 

For functional validation, I connected PWM0/PWM1 (continuous output)
to PWM2 (capture input) pairwise.

I enabled the counter via:
/sys/bus/counter/devices/counter0/count0/enable

Then I verified the functionality by reading the count values from:
/sys/bus/counter/devices/counter0/count0/count
/sys/bus/counter/devices/counter0/count1/count

Tested-by: Damon Ding <damon.ding@rock-chips.com>

BTW: Is there any user-space test tool similar to libpwm for the
counter subsystem?

......
> diff --git a/drivers/counter/rockchip-pwm-capture.c b/drivers/counter/rockchip-pwm-capture.c
> new file mode 100644
> index 000000000000..09a92f2bc409
> --- /dev/null
> +++ b/drivers/counter/rockchip-pwm-capture.c
> @@ -0,0 +1,307 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2025 Collabora Ltd.
> + *
> + * A counter driver for the Pulse-Width-Modulation (PWM) hardware found on
> + * Rockchip SoCs such as the RK3576, internally referred to as "PWM v4". It
> + * allows for measuring the high cycles and low cycles of a PWM signal through
> + * the generic counter framework, while guaranteeing exclusive use over the
> + * MFPWM device while the counter is enabled.
> + *
> + * Authors:
> + *     Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> + */
> +
> +#include <linux/cleanup.h>
> +#include <linux/counter.h>
> +#include <linux/devm-helpers.h>
> +#include <linux/interrupt.h>
> +#include <linux/mfd/rockchip-mfpwm.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +
> +#define RKPWMC_INT_MASK			(PWMV4_INT_LPC | PWMV4_INT_HPC)
> +
> +struct rockchip_pwm_capture {
> +	struct rockchip_mfpwm_func *pwmf;
> +	struct counter_device *counter;
> +};
> +
> +static struct counter_signal rkpwmc_signals[] = {
> +	{
> +		.id = 0,
> +		.name = "PWM Clock"
> +	},
> +};
> +
> +static const enum counter_synapse_action rkpwmc_hpc_lpc_actions[] = {
> +	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
> +	COUNTER_SYNAPSE_ACTION_NONE,
> +};

For the capture function, it uses the PWM's reference clock (dclk) as 
the time base to measure how many reference cycles the high and low 
levels of the input waveform last respectively.

I find it a bit strange to set COUNTER_SYNAPSE_ACTION_BOTH_EDGES for 
counting. If we treat the input waveform as a sequence of square waves 
sampled by dclk cycles, it feels like we should count on a single edge 
(rising edge only) rather than both edges.

> +
> +static struct counter_synapse rkpwmc_pwm_synapses[] = {
> +	{
> +		.actions_list = rkpwmc_hpc_lpc_actions,
> +		.num_actions = ARRAY_SIZE(rkpwmc_hpc_lpc_actions),
> +		.signal = &rkpwmc_signals[0]
> +	},
> +};
> +

Best regards,
Damon



^ permalink raw reply

* Re: [PATCH] iio: adc: meson-saradc: fix calibration buffer leak on error
From: Jonathan Cameron @ 2026-04-26 10:41 UTC (permalink / raw)
  To: Rosen Penev
  Cc: Felix Gu, David Lechner, Nuno Sá, Andy Shevchenko,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
	linux-iio, linux-arm-kernel, linux-amlogic, linux-kernel
In-Reply-To: <CAKxU2N9_Nmk_apUZLSCGssXpwxYOz9k99ggRcUM3EPGUzaVi7w@mail.gmail.com>

On Sat, 25 Apr 2026 12:20:55 -0700
Rosen Penev <rosenp@gmail.com> wrote:

> On Sat, Apr 25, 2026 at 9:07 AM Felix Gu <ustc.gu@gmail.com> wrote:
> >
> > meson_sar_adc_temp_sensor_init() allocates a buffer with
> > nvmem_cell_read(), but the old code leaked it if
> > syscon_regmap_lookup_by_phandle() failed.
> >
> > Switch buf to __free(kfree) so all return paths release it.
> >
> > Fixes: d6f2eac64403 ("iio: adc: meson: no devm for nvmem_cell_get")
> > Signed-off-by: Felix Gu <ustc.gu@gmail.com>
> > ---
> >  drivers/iio/adc/meson_saradc.c | 10 +++-------
> >  1 file changed, 3 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c
> > index 23991a3612bd..9708ddcc4919 100644
> > --- a/drivers/iio/adc/meson_saradc.c
> > +++ b/drivers/iio/adc/meson_saradc.c
> > @@ -786,7 +786,7 @@ static int meson_sar_adc_clk_init(struct iio_dev *indio_dev,
> >  static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
> >  {
> >         struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
> > -       u8 *buf, trimming_bits, trimming_mask, upper_adc_val;
> > +       u8 trimming_bits, trimming_mask, upper_adc_val;
> >         struct device *dev = indio_dev->dev.parent;
> >         struct nvmem_cell *temperature_calib;
> >         size_t read_len;
> > @@ -807,14 +807,12 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
> >         }
> >
> >         read_len = MESON_SAR_ADC_EFUSE_BYTES;
> > -       buf = nvmem_cell_read(temperature_calib, &read_len);
> > +       u8 *buf __free(kfree) = nvmem_cell_read(temperature_calib, &read_len);
> >         nvmem_cell_put(temperature_calib);
> >         if (IS_ERR(buf))
> >                 return dev_err_probe(dev, PTR_ERR(buf), "failed to read temperature_calib cell\n");
> > -       if (read_len != MESON_SAR_ADC_EFUSE_BYTES) {
> > -               kfree(buf);  
> I don't like this. Just add the missing kfree.

That is the minimal fix, so we should probably do that first
even if we then circle back to consider if __free() magic is worth using here.

J
> > +       if (read_len != MESON_SAR_ADC_EFUSE_BYTES)
> >                 return dev_err_probe(dev, -EINVAL, "invalid read size of temperature_calib cell\n");
> > -       }
> >
> >         priv->tsc_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "amlogic,hhi-sysctrl");
> >         if (IS_ERR(priv->tsc_regmap))
> > @@ -835,8 +833,6 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
> >         priv->temperature_sensor_adc_val |= upper_adc_val << BITS_PER_BYTE;
> >         priv->temperature_sensor_adc_val >>= trimming_bits;
> >
> > -       kfree(buf);
> > -
> >         return 0;
> >  }
> >
> >
> > ---
> > base-commit: 7080e32d3f09d8688c4a87d81bdcc71f7f606b16
> > change-id: 20260425-meson_saradc-54abc52d9b31
> >
> > Best regards,
> > --
> > Felix Gu <ustc.gu@gmail.com>
> >  



^ permalink raw reply

* Re: [PATCH] iio: adc: meson-saradc: fix calibration buffer leak on error
From: Jonathan Cameron @ 2026-04-26 10:40 UTC (permalink / raw)
  To: Felix Gu
  Cc: David Lechner, Nuno Sá, Andy Shevchenko, Neil Armstrong,
	Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Rosen Penev,
	linux-iio, linux-arm-kernel, linux-amlogic, linux-kernel
In-Reply-To: <CAN4SLj0hp4N_WXPxxQcLjY+espY96LfizsNEqJ3L2UF4_GoCHg@mail.gmail.com>

On Sun, 26 Apr 2026 11:54:47 +0800
Felix Gu <ustc.gu@gmail.com> wrote:

> On Sun, Apr 26, 2026 at 7:16 AM David Lechner <dlechner@baylibre.com> wrote:
> > I just updated iio/testing today and I see return without kfree().
> >
> >         priv->tsc_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "amlogic,hhi-sysctrl");
> >         if (IS_ERR(priv->tsc_regmap))
> >                 return dev_err_probe(dev, PTR_ERR(priv->tsc_regmap),
> >                                      "failed to get amlogic,hhi-sysctrl regmap\n");  
> > >> Should `#include <linux/cleanup.h>` though rather that relying on it being
> > >> included through another header.
> > >>
> > >> With that fixed...
> > >>
> > >> Reviewed-by: David Lechner <dlechner@baylibre.com>
> > >>  
> > >  
> >  
> Hi Jonathan,
> This code was merged into linux/master yesterday, perhaps you haven't
> updated the code base.
Ah.  My bad.  I tend to be lazy and use elixir to check stuff like this
and had completely forgotten I merged the patch that broke this :(

J
> 
> Best regards,
> Felix
> 



^ permalink raw reply

* [PATCH v2 4/4] arm64: dts: allwinner: h616: add hstimer node
From: Michal Piekos @ 2026-04-26 10:15 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
	Maxime Ripard
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-sunxi,
	Michal Piekos
In-Reply-To: <20260426-h616-t113s-hstimer-v2-0-e65e9dc0c9da@mmpsystems.pl>

Describe high speed timer block on Allwinner H616.

Tested on Orange Pi Zero 3:
- hstimer is registered as clocksource
- switching clocksource at runtime works
- after rating increase hstimer operates as a broadcast clockevent device

Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
---
 arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index bf054869e78b..1356e5df2562 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -237,6 +237,16 @@ timer0: timer@3009000 {
 			clocks = <&osc24M>;
 		};
 
+		hstimer@3005000 {
+			compatible = "allwinner,sun50i-h616-hstimer",
+				     "allwinner,sun20i-d1-hstimer";
+			reg = <0x03005000 0x1000>;
+			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_HSTIMER>;
+			resets = <&ccu RST_BUS_HSTIMER>;
+		};
+
 		watchdog: watchdog@30090a0 {
 			compatible = "allwinner,sun50i-h616-wdt",
 				     "allwinner,sun6i-a31-wdt";

-- 
2.43.0



^ permalink raw reply related

* [PATCH v2 2/4] clocksource/drivers/sun5i: add D1 hstimer support
From: Michal Piekos @ 2026-04-26 10:15 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
	Maxime Ripard
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-sunxi,
	Michal Piekos
In-Reply-To: <20260426-h616-t113s-hstimer-v2-0-e65e9dc0c9da@mmpsystems.pl>

D1 high speed timer differs from existing timer-sun5i by register base
offset.

Add sunxi quirks to handle D1 specific offset.
Add D1 compatible string to OF match table.

Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
---
 drivers/clocksource/timer-sun5i.c | 88 ++++++++++++++++++++++++++++++---------
 1 file changed, 69 insertions(+), 19 deletions(-)

diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c
index f827d3f98f60..2b17904debfa 100644
--- a/drivers/clocksource/timer-sun5i.c
+++ b/drivers/clocksource/timer-sun5i.c
@@ -18,21 +18,30 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 
-#define TIMER_IRQ_EN_REG		0x00
+#define TIMER_IRQ_EN_REG			0x00
 #define TIMER_IRQ_EN(val)			BIT(val)
-#define TIMER_IRQ_ST_REG		0x04
-#define TIMER_CTL_REG(val)		(0x20 * (val) + 0x10)
+#define TIMER_IRQ_ST_REG			0x04
+#define TIMER_CTL_REG(val, offset)		(0x20 * (val) + 0x10 + (offset))
 #define TIMER_CTL_ENABLE			BIT(0)
 #define TIMER_CTL_RELOAD			BIT(1)
 #define TIMER_CTL_CLK_PRES(val)			(((val) & 0x7) << 4)
 #define TIMER_CTL_ONESHOT			BIT(7)
-#define TIMER_INTVAL_LO_REG(val)	(0x20 * (val) + 0x14)
-#define TIMER_INTVAL_HI_REG(val)	(0x20 * (val) + 0x18)
-#define TIMER_CNTVAL_LO_REG(val)	(0x20 * (val) + 0x1c)
-#define TIMER_CNTVAL_HI_REG(val)	(0x20 * (val) + 0x20)
+#define TIMER_INTVAL_LO_REG(val, offset)	(0x20 * (val) + 0x14 + (offset))
+#define TIMER_INTVAL_HI_REG(val, offset)	(0x20 * (val) + 0x18 + (offset))
+#define TIMER_CNTVAL_LO_REG(val, offset)	(0x20 * (val) + 0x1c + (offset))
+#define TIMER_CNTVAL_HI_REG(val, offset)	(0x20 * (val) + 0x20 + (offset))
 
 #define TIMER_SYNC_TICKS	3
 
+/**
+ * struct sunxi_timer_quirks - Differences between SoC variants.
+ *
+ * @from_ctl_base_offset: offset applied from ctl register onwards
+ */
+struct sunxi_timer_quirks {
+	u32 from_ctl_base_offset;
+};
+
 struct sun5i_timer {
 	void __iomem		*base;
 	struct clk		*clk;
@@ -40,6 +49,7 @@ struct sun5i_timer {
 	u32			ticks_per_jiffy;
 	struct clocksource	clksrc;
 	struct clock_event_device	clkevt;
+	const struct sunxi_timer_quirks *quirks;
 };
 
 #define nb_to_sun5i_timer(x) \
@@ -57,28 +67,36 @@ struct sun5i_timer {
  */
 static void sun5i_clkevt_sync(struct sun5i_timer *ce)
 {
-	u32 old = readl(ce->base + TIMER_CNTVAL_LO_REG(1));
+	u32 offset = ce->quirks->from_ctl_base_offset;
+	u32 old = readl(ce->base + TIMER_CNTVAL_LO_REG(1, offset));
 
-	while ((old - readl(ce->base + TIMER_CNTVAL_LO_REG(1))) < TIMER_SYNC_TICKS)
+	while ((old - readl(ce->base + TIMER_CNTVAL_LO_REG(1, offset))) <
+	       TIMER_SYNC_TICKS)
 		cpu_relax();
 }
 
 static void sun5i_clkevt_time_stop(struct sun5i_timer *ce, u8 timer)
 {
-	u32 val = readl(ce->base + TIMER_CTL_REG(timer));
-	writel(val & ~TIMER_CTL_ENABLE, ce->base + TIMER_CTL_REG(timer));
+	u32 offset = ce->quirks->from_ctl_base_offset;
+	u32 val = readl(ce->base + TIMER_CTL_REG(timer, offset));
+
+	writel(val & ~TIMER_CTL_ENABLE,
+	       ce->base + TIMER_CTL_REG(timer, offset));
 
 	sun5i_clkevt_sync(ce);
 }
 
 static void sun5i_clkevt_time_setup(struct sun5i_timer *ce, u8 timer, u32 delay)
 {
-	writel(delay, ce->base + TIMER_INTVAL_LO_REG(timer));
+	u32 offset = ce->quirks->from_ctl_base_offset;
+
+	writel(delay, ce->base + TIMER_INTVAL_LO_REG(timer, offset));
 }
 
 static void sun5i_clkevt_time_start(struct sun5i_timer *ce, u8 timer, bool periodic)
 {
-	u32 val = readl(ce->base + TIMER_CTL_REG(timer));
+	u32 offset = ce->quirks->from_ctl_base_offset;
+	u32 val = readl(ce->base + TIMER_CTL_REG(timer, offset));
 
 	if (periodic)
 		val &= ~TIMER_CTL_ONESHOT;
@@ -86,7 +104,7 @@ static void sun5i_clkevt_time_start(struct sun5i_timer *ce, u8 timer, bool perio
 		val |= TIMER_CTL_ONESHOT;
 
 	writel(val | TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
-	       ce->base + TIMER_CTL_REG(timer));
+	       ce->base + TIMER_CTL_REG(timer, offset));
 }
 
 static int sun5i_clkevt_shutdown(struct clock_event_device *clkevt)
@@ -141,8 +159,9 @@ static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
 static u64 sun5i_clksrc_read(struct clocksource *clksrc)
 {
 	struct sun5i_timer *cs = clksrc_to_sun5i_timer(clksrc);
+	u32 offset = cs->quirks->from_ctl_base_offset;
 
-	return ~readl(cs->base + TIMER_CNTVAL_LO_REG(1));
+	return ~readl(cs->base + TIMER_CNTVAL_LO_REG(1, offset));
 }
 
 static int sun5i_rate_cb(struct notifier_block *nb,
@@ -173,12 +192,13 @@ static int sun5i_setup_clocksource(struct platform_device *pdev,
 				   unsigned long rate)
 {
 	struct sun5i_timer *cs = platform_get_drvdata(pdev);
+	u32 offset = cs->quirks->from_ctl_base_offset;
 	void __iomem *base = cs->base;
 	int ret;
 
-	writel(~0, base + TIMER_INTVAL_LO_REG(1));
+	writel(~0, base + TIMER_INTVAL_LO_REG(1, offset));
 	writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
-	       base + TIMER_CTL_REG(1));
+	       base + TIMER_CTL_REG(1, offset));
 
 	cs->clksrc.name = pdev->dev.of_node->name;
 	cs->clksrc.rating = 340;
@@ -237,7 +257,9 @@ static int sun5i_setup_clockevent(struct platform_device *pdev,
 
 static int sun5i_timer_probe(struct platform_device *pdev)
 {
+	const struct sunxi_timer_quirks *quirks;
 	struct device *dev = &pdev->dev;
+	struct device_node *node = dev_of_node(&pdev->dev);
 	struct sun5i_timer *st;
 	struct reset_control *rstc;
 	void __iomem *timer_base;
@@ -251,6 +273,9 @@ static int sun5i_timer_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, st);
 
+	if (!node)
+		return -EINVAL;
+
 	timer_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(timer_base)) {
 		dev_err(dev, "Can't map registers\n");
@@ -273,11 +298,18 @@ static int sun5i_timer_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	quirks = of_device_get_match_data(&pdev->dev);
+	if (!quirks) {
+		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
+		return -ENODEV;
+	}
+
 	st->base = timer_base;
 	st->ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
 	st->clk = clk;
 	st->clk_rate_cb.notifier_call = sun5i_rate_cb;
 	st->clk_rate_cb.next = NULL;
+	st->quirks = quirks;
 
 	ret = devm_clk_notifier_register(dev, clk, &st->clk_rate_cb);
 	if (ret) {
@@ -311,9 +343,27 @@ static void sun5i_timer_remove(struct platform_device *pdev)
 	clocksource_unregister(&st->clksrc);
 }
 
+static const struct sunxi_timer_quirks sun5i_sun7i_hstimer_quirks = {
+	.from_ctl_base_offset = 0x0,
+};
+
+static const struct sunxi_timer_quirks sun20i_d1_hstimer_quirks = {
+	.from_ctl_base_offset = 0x10,
+};
+
 static const struct of_device_id sun5i_timer_of_match[] = {
-	{ .compatible = "allwinner,sun5i-a13-hstimer" },
-	{ .compatible = "allwinner,sun7i-a20-hstimer" },
+	{
+		.compatible = "allwinner,sun5i-a13-hstimer",
+		.data = &sun5i_sun7i_hstimer_quirks,
+	},
+	{
+		.compatible = "allwinner,sun7i-a20-hstimer",
+		.data = &sun5i_sun7i_hstimer_quirks,
+	},
+	{
+		.compatible = "allwinner,sun20i-d1-hstimer",
+		.data = &sun20i_d1_hstimer_quirks,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, sun5i_timer_of_match);

-- 
2.43.0



^ permalink raw reply related

* [PATCH v2 3/4] arm: dts: allwinner: t113s: add hstimer node
From: Michal Piekos @ 2026-04-26 10:15 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
	Maxime Ripard
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-sunxi,
	Michal Piekos
In-Reply-To: <20260426-h616-t113s-hstimer-v2-0-e65e9dc0c9da@mmpsystems.pl>

Describe high speed timer block on Allwinner T113-S3.

Tested on LCPI-PC-T113/F113:
- hstimer is registered as clocksource
- switching clocksource at runtime works
- after rating increase hstimer operates as a broadcast clockevent device

Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
---
 arch/arm/boot/dts/allwinner/sun8i-t113s.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/allwinner/sun8i-t113s.dtsi b/arch/arm/boot/dts/allwinner/sun8i-t113s.dtsi
index 424f4a2487e2..40e76cfc8a1d 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-t113s.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun8i-t113s.dtsi
@@ -34,6 +34,17 @@ cpu1: cpu@1 {
 		};
 	};
 
+	soc {
+		hstimer@3008000 {
+			compatible = "allwinner,sun20i-d1-hstimer";
+			reg = <0x03008000 0x1000>;
+			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_HSTIMER>;
+			resets = <&ccu RST_BUS_HSTIMER>;
+		};
+	};
+
 	gic: interrupt-controller@1c81000 {
 		compatible = "arm,gic-400";
 		reg = <0x03021000 0x1000>,

-- 
2.43.0



^ permalink raw reply related

* [PATCH v2 0/4] Add hstimer support for H616 and T113-S3
From: Michal Piekos @ 2026-04-26 10:15 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
	Maxime Ripard
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-sunxi,
	Michal Piekos

Add support for Allwinner D1 high speed timer in sun5i hstimer driver
and describe corresponding nodes in dts for H616 and T113-S3 SoC's.

D1 and H616 uses same model as existing driver except register shift
compared to older variants. 

Added register layout abstraction in the driver, extended the binding
with new compatibles and wired up dts nodes for T113-S3 and H616 which
uses D1 as fallback compatible.

Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
---
Changes in v2:
- Change driver handling of different offsets to using quirks
- Change from t113s to d1 as the fallback compatible string
- Fix conditional compatible matching
- Link to v1: https://lore.kernel.org/r/20260419-h616-t113s-hstimer-v1-0-1af74ebef7c5@mmpsystems.pl

---
Michal Piekos (4):
      dt-bindings: timer: allwinner,sun5i-a13-hstimer: add H616 and D1
      clocksource/drivers/sun5i: add D1 hstimer support
      arm: dts: allwinner: t113s: add hstimer node
      arm64: dts: allwinner: h616: add hstimer node

 .../timer/allwinner,sun5i-a13-hstimer.yaml         |  9 ++-
 arch/arm/boot/dts/allwinner/sun8i-t113s.dtsi       | 11 +++
 arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi     | 10 +++
 drivers/clocksource/timer-sun5i.c                  | 88 +++++++++++++++++-----
 4 files changed, 98 insertions(+), 20 deletions(-)
---
base-commit: 897d54018cc9aa97fd1529ca08a53b429d05a566
change-id: 20260413-h616-t113s-hstimer-62939948f91c

Best regards,
-- 
Michal Piekos <michal.piekos@mmpsystems.pl>



^ permalink raw reply

* [PATCH v2 1/4] dt-bindings: timer: allwinner,sun5i-a13-hstimer: add H616 and D1
From: Michal Piekos @ 2026-04-26 10:15 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
	Maxime Ripard
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-sunxi,
	Michal Piekos
In-Reply-To: <20260426-h616-t113s-hstimer-v2-0-e65e9dc0c9da@mmpsystems.pl>

D1 is similar to existing sun5i, but with different register offsets.
H616 uses same offsets as D1.

Add allwinner,sun20i-d1-hstimer
Add allwinner,sun50i-h616-hstimer with fallback to
allwinner,sun20i-d1-hstimer
Extend schema condition for interrupts to cover D1 compatible variant.

Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
---
 .../devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml   | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml
index f1853daec2f9..3e2725c56995 100644
--- a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml
+++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml
@@ -15,9 +15,13 @@ properties:
     oneOf:
       - const: allwinner,sun5i-a13-hstimer
       - const: allwinner,sun7i-a20-hstimer
+      - const: allwinner,sun20i-d1-hstimer
       - items:
           - const: allwinner,sun6i-a31-hstimer
           - const: allwinner,sun7i-a20-hstimer
+      - items:
+          - const: allwinner,sun50i-h616-hstimer
+          - const: allwinner,sun20i-d1-hstimer
 
   reg:
     maxItems: 1
@@ -45,7 +49,10 @@ required:
 if:
   properties:
     compatible:
-      const: allwinner,sun5i-a13-hstimer
+      anyOf:
+        - const: allwinner,sun5i-a13-hstimer
+        - contains:
+            const: allwinner,sun20i-d1-hstimer
 
 then:
   properties:

-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH v5 3/6] pwm: Add rockchip PWMv4 driver
From: Damon Ding @ 2026-04-26 10:09 UTC (permalink / raw)
  To: Nicolas Frattaroli, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Lee Jones,
	William Breathitt Gray
  Cc: kernel, Jonas Karlman, Alexey Charkov, linux-rockchip, linux-pwm,
	devicetree, linux-arm-kernel, linux-kernel, linux-iio
In-Reply-To: <20260420-rk3576-pwm-v5-3-ae7cfbbe5427@collabora.com>

Hi Nicolas,

On 4/20/2026 9:52 PM, Nicolas Frattaroli wrote:
> The Rockchip RK3576 brings with it a new PWM IP, in downstream code
> referred to as "v4". This new IP is different enough from the previous
> Rockchip IP that I felt it necessary to add a new driver for it, instead
> of shoehorning it in the old one.
> 
> Add this new driver, based on the PWM core's waveform APIs. Its platform
> device is registered by the parent mfpwm driver, from which it also
> receives a little platform data struct, so that mfpwm can guarantee that
> all the platform device drivers spread across different subsystems for
> this specific hardware IP do not interfere with each other.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> ---
>   MAINTAINERS                   |   1 +
>   drivers/pwm/Kconfig           |  11 ++
>   drivers/pwm/Makefile          |   1 +
>   drivers/pwm/pwm-rockchip-v4.c | 383 ++++++++++++++++++++++++++++++++++++++++++
>   4 files changed, 396 insertions(+)
> 
......
> diff --git a/drivers/pwm/pwm-rockchip-v4.c b/drivers/pwm/pwm-rockchip-v4.c
> new file mode 100644
> index 000000000000..b7de72c433c5
> --- /dev/null
> +++ b/drivers/pwm/pwm-rockchip-v4.c
> @@ -0,0 +1,383 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2025 Collabora Ltd.
> + *
> + * A Pulse-Width-Modulation (PWM) generator driver for the generators found in
> + * Rockchip SoCs such as the RK3576, internally referred to as "PWM v4". Uses
> + * the MFPWM infrastructure to guarantee exclusive use over the device without
> + * other functions of the device from different drivers interfering with its
> + * operation while it's active.
> + *
> + * Technical Reference Manual: Chapter 31 of the RK3506 TRM Part 1, a SoC which
> + * uses the same PWM hardware and has a publicly available TRM.
> + * https://opensource.rock-chips.com/images/3/36/Rockchip_RK3506_TRM_Part_1_V1.2-20250811.pdf
> + *
> + * Authors:
> + *     Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> + *
> + * Limitations:
> + * - The hardware supports both completing the currently running period
> + *   on disable (by switching to oneshot mode with a single repetition and
> + *   only disable when the complete irq fires), and abrupt disable (freeze).
> + *   Only the latter is implemented in the driver.
> + * - When the output is disabled, the pin will remain driven to whatever state
> + *   it last had.

This limitation exists because after disabling the PWM output via 
registers, the actual shutdown only happens after the current period 
completes.

Therefore, the better approach is to add a delay of one full period
before disabling &rockchip_mfpwm_func.core.

> + * - Adjustments to the duty cycle will only take effect during the next period.
> + * - Adjustments to the period length will only take effect during the next
> + *   period.
> + * - The hardware only supports offsets in [0, period - duty_cycle]
> + */
> +
......
> +
> +	if (wfhw->rate) {
> +		if (!was_enabled) {
> +			dev_dbg(&chip->dev, "Enabling PWM output\n");
> +			ret = clk_enable(pc->pwmf->core);
> +			if (ret)
> +				goto err_mfpwm_release;
> +			ret = clk_set_rate_exclusive(pc->pwmf->core, wfhw->rate);
> +			if (ret) {
> +				clk_disable(pc->pwmf->core);
> +				goto err_mfpwm_release;
> +			}
> +
> +			/*
> +			 * Output should be on now, acquire device to guarantee
> +			 * exclusion with other device functions while it's on.
> +			 *
> +			 * It's highly unlikely that this fails, as mfpwm has
> +			 * already been acquired before, and this is just a
> +			 * usage counter increase. Not worth the added
> +			 * complexity of clearing the PWMV4_REG_ENABLE again,
> +			 * especially considering the CTRL_UPDATE_EN behaviour.
> +			 */
> +			ret = mfpwm_acquire(pc->pwmf);
> +			if (ret) {
> +				clk_rate_exclusive_put(pc->pwmf->core);
> +				clk_disable(pc->pwmf->core);
> +				goto err_mfpwm_release;
> +			}
> +		}
> +	} else if (was_enabled) {
> +		dev_dbg(&chip->dev, "Disabling PWM output\n");

Delay for one full PWM period before disabling the dclk.

Although this may introduce some latency for disable -> re-enable 
operations, it ensures that the state after shutdown aligns with the 
actual polarity configuration.

> +		clk_rate_exclusive_put(pc->pwmf->core);
> +		clk_disable(pc->pwmf->core);
> +		/* Output is off now, extra release to balance extra acquire */
> +		mfpwm_release(pc->pwmf);
> +	}
> +
> +err_mfpwm_release:
> +	mfpwm_release(pc->pwmf);
> +
> +	return ret;
> +}
> +
> 

Best regards,
Damon



^ permalink raw reply

* [PATCH] coresight: cti: Fix DT filter signals silently ignored
From: Yingchao Deng @ 2026-04-26  9:59 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Leo Yan,
	Alexander Shishkin, Mathieu Poirier, Greg Kroah-Hartman
  Cc: coresight, linux-arm-kernel, linux-kernel, quic_yingdeng,
	Jinlong Mao, Tingwei Zhang, Jie Gan, Yingchao Deng

In cti_plat_process_filter_sigs(), after allocating a temporary
cti_trig_grp struct via kzalloc_obj(), the code never assigns tg->nr_sigs
= nr_filter_sigs. Since kzalloc zero-initialises the struct, tg->nr_sigs
remains 0. cti_plat_read_trig_group() guards with:
    if (!tgrp->nr_sigs)
        return 0;

so it returns immediately without reading any signal indices from DT.

Fix by assigning tg->nr_sigs before calling cti_plat_read_trig_group().

Fixes: a5614770ab97 ("coresight: cti: Add device tree support for custom CTI")

Signed-off-by: Yingchao Deng <yingchao.deng@oss.qualcomm.com>
---
 drivers/hwtracing/coresight/coresight-cti-platform.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hwtracing/coresight/coresight-cti-platform.c b/drivers/hwtracing/coresight/coresight-cti-platform.c
index 4eff96f48594..d6d5388705c3 100644
--- a/drivers/hwtracing/coresight/coresight-cti-platform.c
+++ b/drivers/hwtracing/coresight/coresight-cti-platform.c
@@ -329,6 +329,7 @@ static int cti_plat_process_filter_sigs(struct cti_drvdata *drvdata,
 	if (!tg)
 		return -ENOMEM;
 
+	tg->nr_sigs = nr_filter_sigs;
 	err = cti_plat_read_trig_group(tg, fwnode, CTI_DT_FILTER_OUT_SIGS);
 	if (!err)
 		drvdata->config.trig_out_filter |= tg->used_mask;

---
base-commit: 7080e32d3f09d8688c4a87d81bdcc71f7f606b16
change-id: 20260426-nr_sigs-268add9d09ba

Best regards,
-- 
Yingchao Deng <yingchao.deng@oss.qualcomm.com>



^ permalink raw reply related

* Re: [PATCH v8 3/6] drm/bridge: simple: Add the Lontium LT8711UXD DP-to-HDMI bridge
From: Heiko Stuebner @ 2026-04-26  9:54 UTC (permalink / raw)
  To: Dmitry Baryshkov, Laurent Pinchart
  Cc: Dennis Gilmore, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jonas Karlman,
	Jernej Skrabec, Maxime Ripard, Alexey Charkov, devicetree,
	linux-rockchip, linux-arm-kernel, dri-devel, linux-kernel
In-Reply-To: <20260425234845.GC2964234@killaraus.ideasonboard.com>

Am Sonntag, 26. April 2026, 01:48:45 Mitteleuropäische Sommerzeit schrieb Laurent Pinchart:
> On Sun, Apr 26, 2026 at 12:44:59AM +0300, Dmitry Baryshkov wrote:
> > On Sat, Apr 25, 2026 at 01:10:02PM -0500, Dennis Gilmore wrote:
> > > On Sat, Apr 25, 2026 at 9:24 AM Dmitry Baryshkov wrote:
> > > > On Sat, Apr 25, 2026 at 02:28:44PM +0300, Laurent Pinchart wrote:
> > > > > Hi Dennis,
> > > > >
> > > > > Thank you for the patch.
> > > > >
> > > > > On Fri, Apr 24, 2026 at 10:10:08PM -0500, Dennis Gilmore wrote:
> > > > > > The Lontium LT8711UXD is a high performance two lane Type-C/DP1.4
> > > > > > to HDMI2.0 converter, designed to connect a USB Type-C source or
> > > > > > a DP1.4 source to an HDMI2.0 sink.
> > > > >
> > > > > As far as I can tell, the LT8711UXD has an I2C control interface.
> > > > > Shouldn't it be an I2C device ?
> > > >
> > > > From the datasheet:
> > > >
> > > > The device is capable of automatic operation which is
> > > > enabled by an integrated microprocessor that uses an
> > > > embedded SPI flash for firmware storage. System control
> > > > is also available through the use of a dedicated
> > > > configuration I2C slave interface.
> > > >
> > > > My guess was that it can either be an I2C device or it can function as a
> > > > simple platdev with no I2C controls. Please correct me if my
> > > > understanding was wrong.
> > > >
> > > > But now looking at the schematics, it seems to be connected to I2C6.
> > > > Which means that it should be desribed (and bound) as such.
> > > 
> > > Hi Dmitry and Laurent,
> > > 
> > > While the schematic shows that it can use I2C and has been wired up,
> > > it also shows that both MODE_SEL and I2C_ADDR have unpopulated 10k
> > > resistors; as a result, MODE_SEL is connected directly to GND,

looking at the schematics linked in the board patch, I somehow see
both R9 (mode_sel -> vcc3v3_io) but also R17 (mode_sel -> gnd) marked
as 10K.nc ?


> > > putting
> > > the bridge in autonomous mode. I confirmed this by running `i2cdetect
> > > -r -y 6`, with the only device on the bus being the HYM8563 RTC at
> > > 0x51. Without reworking the board, the device is not directly
> > > controllable and just runs autonomously.
> > 
> > I think it would be nice to mention:
> > - In the commit for the bindings, that the device can be running
> >   uncontrolled or it can be attached over I2C, bindings describe the
> >   uncontrolled mode.
> > - In this commit message, the same.
> > - In the commit message for the board DT mention your findings about the
> >   board, mention soldering R9 or R17 (which one?) and R27.
> 
> Additionally, how are we going to handle boards where the device
> operates in I2C mode ? Will we use a different compatible string (maybe
> "lontium,lt8711uxd-i2c") ? If DT maintainers are fine with that, I have
> no objection to this patch.

I would assume it'd be more the dt-maintainers objecting?
I.e. the two different bindings for the same hardware and leaking Linux
implementation-specifics into the binding.

I'm don't have deep insight into the i2c framework, but I guess the i2c
device probe does not need to talk to an i2c device due to resources
needing setup. Does the i2c core need to talk to the device at all?

Because otherwise, you could just do a regular i2c device (the routing
for everything is there afterall), add a lontium,automatic-mode; flag
to the node to denote mode.

And if for whatever reason a variant appears with the lines connected
you can just modifiy the DT via an overlay?


Heiko




^ permalink raw reply

* [PATCH v8 4/4] coresight: cti: expose banked sysfs registers for Qualcomm extended CTI
From: Yingchao Deng @ 2026-04-26  9:44 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Leo Yan,
	Alexander Shishkin
  Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
	quic_yingdeng, Jinlong Mao, Tingwei Zhang, Jie Gan, Yingchao Deng
In-Reply-To: <20260426-extended-cti-v8-0-23b900a4902f@oss.qualcomm.com>

Qualcomm extended CTI implements banked trigger status and integration
registers, where each bank covers 32 triggers. Multiple instances of
these registers are required to expose the full trigger space.

Add static sysfs entries for the banked CTI registers and control their
visibility based on the underlying hardware configuration. Numbered
sysfs nodes are hidden on standard ARM CTIs, preserving the existing ABI.
On Qualcomm CTIs, only banked registers backed by hardware are exposed,
with the number of visible banks derived from nr_trig_max.

This ensures that userspace only sees registers that are actually
implemented, while maintaining compatibility with existing CTI tooling.

Signed-off-by: Yingchao Deng <yingchao.deng@oss.qualcomm.com>
---
 drivers/hwtracing/coresight/coresight-cti-sysfs.c | 58 +++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
index 8b70e7e38ea3..046757e4e9b6 100644
--- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
@@ -512,18 +512,36 @@ static struct attribute *coresight_cti_regs_attrs[] = {
 	&dev_attr_appclear.attr,
 	&dev_attr_apppulse.attr,
 	coresight_cti_reg(triginstatus, CTITRIGINSTATUS),
+	coresight_cti_reg(triginstatus1, CTI_REG_SET_NR_CONST(CTITRIGINSTATUS, 1)),
+	coresight_cti_reg(triginstatus2, CTI_REG_SET_NR_CONST(CTITRIGINSTATUS, 2)),
+	coresight_cti_reg(triginstatus3, CTI_REG_SET_NR_CONST(CTITRIGINSTATUS, 3)),
 	coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS),
+	coresight_cti_reg(trigoutstatus1, CTI_REG_SET_NR_CONST(CTITRIGOUTSTATUS, 1)),
+	coresight_cti_reg(trigoutstatus2, CTI_REG_SET_NR_CONST(CTITRIGOUTSTATUS, 2)),
+	coresight_cti_reg(trigoutstatus3, CTI_REG_SET_NR_CONST(CTITRIGOUTSTATUS, 3)),
 	coresight_cti_reg(chinstatus, CTICHINSTATUS),
 	coresight_cti_reg(choutstatus, CTICHOUTSTATUS),
 #ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
 	coresight_cti_reg_rw(itctrl, CORESIGHT_ITCTRL),
 	coresight_cti_reg(ittrigin, ITTRIGIN),
+	coresight_cti_reg(ittrigin1, CTI_REG_SET_NR_CONST(ITTRIGIN, 1)),
+	coresight_cti_reg(ittrigin2, CTI_REG_SET_NR_CONST(ITTRIGIN, 2)),
+	coresight_cti_reg(ittrigin3, CTI_REG_SET_NR_CONST(ITTRIGIN, 3)),
 	coresight_cti_reg(itchin, ITCHIN),
 	coresight_cti_reg_rw(ittrigout, ITTRIGOUT),
+	coresight_cti_reg_rw(ittrigout1, CTI_REG_SET_NR_CONST(ITTRIGOUT, 1)),
+	coresight_cti_reg_rw(ittrigout2, CTI_REG_SET_NR_CONST(ITTRIGOUT, 2)),
+	coresight_cti_reg_rw(ittrigout3, CTI_REG_SET_NR_CONST(ITTRIGOUT, 3)),
 	coresight_cti_reg_rw(itchout, ITCHOUT),
 	coresight_cti_reg(itchoutack, ITCHOUTACK),
 	coresight_cti_reg(ittrigoutack, ITTRIGOUTACK),
+	coresight_cti_reg(ittrigoutack1, CTI_REG_SET_NR_CONST(ITTRIGOUTACK, 1)),
+	coresight_cti_reg(ittrigoutack2, CTI_REG_SET_NR_CONST(ITTRIGOUTACK, 2)),
+	coresight_cti_reg(ittrigoutack3, CTI_REG_SET_NR_CONST(ITTRIGOUTACK, 3)),
 	coresight_cti_reg_wo(ittriginack, ITTRIGINACK),
+	coresight_cti_reg_wo(ittriginack1, CTI_REG_SET_NR_CONST(ITTRIGINACK, 1)),
+	coresight_cti_reg_wo(ittriginack2, CTI_REG_SET_NR_CONST(ITTRIGINACK, 2)),
+	coresight_cti_reg_wo(ittriginack3, CTI_REG_SET_NR_CONST(ITTRIGINACK, 3)),
 	coresight_cti_reg_wo(itchinack, ITCHINACK),
 #endif
 	NULL,
@@ -534,10 +552,50 @@ static umode_t coresight_cti_regs_is_visible(struct kobject *kobj,
 {
 	struct device *dev = kobj_to_dev(kobj);
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	static const char * const qcom_suffix_registers[] = {
+		"triginstatus",
+		"trigoutstatus",
+#ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
+		"ittrigin",
+		"ittrigout",
+		"ittriginack",
+		"ittrigoutack",
+#endif
+	};
+	int i, nr, max_bank;
+	size_t len;
 
 	if (attr == &dev_attr_asicctl.attr && !drvdata->config.asicctl_impl)
 		return 0;
 
+	/*
+	 * Banked regs are exposed as <qcom_suffix_registers><nr> (nr = 1..3).
+	 * - Hide them on standard CTIs.
+	 * - On QCOM CTIs, hide suffixes beyond the number of banks implied
+	 *   by nr_trig_max (32 triggers per bank).
+	 */
+	for (i = 0; i < ARRAY_SIZE(qcom_suffix_registers); i++) {
+		len = strlen(qcom_suffix_registers[i]);
+
+		if (strncmp(attr->name, qcom_suffix_registers[i], len))
+			continue;
+
+		if (kstrtoint(attr->name + len, 10, &nr))
+			continue;
+
+		if (!drvdata->is_qcom_cti)
+			return 0;
+
+		if (nr < 1 || nr > 3)
+			return 0;
+
+		max_bank = DIV_ROUND_UP(drvdata->config.nr_trig_max, 32) - 1;
+		if (nr > max_bank)
+			return 0;
+
+		break;
+	}
+
 	return attr->mode;
 }
 

-- 
2.43.0



^ permalink raw reply related

* [PATCH v8 3/4] coresight: cti: add Qualcomm extended CTI identification and quirks
From: Yingchao Deng @ 2026-04-26  9:44 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Leo Yan,
	Alexander Shishkin
  Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
	quic_yingdeng, Jinlong Mao, Tingwei Zhang, Jie Gan, Yingchao Deng
In-Reply-To: <20260426-extended-cti-v8-0-23b900a4902f@oss.qualcomm.com>

Qualcomm implements an extended variant of the ARM CoreSight CTI with a
different register layout and vendor-specific behavior. While the
programming model remains largely compatible, the register offsets differ
from the standard ARM CTI and require explicit handling.

Detect Qualcomm CTIs via the DEVARCH register and record this in the CTI
driver data. Introduce a small mapping layer to translate standard CTI
register offsets to Qualcomm-specific offsets, allowing the rest of the
driver to use a common register access path.

Additionally, handle a Qualcomm-specific quirk where the CLAIMSET
register is incorrectly initialized to a non-zero value, which can cause
tools or drivers to assume the component is already claimed. Clear the
register during probe to reflect the actual unclaimed state.

No functional change is intended for standard ARM CTI devices.

Co-developed-by: Jinlong Mao <jinlong.mao@oss.qualcomm.com>
Signed-off-by: Jinlong Mao <jinlong.mao@oss.qualcomm.com>
Signed-off-by: Yingchao Deng <yingchao.deng@oss.qualcomm.com>
---
 drivers/hwtracing/coresight/coresight-cti-core.c | 28 +++++++++-
 drivers/hwtracing/coresight/coresight-cti.h      |  4 +-
 drivers/hwtracing/coresight/qcom-cti.h           | 65 ++++++++++++++++++++++++
 3 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
index c4cbeb64365b..b1c69a3e9b99 100644
--- a/drivers/hwtracing/coresight/coresight-cti-core.c
+++ b/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -21,6 +21,7 @@
 
 #include "coresight-priv.h"
 #include "coresight-cti.h"
+#include "qcom-cti.h"
 
 /*
  * CTI devices can be associated with a PE, or be connected to CoreSight
@@ -47,6 +48,10 @@ static void __iomem *cti_reg_addr(struct cti_drvdata *drvdata, int reg)
 	u32 offset = CTI_REG_CLR_NR(reg);
 	u32 nr = CTI_REG_GET_NR(reg);
 
+	/* convert to qcom specific offset */
+	if (unlikely(drvdata->is_qcom_cti))
+		offset = cti_qcom_reg_off(offset);
+
 	return drvdata->base + offset + sizeof(u32) * nr;
 }
 
@@ -170,6 +175,9 @@ void cti_write_intack(struct device *dev, u32 ackval)
 /* DEVID[19:16] - number of CTM channels */
 #define CTI_DEVID_CTMCHANNELS(devid_val) ((int) BMVAL(devid_val, 16, 19))
 
+/* DEVARCH[31:21] - ARCHITECT */
+#define CTI_DEVARCH_ARCHITECT(devarch_val) ((int)BMVAL(devarch_val, 21, 31))
+
 static int cti_set_default_config(struct device *dev,
 				  struct cti_drvdata *drvdata)
 {
@@ -700,6 +708,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
 	struct coresight_desc cti_desc;
 	struct coresight_platform_data *pdata = NULL;
 	struct resource *res = &adev->res;
+	u32 devarch;
 
 	/* driver data*/
 	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
@@ -724,6 +733,22 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
 
 	raw_spin_lock_init(&drvdata->spinlock);
 
+	devarch = readl_relaxed(drvdata->base + CORESIGHT_DEVARCH);
+	if (CTI_DEVARCH_ARCHITECT(devarch) == ARCHITECT_QCOM) {
+		drvdata->is_qcom_cti = true;
+		/*
+		 * QCOM CTI does not implement Claimtag functionality as
+		 * per CoreSight specification, but its CLAIMSET register
+		 * is incorrectly initialized to 0xF. This can mislead
+		 * tools or drivers into thinking the component is claimed.
+		 *
+		 * Reset CLAIMSET to 0 to reflect that no claims are active.
+		 */
+		CS_UNLOCK(drvdata->base);
+		writel_relaxed(0, drvdata->base + CORESIGHT_CLAIMSET);
+		CS_LOCK(drvdata->base);
+	}
+
 	/* initialise CTI driver config values */
 	ret = cti_set_default_config(dev, drvdata);
 	if (ret)
@@ -780,7 +805,8 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
 
 	/* all done - dec pm refcount */
 	pm_runtime_put(&adev->dev);
-	dev_info(&drvdata->csdev->dev, "CTI initialized\n");
+	dev_info(&drvdata->csdev->dev,
+		 "%sCTI initialized\n", drvdata->is_qcom_cti ? "QCOM " : "");
 	return 0;
 }
 
diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h
index dd1ba44518c4..2598601e7b93 100644
--- a/drivers/hwtracing/coresight/coresight-cti.h
+++ b/drivers/hwtracing/coresight/coresight-cti.h
@@ -55,10 +55,11 @@ struct fwnode_handle;
 /*
  * CTI CSSoc 600 has a max of 32 trigger signals per direction.
  * CTI CSSoc 400 has 8 IO triggers - other CTIs can be impl def.
+ * QCOM CTI supports up to 128 trigger signals per direction.
  * Max of in and out defined in the DEVID register.
  * - pick up actual number used from .dts parameters if present.
  */
-#define CTIINOUTEN_MAX		32
+#define CTIINOUTEN_MAX		128
 
 /*
  * Encode CTI register offset and register index in one u32:
@@ -188,6 +189,7 @@ struct cti_drvdata {
 	raw_spinlock_t spinlock;
 	struct cti_config config;
 	struct list_head node;
+	bool is_qcom_cti;
 };
 
 /*
diff --git a/drivers/hwtracing/coresight/qcom-cti.h b/drivers/hwtracing/coresight/qcom-cti.h
new file mode 100644
index 000000000000..fd1bf07d7cb4
--- /dev/null
+++ b/drivers/hwtracing/coresight/qcom-cti.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _CORESIGHT_QCOM_CTI_H
+#define _CORESIGHT_QCOM_CTI_H
+
+#include "coresight-cti.h"
+
+#define ARCHITECT_QCOM 0x477
+
+/* CTI programming registers */
+#define QCOM_CTIINTACK		0x020
+#define QCOM_CTIAPPSET		0x004
+#define QCOM_CTIAPPCLEAR	0x008
+#define QCOM_CTIAPPPULSE	0x00C
+#define QCOM_CTIINEN		0x400
+#define QCOM_CTIOUTEN		0x800
+#define QCOM_CTITRIGINSTATUS	0x040
+#define QCOM_CTITRIGOUTSTATUS	0x060
+#define QCOM_CTICHINSTATUS	0x080
+#define QCOM_CTICHOUTSTATUS	0x084
+#define QCOM_CTIGATE		0x088
+#define QCOM_ASICCTL		0x08C
+/* Integration test registers */
+#define QCOM_ITCHINACK		0xE70
+#define QCOM_ITTRIGINACK	0xE80
+#define QCOM_ITCHOUT		0xE74
+#define QCOM_ITTRIGOUT		0xEA0
+#define QCOM_ITCHOUTACK		0xE78
+#define QCOM_ITTRIGOUTACK	0xEC0
+#define QCOM_ITCHIN		0xE7C
+#define QCOM_ITTRIGIN		0xEE0
+
+static noinline u32 cti_qcom_reg_off(u32 offset)
+{
+	switch (offset) {
+	case CTIINTACK:		return QCOM_CTIINTACK;
+	case CTIAPPSET:		return QCOM_CTIAPPSET;
+	case CTIAPPCLEAR:	return QCOM_CTIAPPCLEAR;
+	case CTIAPPPULSE:	return QCOM_CTIAPPPULSE;
+	case CTIINEN:		return QCOM_CTIINEN;
+	case CTIOUTEN:		return QCOM_CTIOUTEN;
+	case CTITRIGINSTATUS:	return QCOM_CTITRIGINSTATUS;
+	case CTITRIGOUTSTATUS:	return QCOM_CTITRIGOUTSTATUS;
+	case CTICHINSTATUS:	return QCOM_CTICHINSTATUS;
+	case CTICHOUTSTATUS:	return QCOM_CTICHOUTSTATUS;
+	case CTIGATE:		return QCOM_CTIGATE;
+	case ASICCTL:		return QCOM_ASICCTL;
+	case ITCHINACK:		return QCOM_ITCHINACK;
+	case ITTRIGINACK:	return QCOM_ITTRIGINACK;
+	case ITCHOUT:		return QCOM_ITCHOUT;
+	case ITTRIGOUT:		return QCOM_ITTRIGOUT;
+	case ITCHOUTACK:	return QCOM_ITCHOUTACK;
+	case ITTRIGOUTACK:	return QCOM_ITTRIGOUTACK;
+	case ITCHIN:		return QCOM_ITCHIN;
+	case ITTRIGIN:		return QCOM_ITTRIGIN;
+
+	default:
+		return offset;
+	}
+}
+
+#endif  /* _CORESIGHT_QCOM_CTI_H */

-- 
2.43.0



^ permalink raw reply related

* [PATCH v8 2/4] coresight: cti: encode trigger register index in register offsets
From: Yingchao Deng @ 2026-04-26  9:44 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Leo Yan,
	Alexander Shishkin
  Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
	quic_yingdeng, Jinlong Mao, Tingwei Zhang, Jie Gan, Yingchao Deng
In-Reply-To: <20260426-extended-cti-v8-0-23b900a4902f@oss.qualcomm.com>

Introduce a small encoding to carry the register index together with the
base offset in a single u32, and use a common helper to compute the final
MMIO address. This refactors register access to be based on the encoded
(reg, nr) pair, reducing duplicated arithmetic and making it easier to
support variants that bank or relocate trigger-indexed registers.

Signed-off-by: Yingchao Deng <yingchao.deng@oss.qualcomm.com>
---
 drivers/hwtracing/coresight/coresight-cti-core.c  | 31 +++++++++++++++--------
 drivers/hwtracing/coresight/coresight-cti-sysfs.c |  4 +--
 drivers/hwtracing/coresight/coresight-cti.h       | 16 ++++++++++--
 3 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
index 4e7d12bd2d3e..c4cbeb64365b 100644
--- a/drivers/hwtracing/coresight/coresight-cti-core.c
+++ b/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -42,6 +42,14 @@ static DEFINE_MUTEX(ect_mutex);
 #define csdev_to_cti_drvdata(csdev)	\
 	dev_get_drvdata(csdev->dev.parent)
 
+static void __iomem *cti_reg_addr(struct cti_drvdata *drvdata, int reg)
+{
+	u32 offset = CTI_REG_CLR_NR(reg);
+	u32 nr = CTI_REG_GET_NR(reg);
+
+	return drvdata->base + offset + sizeof(u32) * nr;
+}
+
 /* write set of regs to hardware - call with spinlock claimed */
 void cti_write_all_hw_regs(struct cti_drvdata *drvdata)
 {
@@ -55,16 +63,17 @@ void cti_write_all_hw_regs(struct cti_drvdata *drvdata)
 
 	/* write the CTI trigger registers */
 	for (i = 0; i < config->nr_trig_max; i++) {
-		writel_relaxed(config->ctiinen[i], drvdata->base + CTIINEN(i));
+		writel_relaxed(config->ctiinen[i],
+			       cti_reg_addr(drvdata, CTI_REG_SET_NR(CTIINEN, i)));
 		writel_relaxed(config->ctiouten[i],
-			       drvdata->base + CTIOUTEN(i));
+			       cti_reg_addr(drvdata, CTI_REG_SET_NR(CTIOUTEN, i)));
 	}
 
 	/* other regs */
-	writel_relaxed(config->ctigate, drvdata->base + CTIGATE);
+	writel_relaxed(config->ctigate, cti_reg_addr(drvdata, CTIGATE));
 	if (config->asicctl_impl)
-		writel_relaxed(config->asicctl, drvdata->base + ASICCTL);
-	writel_relaxed(config->ctiappset, drvdata->base + CTIAPPSET);
+		writel_relaxed(config->asicctl, cti_reg_addr(drvdata, ASICCTL));
+	writel_relaxed(config->ctiappset, cti_reg_addr(drvdata, CTIAPPSET));
 
 	/* re-enable CTI */
 	writel_relaxed(1, drvdata->base + CTICONTROL);
@@ -127,7 +136,7 @@ u32 cti_read_single_reg(struct cti_drvdata *drvdata, int offset)
 	int val;
 
 	CS_UNLOCK(drvdata->base);
-	val = readl_relaxed(drvdata->base + offset);
+	val = readl_relaxed(cti_reg_addr(drvdata, offset));
 	CS_LOCK(drvdata->base);
 
 	return val;
@@ -136,7 +145,7 @@ u32 cti_read_single_reg(struct cti_drvdata *drvdata, int offset)
 void cti_write_single_reg(struct cti_drvdata *drvdata, int offset, u32 value)
 {
 	CS_UNLOCK(drvdata->base);
-	writel_relaxed(value, drvdata->base + offset);
+	writel_relaxed(value, cti_reg_addr(drvdata, offset));
 	CS_LOCK(drvdata->base);
 }
 
@@ -344,8 +353,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
 
 	/* update the local register values */
 	chan_bitmask = BIT(channel_idx);
-	reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) :
-		      CTIOUTEN(trigger_idx));
+	reg_offset = (direction == CTI_TRIG_IN ? CTIINEN : CTIOUTEN);
 
 	guard(raw_spinlock_irqsave)(&drvdata->spinlock);
 
@@ -365,8 +373,9 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
 
 	/* write through if enabled */
 	if (cti_is_active(config))
-		cti_write_single_reg(drvdata, reg_offset, reg_value);
-
+		cti_write_single_reg(drvdata,
+				     CTI_REG_SET_NR(reg_offset, trigger_idx),
+				     reg_value);
 	return 0;
 }
 
diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
index 2bbfa405cb6b..8b70e7e38ea3 100644
--- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
@@ -386,7 +386,7 @@ static ssize_t inen_store(struct device *dev,
 
 	/* write through if enabled */
 	if (cti_is_active(config))
-		cti_write_single_reg(drvdata, CTIINEN(index), val);
+		cti_write_single_reg(drvdata, CTI_REG_SET_NR(CTIINEN, index), val);
 
 	return size;
 }
@@ -427,7 +427,7 @@ static ssize_t outen_store(struct device *dev,
 
 	/* write through if enabled */
 	if (cti_is_active(config))
-		cti_write_single_reg(drvdata, CTIOUTEN(index), val);
+		cti_write_single_reg(drvdata, CTI_REG_SET_NR(CTIOUTEN, index), val);
 
 	return size;
 }
diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h
index ef079fc18b72..dd1ba44518c4 100644
--- a/drivers/hwtracing/coresight/coresight-cti.h
+++ b/drivers/hwtracing/coresight/coresight-cti.h
@@ -7,6 +7,7 @@
 #ifndef _CORESIGHT_CORESIGHT_CTI_H
 #define _CORESIGHT_CORESIGHT_CTI_H
 
+#include <linux/bitfield.h>
 #include <linux/coresight.h>
 #include <linux/device.h>
 #include <linux/list.h>
@@ -30,8 +31,8 @@ struct fwnode_handle;
 #define CTIAPPSET		0x014
 #define CTIAPPCLEAR		0x018
 #define CTIAPPPULSE		0x01C
-#define CTIINEN(n)		(0x020 + (4 * n))
-#define CTIOUTEN(n)		(0x0A0 + (4 * n))
+#define CTIINEN			0x020
+#define CTIOUTEN		0x0A0
 #define CTITRIGINSTATUS		0x130
 #define CTITRIGOUTSTATUS	0x134
 #define CTICHINSTATUS		0x138
@@ -59,6 +60,17 @@ struct fwnode_handle;
  */
 #define CTIINOUTEN_MAX		32
 
+/*
+ * Encode CTI register offset and register index in one u32:
+ *   - bits[0:11]  : base register offset (0x000 to 0xFFF)
+ *   - bits[24:31] : register index (nr)
+ */
+#define CTI_REG_NR_MASK			GENMASK(31, 24)
+#define CTI_REG_GET_NR(reg)		FIELD_GET(CTI_REG_NR_MASK, (reg))
+#define CTI_REG_SET_NR_CONST(reg, nr)	((reg) | FIELD_PREP_CONST(CTI_REG_NR_MASK, (nr)))
+#define CTI_REG_SET_NR(reg, nr)		((reg) | FIELD_PREP(CTI_REG_NR_MASK, (nr)))
+#define CTI_REG_CLR_NR(reg)		((reg) & (~CTI_REG_NR_MASK))
+
 /**
  * Group of related trigger signals
  *

-- 
2.43.0



^ permalink raw reply related

* [PATCH v8 1/4] coresight: cti: Convert trigger usage fields to dynamic bitmaps and arrays
From: Yingchao Deng @ 2026-04-26  9:44 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Leo Yan,
	Alexander Shishkin
  Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
	quic_yingdeng, Jinlong Mao, Tingwei Zhang, Jie Gan, Yingchao Deng
In-Reply-To: <20260426-extended-cti-v8-0-23b900a4902f@oss.qualcomm.com>

Replace the fixed-size u32 fields in the cti_config and cti_trig_grp
structure with dynamically allocated bitmaps and arrays. This allows
memory to be allocated based on the actual number of triggers during probe
time, reducing memory footprint and improving scalability for platforms
with varying trigger counts.

Signed-off-by: Yingchao Deng <yingchao.deng@oss.qualcomm.com>
---
 drivers/hwtracing/coresight/coresight-cti-core.c   | 59 +++++++++++++++++-----
 .../hwtracing/coresight/coresight-cti-platform.c   | 26 +++++++---
 drivers/hwtracing/coresight/coresight-cti-sysfs.c  | 14 ++---
 drivers/hwtracing/coresight/coresight-cti.h        | 12 ++---
 4 files changed, 76 insertions(+), 35 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
index 2f4c9362709a..4e7d12bd2d3e 100644
--- a/drivers/hwtracing/coresight/coresight-cti-core.c
+++ b/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -161,8 +161,8 @@ void cti_write_intack(struct device *dev, u32 ackval)
 /* DEVID[19:16] - number of CTM channels */
 #define CTI_DEVID_CTMCHANNELS(devid_val) ((int) BMVAL(devid_val, 16, 19))
 
-static void cti_set_default_config(struct device *dev,
-				   struct cti_drvdata *drvdata)
+static int cti_set_default_config(struct device *dev,
+				  struct cti_drvdata *drvdata)
 {
 	struct cti_config *config = &drvdata->config;
 	u32 devid;
@@ -181,6 +181,26 @@ static void cti_set_default_config(struct device *dev,
 		config->nr_trig_max = CTIINOUTEN_MAX;
 	}
 
+	config->trig_in_use = devm_bitmap_zalloc(dev, config->nr_trig_max, GFP_KERNEL);
+	if (!config->trig_in_use)
+		return -ENOMEM;
+
+	config->trig_out_use = devm_bitmap_zalloc(dev, config->nr_trig_max, GFP_KERNEL);
+	if (!config->trig_out_use)
+		return -ENOMEM;
+
+	config->trig_out_filter = devm_bitmap_zalloc(dev, config->nr_trig_max, GFP_KERNEL);
+	if (!config->trig_out_filter)
+		return -ENOMEM;
+
+	config->ctiinen = devm_kcalloc(dev, config->nr_trig_max, sizeof(u32), GFP_KERNEL);
+	if (!config->ctiinen)
+		return -ENOMEM;
+
+	config->ctiouten = devm_kcalloc(dev, config->nr_trig_max, sizeof(u32), GFP_KERNEL);
+	if (!config->ctiouten)
+		return -ENOMEM;
+
 	config->nr_ctm_channels = CTI_DEVID_CTMCHANNELS(devid);
 
 	/* Most regs default to 0 as zalloc'ed except...*/
@@ -189,6 +209,7 @@ static void cti_set_default_config(struct device *dev,
 	config->enable_req_count = 0;
 
 	config->asicctl_impl = !!FIELD_GET(GENMASK(4, 0), devid);
+	return 0;
 }
 
 /*
@@ -219,8 +240,10 @@ int cti_add_connection_entry(struct device *dev, struct cti_drvdata *drvdata,
 	cti_dev->nr_trig_con++;
 
 	/* add connection usage bit info to overall info */
-	drvdata->config.trig_in_use |= tc->con_in->used_mask;
-	drvdata->config.trig_out_use |= tc->con_out->used_mask;
+	bitmap_or(drvdata->config.trig_in_use, drvdata->config.trig_in_use,
+		  tc->con_in->used_mask, drvdata->config.nr_trig_max);
+	bitmap_or(drvdata->config.trig_out_use, drvdata->config.trig_out_use,
+		  tc->con_out->used_mask, drvdata->config.nr_trig_max);
 
 	return 0;
 }
@@ -231,6 +254,8 @@ struct cti_trig_con *cti_allocate_trig_con(struct device *dev, int in_sigs,
 {
 	struct cti_trig_con *tc = NULL;
 	struct cti_trig_grp *in = NULL, *out = NULL;
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev);
+	int n_trigs = drvdata->config.nr_trig_max;
 
 	tc = devm_kzalloc(dev, sizeof(struct cti_trig_con), GFP_KERNEL);
 	if (!tc)
@@ -242,12 +267,20 @@ struct cti_trig_con *cti_allocate_trig_con(struct device *dev, int in_sigs,
 	if (!in)
 		return NULL;
 
+	in->used_mask = devm_bitmap_zalloc(dev, n_trigs, GFP_KERNEL);
+	if (!in->used_mask)
+		return NULL;
+
 	out = devm_kzalloc(dev,
 			   offsetof(struct cti_trig_grp, sig_types[out_sigs]),
 			   GFP_KERNEL);
 	if (!out)
 		return NULL;
 
+	out->used_mask = devm_bitmap_zalloc(dev, n_trigs, GFP_KERNEL);
+	if (!out->used_mask)
+		return NULL;
+
 	tc->con_in = in;
 	tc->con_out = out;
 	tc->con_in->nr_sigs = in_sigs;
@@ -263,7 +296,6 @@ int cti_add_default_connection(struct device *dev, struct cti_drvdata *drvdata)
 {
 	int ret = 0;
 	int n_trigs = drvdata->config.nr_trig_max;
-	u32 n_trig_mask = GENMASK(n_trigs - 1, 0);
 	struct cti_trig_con *tc = NULL;
 
 	/*
@@ -274,8 +306,8 @@ int cti_add_default_connection(struct device *dev, struct cti_drvdata *drvdata)
 	if (!tc)
 		return -ENOMEM;
 
-	tc->con_in->used_mask = n_trig_mask;
-	tc->con_out->used_mask = n_trig_mask;
+	bitmap_fill(tc->con_in->used_mask, n_trigs);
+	bitmap_fill(tc->con_out->used_mask, n_trigs);
 	ret = cti_add_connection_entry(dev, drvdata, tc, NULL, "default");
 	return ret;
 }
@@ -288,7 +320,6 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
 {
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
-	u32 trig_bitmask;
 	u32 chan_bitmask;
 	u32 reg_value;
 	int reg_offset;
@@ -298,18 +329,16 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
 	   (trigger_idx >= config->nr_trig_max))
 		return -EINVAL;
 
-	trig_bitmask = BIT(trigger_idx);
-
 	/* ensure registered triggers and not out filtered */
 	if (direction == CTI_TRIG_IN)	{
-		if (!(trig_bitmask & config->trig_in_use))
+		if (!(test_bit(trigger_idx, config->trig_in_use)))
 			return -EINVAL;
 	} else {
-		if (!(trig_bitmask & config->trig_out_use))
+		if (!(test_bit(trigger_idx, config->trig_out_use)))
 			return -EINVAL;
 
 		if ((config->trig_filter_enable) &&
-		    (config->trig_out_filter & trig_bitmask))
+		    test_bit(trigger_idx, config->trig_out_filter))
 			return -EINVAL;
 	}
 
@@ -687,7 +716,9 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
 	raw_spin_lock_init(&drvdata->spinlock);
 
 	/* initialise CTI driver config values */
-	cti_set_default_config(dev, drvdata);
+	ret = cti_set_default_config(dev, drvdata);
+	if (ret)
+		return ret;
 
 	pdata = coresight_cti_get_platform_data(dev);
 	if (IS_ERR(pdata)) {
diff --git a/drivers/hwtracing/coresight/coresight-cti-platform.c b/drivers/hwtracing/coresight/coresight-cti-platform.c
index 4eff96f48594..557debbc8ca4 100644
--- a/drivers/hwtracing/coresight/coresight-cti-platform.c
+++ b/drivers/hwtracing/coresight/coresight-cti-platform.c
@@ -136,8 +136,8 @@ static int cti_plat_create_v8_etm_connection(struct device *dev,
 		goto create_v8_etm_out;
 
 	/* build connection data */
-	tc->con_in->used_mask = 0xF0; /* sigs <4,5,6,7> */
-	tc->con_out->used_mask = 0xF0; /* sigs <4,5,6,7> */
+	bitmap_set(tc->con_in->used_mask, 4, 4); /* sigs <4,5,6,7> */
+	bitmap_set(tc->con_out->used_mask, 4, 4); /* sigs <4,5,6,7> */
 
 	/*
 	 * The EXTOUT type signals from the ETM are connected to a set of input
@@ -194,10 +194,10 @@ static int cti_plat_create_v8_connections(struct device *dev,
 		goto of_create_v8_out;
 
 	/* Set the v8 PE CTI connection data */
-	tc->con_in->used_mask = 0x3; /* sigs <0 1> */
+	bitmap_set(tc->con_in->used_mask, 0, 2); /* sigs <0 1> */
 	tc->con_in->sig_types[0] = PE_DBGTRIGGER;
 	tc->con_in->sig_types[1] = PE_PMUIRQ;
-	tc->con_out->used_mask = 0x7; /* sigs <0 1 2 > */
+	bitmap_set(tc->con_out->used_mask, 0, 3); /* sigs <0 1 2 > */
 	tc->con_out->sig_types[0] = PE_EDBGREQ;
 	tc->con_out->sig_types[1] = PE_DBGRESTART;
 	tc->con_out->sig_types[2] = PE_CTIIRQ;
@@ -213,7 +213,7 @@ static int cti_plat_create_v8_connections(struct device *dev,
 		goto of_create_v8_out;
 
 	/* filter pe_edbgreq - PE trigout sig <0> */
-	drvdata->config.trig_out_filter |= 0x1;
+	set_bit(0, drvdata->config.trig_out_filter);
 
 of_create_v8_out:
 	return ret;
@@ -257,7 +257,7 @@ static int cti_plat_read_trig_group(struct cti_trig_grp *tgrp,
 	if (!err) {
 		/* set the signal usage mask */
 		for (idx = 0; idx < tgrp->nr_sigs; idx++)
-			tgrp->used_mask |= BIT(values[idx]);
+			set_bit(values[idx], tgrp->used_mask);
 	}
 
 	kfree(values);
@@ -316,23 +316,33 @@ static int cti_plat_process_filter_sigs(struct cti_drvdata *drvdata,
 {
 	struct cti_trig_grp *tg = NULL;
 	int err = 0, nr_filter_sigs;
+	int nr_trigs = drvdata->config.nr_trig_max;
 
 	nr_filter_sigs = cti_plat_count_sig_elements(fwnode,
 						     CTI_DT_FILTER_OUT_SIGS);
 	if (nr_filter_sigs == 0)
 		return 0;
 
-	if (nr_filter_sigs > drvdata->config.nr_trig_max)
+	if (nr_filter_sigs > nr_trigs)
 		return -EINVAL;
 
 	tg = kzalloc_obj(*tg);
 	if (!tg)
 		return -ENOMEM;
 
+	tg->used_mask = bitmap_zalloc(nr_trigs, GFP_KERNEL);
+	if (!tg->used_mask) {
+		kfree(tg);
+		return -ENOMEM;
+	}
+
 	err = cti_plat_read_trig_group(tg, fwnode, CTI_DT_FILTER_OUT_SIGS);
 	if (!err)
-		drvdata->config.trig_out_filter |= tg->used_mask;
+		bitmap_or(drvdata->config.trig_out_filter,
+			  drvdata->config.trig_out_filter,
+			  tg->used_mask, nr_trigs);
 
+	bitmap_free(tg->used_mask);
 	kfree(tg);
 	return err;
 }
diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
index 3fe2c916d228..2bbfa405cb6b 100644
--- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
@@ -719,12 +719,12 @@ static ssize_t trigout_filtered_show(struct device *dev,
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *cfg = &drvdata->config;
 	int nr_trig_max = cfg->nr_trig_max;
-	unsigned long mask = cfg->trig_out_filter;
+	unsigned long *mask = cfg->trig_out_filter;
 
-	if (mask == 0)
+	if (bitmap_empty(mask, nr_trig_max))
 		return 0;
 
-	return sysfs_emit(buf, "%*pbl\n", nr_trig_max, &mask);
+	return sysfs_emit(buf, "%*pbl\n", nr_trig_max, mask);
 }
 static DEVICE_ATTR_RO(trigout_filtered);
 
@@ -931,9 +931,9 @@ static ssize_t trigin_sig_show(struct device *dev,
 	struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *cfg = &drvdata->config;
-	unsigned long mask = con->con_in->used_mask;
+	unsigned long *mask = con->con_in->used_mask;
 
-	return sysfs_emit(buf, "%*pbl\n", cfg->nr_trig_max, &mask);
+	return sysfs_emit(buf, "%*pbl\n", cfg->nr_trig_max, mask);
 }
 
 static ssize_t trigout_sig_show(struct device *dev,
@@ -945,9 +945,9 @@ static ssize_t trigout_sig_show(struct device *dev,
 	struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *cfg = &drvdata->config;
-	unsigned long mask = con->con_out->used_mask;
+	unsigned long *mask = con->con_out->used_mask;
 
-	return sysfs_emit(buf, "%*pbl\n", cfg->nr_trig_max, &mask);
+	return sysfs_emit(buf, "%*pbl\n", cfg->nr_trig_max, mask);
 }
 
 /* convert a sig type id to a name */
diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h
index c5f9e79fabc6..ef079fc18b72 100644
--- a/drivers/hwtracing/coresight/coresight-cti.h
+++ b/drivers/hwtracing/coresight/coresight-cti.h
@@ -68,7 +68,7 @@ struct fwnode_handle;
  */
 struct cti_trig_grp {
 	int nr_sigs;
-	u32 used_mask;
+	unsigned long *used_mask;
 	int sig_types[];
 };
 
@@ -145,17 +145,17 @@ struct cti_config {
 	int enable_req_count;
 
 	/* registered triggers and filtering */
-	u32 trig_in_use;
-	u32 trig_out_use;
-	u32 trig_out_filter;
+	unsigned long *trig_in_use;
+	unsigned long *trig_out_use;
+	unsigned long *trig_out_filter;
 	bool trig_filter_enable;
 	u8 xtrig_rchan_sel;
 
 	/* cti cross trig programmable regs */
 	u32 ctiappset;
 	u8 ctiinout_sel;
-	u32 ctiinen[CTIINOUTEN_MAX];
-	u32 ctiouten[CTIINOUTEN_MAX];
+	u32 *ctiinen;
+	u32 *ctiouten;
 	u32 ctigate;
 	u32 asicctl;
 };

-- 
2.43.0



^ permalink raw reply related

* [PATCH v8 0/4] Add Qualcomm extended CTI support
From: Yingchao Deng @ 2026-04-26  9:44 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Leo Yan,
	Alexander Shishkin
  Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
	quic_yingdeng, Jinlong Mao, Tingwei Zhang, Jie Gan, Yingchao Deng

The Qualcomm extended CTI is a heavily parameterized version of ARM’s
CSCTI. It allows a debugger to send to trigger events to a processor or to
send a trigger event to one or more processors when a trigger event occurs
on another processor on the same SoC, or even between SoCs.

Qualcomm extended CTI supports up to 128 triggers. And some of the register
offsets are changed.

The commands to configure CTI triggers are the same as ARM's CTI.

Prerequisites:
   This series depends on the following CoreSight fix:
   [PATCH v2 1/1] coresight: fix issue where coresight component has no claimtags
Link: https://lore.kernel.org/all/20251027223545.2801-2-mike.leach@linaro.org/

Changes in v8:
1. Rebased on top of linux-next-20260424.
2. patch 1: Use devm_bitmap_zalloc() with nr_trig_max instead of per-connection
   signal counts; add bitmap_zalloc() for filter trigger group.
3. patch 2: Add #include <linux/bitfield.h>; move CTIINOUTEN_MAX expansion
   to patch3.
4. patch 3: wrap CLAIMSET clear with CS_UNLOCK/CS_LOCK; move CTIINOUTEN_MAX
   to 128 here with comment; fix macro alignment in qcom-cti.h.
5. patch 4: Make qcom_suffix_registers[] static.

Changes in v7:
1. Split the extended CTI support into smaller, logically independent
   patches to improve reviewability.
2. Removed the dual offset-array based register access used in v6 for
   standard and Qualcomm CTIs. Register addressing is now unified through
   a single code path by encoding the register index together with the base
   offset and applying variant-specific translation at the final MMIO
   access point. 
3. Removed ext_reg_sel, extend the CTI sysfs interface to expose banked 
   register instances on Qualcomm CTIs only. Numbered sysfs nodes are
   hidden on standard ARM CTIs, and on Qualcomm CTIs their visibility is
   derived from nr_trig_max (32 triggers per bank), ensuring that only
   registers backed by hardware are exposed.
Link to v6 - https://lore.kernel.org/all/20251202-extended_cti-v6-0-ab68bb15c4f5@oss.qualcomm.com/

Changes in v6:
1. Rename regs_idx to ext_reg_sel and add information in documentation
   file.
2. Reset CLAIMSET to zero for qcom-cti during probe.
3. Retrieve idx value under spinlock.
4. Use yearless copyright for qcom-cti.h.
Link to v5 - https://lore.kernel.org/all/20251020-extended_cti-v5-0-6f193da2d467@oss.qualcomm.com/

Changes in v5:
1. Move common part in qcom-cti.h to coresight-cti.h.
2. Convert trigger usage fields to dynamic bitmaps and arrays.
3. Fix holes in struct cti_config to save some space.
4. Revert the previous changes related to the claim tag in
   cti_enable/disable_hw.
Link to v4 - https://lore.kernel.org/linux-arm-msm/20250902-extended_cti-v4-1-7677de04b416@oss.qualcomm.com/

Changes in v4:
1. Read the DEVARCH registers to identify Qualcomm CTI.
2. Add a reg_idx node, and refactor the coresight_cti_reg_show() and
coresight_cti_reg_store() functions accordingly.
3. The register offsets specific to Qualcomm CTI are moved to qcom_cti.h.
Link to v3 - https://lore.kernel.org/linux-arm-msm/20250722081405.2947294-1-quic_jinlmao@quicinc.com/

Changes in v3:
1. Rename is_extended_cti() to of_is_extended_cti().
2. Add the missing 'i' when write the CTI trigger registers.
3. Convert the multi-line output in sysfs to single line.
4. Initialize offset arrays using designated initializer.
Link to V2 - https://lore.kernel.org/all/20250429071841.1158315-3-quic_jinlmao@quicinc.com/

Changes in V2:
1. Add enum for compatible items.
2. Move offset arrays to coresight-cti-core

Signed-off-by: Yingchao Deng <yingchao.deng@oss.qualcomm.com>
---
Yingchao Deng (4):
      coresight: cti: Convert trigger usage fields to dynamic bitmaps and arrays
      coresight: cti: encode trigger register index in register offsets
      coresight: cti: add Qualcomm extended CTI identification and quirks
      coresight: cti: expose banked sysfs registers for Qualcomm extended CTI

 drivers/hwtracing/coresight/coresight-cti-core.c   | 118 ++++++++++++++++-----
 .../hwtracing/coresight/coresight-cti-platform.c   |  26 +++--
 drivers/hwtracing/coresight/coresight-cti-sysfs.c  |  76 +++++++++++--
 drivers/hwtracing/coresight/coresight-cti.h        |  32 ++++--
 drivers/hwtracing/coresight/qcom-cti.h             |  65 ++++++++++++
 5 files changed, 265 insertions(+), 52 deletions(-)
---
base-commit: 8594d92c94a3624acf07acf634a5e73a8c8f63e2
change-id: 20260426-extended-cti-32f728f93cba

Best regards,
-- 
Yingchao Deng <yingchao.deng@oss.qualcomm.com>



^ permalink raw reply

* Re: [PATCH v5 3/6] pwm: Add rockchip PWMv4 driver
From: Damon Ding @ 2026-04-26  9:44 UTC (permalink / raw)
  To: Nicolas Frattaroli, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Lee Jones,
	William Breathitt Gray
  Cc: kernel, Jonas Karlman, Alexey Charkov, linux-rockchip, linux-pwm,
	devicetree, linux-arm-kernel, linux-kernel, linux-iio
In-Reply-To: <20260420-rk3576-pwm-v5-3-ae7cfbbe5427@collabora.com>

Hi Nicolas,

On 4/20/2026 9:52 PM, Nicolas Frattaroli wrote:
> The Rockchip RK3576 brings with it a new PWM IP, in downstream code
> referred to as "v4". This new IP is different enough from the previous
> Rockchip IP that I felt it necessary to add a new driver for it, instead
> of shoehorning it in the old one.
> 
> Add this new driver, based on the PWM core's waveform APIs. Its platform
> device is registered by the parent mfpwm driver, from which it also
> receives a little platform data struct, so that mfpwm can guarantee that
> all the platform device drivers spread across different subsystems for
> this specific hardware IP do not interfere with each other.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Tested-by: Damon Ding <damon.ding@rock-chips.com>

The continuous mode of all PWM channels has been preliminarily tested
and verified working on the RK3576 IoT board.

I have tested with several typical period and duty cycle configurations.

Following Uwe's suggestion [0], I also tested with libpwm using commands
similar to the following:

./pwmset -c 0 -p 0 -P 1000000 -D 500000 -s 5000

I was previously unaware of the existence of libpwm. I will continue to 
follow its upstream development and updates going forward. :-)

Best regards,
Damon

[0]https://lore.kernel.org/all/fgu42esufq2x4fcccncqs3hlotih2gqmws5atotlaznuahoslw@34vblr6vboze/


^ permalink raw reply

* Re: [PATCH v4 35/49] KVM: arm64: GICv3: nv: Plug L1 LR sync into deactivation primitive
From: Marc Zyngier @ 2026-04-26  9:14 UTC (permalink / raw)
  To: Vishnu Pajjuri
  Cc: Fuad Tabba, Joey Gouly, Suzuki K Poulose, Oliver Upton,
	Zenghui Yu, Christoffer Dall, Mark Brown, kvm, linux-arm-kernel,
	kvmarm, Darren Hart
In-Reply-To: <e283e755-c348-43cf-b5fe-278c5eab742d@os.amperecomputing.com>

On Wed, 22 Apr 2026 15:57:44 +0100,
Vishnu Pajjuri <vishnu@os.amperecomputing.com> wrote:
> 
> Hi Marc,
> 
> On 22-04-2026 12:25, Marc Zyngier wrote:
> >
> > Have you made progress on this? I can't reproduce it at all despite my
> > best effort. I'm perfectly happy to help, but you need to give me
> > *something* to go on.
> 
> 
> Thanks for your support!!
> 
> The issue is triggered as soon as the timer interrupt (IRQ 27) is
> deactivated. Preventing the deactivation of IRQ 27 during nested VGIC
> state transitions prevents the failure from reproducing.

Which level of deactivation? From L2 to L1? Or L1 to L0? The former
should just be a an update to the irq structure, while the latter is
effectively a write to ICC_DIR_EL1, and *that* is a new behaviour
introduced by this patch.

I wonder if your implementation is such that ICC_DIR_EL1 is trapped by
ICH_HCR_EL2.TDIR, which is allowed by the architecture, but that none
of the two implementations I have actually enforce (the trap only
applies to ICV_DIR_EL1). Can you try the hack below which disables the
traps much earlier, and let me know if that helps?

Even if that's the case, this should result in an EL2->EL2 exception,
and that should be caught as an unhandled exception in entry-common.c,
so something else is afoot.

Thanks,

	M.

diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
index 5c69fa615823c..ee415c1038b4e 100644
--- a/arch/arm64/kvm/vgic/vgic-v3-nested.c
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -280,6 +280,14 @@ void vgic_v3_sync_nested(struct kvm_vcpu *vcpu)
 	struct shadow_if *shadow_if = get_shadow_if();
 	int i;
 
+	/* We need these to be synchronised to generate the MI */
+	__vcpu_assign_sys_reg(vcpu, ICH_VMCR_EL2, read_sysreg_s(SYS_ICH_VMCR_EL2));
+	__vcpu_rmw_sys_reg(vcpu, ICH_HCR_EL2, &=, ~ICH_HCR_EL2_EOIcount);
+	__vcpu_rmw_sys_reg(vcpu, ICH_HCR_EL2, |=, read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EL2_EOIcount);
+
+	write_sysreg_s(0, SYS_ICH_HCR_EL2);
+	isb();
+
 	for_each_set_bit(i, &shadow_if->lr_map, kvm_vgic_global_state.nr_lr) {
 		u64 val, host_lr, lr;
 
@@ -309,14 +317,6 @@ void vgic_v3_sync_nested(struct kvm_vcpu *vcpu)
 		vgic_v3_deactivate(vcpu, FIELD_GET(ICH_LR_PHYS_ID_MASK, lr));
 	}
 
-	/* We need these to be synchronised to generate the MI */
-	__vcpu_assign_sys_reg(vcpu, ICH_VMCR_EL2, read_sysreg_s(SYS_ICH_VMCR_EL2));
-	__vcpu_rmw_sys_reg(vcpu, ICH_HCR_EL2, &=, ~ICH_HCR_EL2_EOIcount);
-	__vcpu_rmw_sys_reg(vcpu, ICH_HCR_EL2, |=, read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EL2_EOIcount);
-
-	write_sysreg_s(0, SYS_ICH_HCR_EL2);
-	isb();
-
 	vgic_v3_nested_update_mi(vcpu);
 }
 

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply related

* Re: [PATCH v10 03/11] drm/fourcc: Add DRM_FORMAT_Y8
From: Simon Ser @ 2026-04-26  8:26 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
	Michal Simek, dri-devel, linux-kernel, linux-arm-kernel,
	Geert Uytterhoeven, Dmitry Baryshkov, Pekka Paalanen,
	Pekka Paalanen, Dmitry Baryshkov
In-Reply-To: <20260423-xilinx-formats-v10-3-c690c2b8ea89@ideasonboard.com>

On Thursday, April 23rd, 2026 at 16:22, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> wrote:

> However, adding DRM_FORMAT_Y8 makes sense, we can mark it as 'is_yuv' in
> the drm_format_info, and this can help the drivers handle e.g.
> full/limited range. This will distinguish two single-channel formats:
> R8, which is a RGB format with the same value for all components, and
> Y8, which is a Y-only YCbCr format, with Cb and Cr being neutral.

I've been wondering on IRC whether we really need yet another 1-channel
format, since Y8 isn't that different from Y8. Pekka said:

- R8 doesn't necessarily expand to G an B channels. The Vulkan spec
  states that R8 expands to (R, 0, 0).
- Y8 is semantically more correct than R8 to represent grayscale
  formats.

I wonder if we would've added R8 at all if had Y8 from the start… 

Acked-by: Simon Ser <contact@emersion.fr>


^ permalink raw reply

* Re: [PATCH v10 01/11] drm/fourcc: Add warning for bad bpp
From: Simon Ser @ 2026-04-26  8:07 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
	Michal Simek, dri-devel, linux-kernel, linux-arm-kernel,
	Geert Uytterhoeven, Dmitry Baryshkov, Pekka Paalanen
In-Reply-To: <20260423-xilinx-formats-v10-1-c690c2b8ea89@ideasonboard.com>

I'm a bit concerned about zero here because none of the callers are
equipped to deal with zero AFAIU… Maybe that's fine, I'm not sure.

In any case, this is better than silently doing the wrong thing.

Acked-by: Simon Ser <contact@emersion.fr>


^ permalink raw reply

* Re: [PATCH v10 05/11] drm/fourcc: Add DRM_FORMAT_T430
From: Simon Ser @ 2026-04-26  8:05 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
	Michal Simek, dri-devel, linux-kernel, linux-arm-kernel,
	Geert Uytterhoeven, Dmitry Baryshkov, Pekka Paalanen
In-Reply-To: <20260423-xilinx-formats-v10-5-c690c2b8ea89@ideasonboard.com>

Reviewed-by: Simon Ser <contact@emersion.fr>


^ permalink raw reply

* Re: [PATCH v10 02/11] drm/fourcc: Add DRM_FORMAT_P230
From: Simon Ser @ 2026-04-26  8:03 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
	Michal Simek, dri-devel, linux-kernel, linux-arm-kernel,
	Geert Uytterhoeven, Dmitry Baryshkov, Pekka Paalanen,
	Dmitry Baryshkov
In-Reply-To: <20260423-xilinx-formats-v10-2-c690c2b8ea89@ideasonboard.com>

Reviewed-by: Simon Ser <contact@emersion.fr>


^ permalink raw reply

* Re: [PATCH v5 5/6] arm64: dts: rockchip: add PWM nodes to RK3576 SoC dtsi
From: Damon Ding @ 2026-04-26  7:30 UTC (permalink / raw)
  To: Nicolas Frattaroli, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Lee Jones,
	William Breathitt Gray
  Cc: kernel, Jonas Karlman, Alexey Charkov, linux-rockchip, linux-pwm,
	devicetree, linux-arm-kernel, linux-kernel, linux-iio
In-Reply-To: <20260420-rk3576-pwm-v5-5-ae7cfbbe5427@collabora.com>

Hi Nicolas,

On 4/20/2026 9:52 PM, Nicolas Frattaroli wrote:
> The RK3576 SoC features three distinct PWM controllers, with variable
> numbers of channels. Add each channel as a separate node to the SoC's
> device tree, as they don't really overlap in register ranges.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> ---
>   arch/arm64/boot/dts/rockchip/rk3576.dtsi | 208 +++++++++++++++++++++++++++++++
>   1 file changed, 208 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
> index e12a2a0cfb89..55d6b103c329 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
> @@ -1032,6 +1032,32 @@ uart1: serial@27310000 {
>   			status = "disabled";
>   		};
>   
> +		pwm0_2ch_0: pwm@27330000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x27330000 0x0 0x1000>;
> +			clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>,
> +				 <&cru CLK_PMU1PWM_OSC>, <&cru CLK_PMU1PWM_RC>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm0m0_ch0>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm0_2ch_1: pwm@27331000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x27331000 0x0 0x1000>;
> +			clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>,
> +				 <&cru CLK_PMU1PWM_OSC>, <&cru CLK_PMU1PWM_RC>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm0m0_ch1>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
>   		pmu: power-management@27380000 {
>   			compatible = "rockchip,rk3576-pmu", "syscon", "simple-mfd";
>   			reg = <0x0 0x27380000 0x0 0x800>;
> @@ -2630,6 +2656,188 @@ uart9: serial@2adc0000 {
>   			status = "disabled";
>   		};
>   
> +		pwm1_6ch_0: pwm@2add0000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2add0000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>,
> +				 <&cru CLK_OSC_PWM1>, <&cru CLK_RC_PWM1>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm1m0_ch0>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm1_6ch_1: pwm@2add1000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2add1000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>,
> +				 <&cru CLK_OSC_PWM1>, <&cru CLK_RC_PWM1>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm1m0_ch1>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm1_6ch_2: pwm@2add2000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2add2000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>,
> +				 <&cru CLK_OSC_PWM1>, <&cru CLK_RC_PWM1>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm1m0_ch2>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm1_6ch_3: pwm@2add3000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2add3000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>,
> +				 <&cru CLK_OSC_PWM1>, <&cru CLK_RC_PWM1>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm1m0_ch3>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm1_6ch_4: pwm@2add4000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2add4000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>,
> +				 <&cru CLK_OSC_PWM1>, <&cru CLK_RC_PWM1>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm1m0_ch4>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm1_6ch_5: pwm@2add5000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2add5000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>,
> +				 <&cru CLK_OSC_PWM1>, <&cru CLK_RC_PWM1>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm1m0_ch5>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm2_8ch_0: pwm@2ade0000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2ade0000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>,
> +				 <&cru CLK_OSC_PWM2>, <&cru CLK_RC_PWM2>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm2m0_ch0>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm2_8ch_1: pwm@2ade1000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2ade1000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>,
> +				 <&cru CLK_OSC_PWM2>, <&cru CLK_RC_PWM2>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm2m0_ch1>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm2_8ch_2: pwm@2ade2000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2ade2000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>,
> +				 <&cru CLK_OSC_PWM2>, <&cru CLK_RC_PWM2>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm2m0_ch2>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm2_8ch_3: pwm@2ade3000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2ade3000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>,
> +				 <&cru CLK_OSC_PWM2>, <&cru CLK_RC_PWM2>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm2m0_ch3>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm2_8ch_4: pwm@2ade4000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2ade4000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>,
> +				 <&cru CLK_OSC_PWM2>, <&cru CLK_RC_PWM2>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm2m0_ch4>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm2_8ch_5: pwm@2ade5000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2ade5000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>,
> +				 <&cru CLK_OSC_PWM2>, <&cru CLK_RC_PWM2>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm2m0_ch5>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm2_8ch_6: pwm@2ade6000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2ade6000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>,
> +				 <&cru CLK_OSC_PWM2>, <&cru CLK_RC_PWM2>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm2m0_ch6>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
> +		pwm2_8ch_7: pwm@2ade7000 {
> +			compatible = "rockchip,rk3576-pwm";
> +			reg = <0x0 0x2ade7000 0x0 0x1000>;
> +			clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>,
> +				 <&cru CLK_OSC_PWM2>, <&cru CLK_RC_PWM2>;
> +			clock-names = "pwm", "pclk", "osc", "rc";
> +			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pwm2m0_ch7>;
> +			#pwm-cells = <3>;
> +			status = "disabled";
> +		};
> +
>   		saradc: adc@2ae00000 {
>   			compatible = "rockchip,rk3576-saradc", "rockchip,rk3588-saradc";
>   			reg = <0x0 0x2ae00000 0x0 0x10000>;
> 

According to the RK3576 TRM, the register base address, clocks and 
interrupt configuration of the PWM node are all correct

Reviewed-by: Damon Ding <damon.ding@rock-chips.com>

Best regards,
Damon



^ permalink raw reply


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