* Re: [PATCH 2/7] dt-bindings: watchdog: mediatek,mtk-wdt: add compatibles for all SoCs
From: Krzysztof Kozlowski @ 2026-07-17 9:16 UTC (permalink / raw)
To: Akari Tsuyukusa
Cc: Wim Van Sebroeck, Guenter Roeck, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Philipp Zabel, open list:WATCHDOG DEVICE DRIVERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support, Roman Vivchar
In-Reply-To: <20260716161923.266315-3-akkun11.open@gmail.com>
On Fri, Jul 17, 2026 at 01:19:18AM +0900, Akari Tsuyukusa wrote:
> The driver recognizes each SoC-specific compatible, update the binding
> to list them in the top-level enum alongside the existing ones. Keep
> the fallback items definition so that old DTS continue to validate.
>
> Affected SoCs: mt2701, mt6572, mt6582, mt6797, mt7622, mt7623,
> mt7629, mt8173, mt8189, mt8365, mt8516.
I do not understand what and why you are doing. Just because driver
recognizes some compatible is not a reason to move compatibles around.
This completely lacks explanation (in terms of DTS, see writing
bindings).
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 2/2] arm64: dts: rockchip: Add Vicharak Vaaman board
From: Krzysztof Kozlowski @ 2026-07-17 9:13 UTC (permalink / raw)
To: Hrushiraj Gandhi
Cc: Heiko Stuebner, devicetree, linux-arm-kernel, linux-rockchip,
linux-kernel, Rob Herring, Krzysztof Kozlowski, Conor Dooley
In-Reply-To: <20260716092859.512306-3-hrushirajg23@gmail.com>
On Thu, Jul 16, 2026 at 02:58:59PM +0530, Hrushiraj Gandhi wrote:
> Add initial devicetree support for the Vicharak Vaaman, an RK3399-based
> single-board computer.
>
> Supported peripherals:
> - RK808 PMIC with core/logic/IO regulators
> - SYR827/SYR828 (vdd_cpu_b/vdd_gpu) CPU-big and GPU regulators
> - Mali GPU
> - Gigabit Ethernet (RGMII, via &gmac)
> - eMMC (HS400, enhanced strobe)
> - microSD card slot
> - SARADC and TSADC
> - PWM-based vdd_log regulator
> - UART2 serial console
>
> Tested by booting to a userspace shell over the serial console and
> verifying eMMC and microSD storage, and Ethernet link-up.
>
> Signed-off-by: Hrushiraj Gandhi <hrushirajg23@gmail.com>
> ---
> arch/arm64/boot/dts/rockchip/Makefile | 1 +
> .../dts/rockchip/rk3399-vicharak-vaaman.dts | 438 ++++++++++++++++++
> 2 files changed, 439 insertions(+)
> create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-vicharak-vaaman.dts
>
> diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
> index 761d82b4f4f2..e1b974502915 100644
> --- a/arch/arm64/boot/dts/rockchip/Makefile
> +++ b/arch/arm64/boot/dts/rockchip/Makefile
> @@ -90,6 +90,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb
> dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64-screen.dtbo
> dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb
> dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-vicharak-vaaman.dtb
> dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb
> dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3528-armsom-sige1.dtb
> dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3528-nanopi-zero2.dtb
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-vicharak-vaaman.dts b/arch/arm64/boot/dts/rockchip/rk3399-vicharak-vaaman.dts
> new file mode 100644
> index 000000000000..6060365bf731
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-vicharak-vaaman.dts
> @@ -0,0 +1,438 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2026 Vicharak Computers Pvt Ltd
> + */
> +
> +/dts-v1/;
> +#include "rk3399.dtsi"
> +
> +/ {
> + model = "Vicharak Vaaman";
> + compatible = "vicharak,vaaman", "rockchip,rk3399";
> +
> + aliases {
> + ethernet0 = &gmac;
> + mmc0 = &sdhci;
> + mmc1 = &sdmmc;
> + };
> +
> + chosen {
> + stdout-path = "serial2:1500000n8";
> + };
> +
> + clkin_gmac: external-gmac-clock {
> + compatible = "fixed-clock";
> + clock-frequency = <125000000>;
> + clock-output-names = "clkin_gmac";
> + #clock-cells = <0>;
> + };
> +
> + vcc12v_dcin: vcc12v-dcin-regulator {
foo-regulator yes?
> + compatible = "regulator-fixed";
> + regulator-name = "vcc12v_dcin";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <12000000>;
> + regulator-max-microvolt = <12000000>;
> + };
This regulator is completely unused (other non-controllable do not
matter).
> +
> + vcc3v3_lan: regulator-vcc3v3-lan {
so why here regulator-foo? Decide.
Please use name for all fixed regulators which matches current format
recommendation: 'regulator-[0-9]v[0-9]'
https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: arm: rockchip: Add Vicharak Vaaman board
From: Krzysztof Kozlowski @ 2026-07-17 9:12 UTC (permalink / raw)
To: Hrushiraj Gandhi
Cc: Heiko Stuebner, devicetree, linux-arm-kernel, linux-rockchip,
linux-kernel, Rob Herring, Krzysztof Kozlowski, Conor Dooley
In-Reply-To: <20260716092859.512306-2-hrushirajg23@gmail.com>
On Thu, Jul 16, 2026 at 02:58:58PM +0530, Hrushiraj Gandhi wrote:
> Document the compatible string for the Vicharak Vaaman, an RK3399-based
> single-board computer.
>
> Signed-off-by: Hrushiraj Gandhi <hrushirajg23@gmail.com>
> ---
> Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++
> 1 file changed, 5 insertions(+)
>
Nothing in cover letter or this changelog explains dependencies and I am
pretty sure this fails tests.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [RFC PATCH 4/9] iommu/rockchip: skip orphaned-fault banks in rk_iommu_is_stall_active
From: sashiko-bot @ 2026-07-17 9:11 UTC (permalink / raw)
To: Jiaxing Hu; +Cc: devicetree, dri-devel, conor+dt, robh
In-Reply-To: <20260717085220.3212274-5-gahing@gahingwoo.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Medium] Skipping orphaned-fault banks in `rk_iommu_is_stall_active` causes `rk_iommu_disable_stall` to unconditionally time out if all banks are skipped (e.g., on a single-bank IOMMU).
Pre-existing issues:
- [High] Multi-bank disable operations (`rk_iommu_disable_stall` and `rk_iommu_disable_paging`) prematurely terminate their waits as soon as the first bank completes its operation.
--
--- Patch [4]: [RFC PATCH 4/9] iommu/rockchip: skip orphaned-fault banks in rk_iommu_is_stall_active ---
commit 0709b1254bd6d532239176eba388c28b0ed8ea3c
Author: Jiaxing Hu <gahing@gahingwoo.com>
iommu/rockchip: skip orphaned-fault banks in rk_iommu_is_stall_active
This commit updates rk_iommu_is_stall_active() to detect and skip
orphaned-fault IOMMU banks that were left in a faulted state by boot
firmware. This ensures the driver doesn't treat them as "not stalled"
which would otherwise cause stall wait loops to fail.
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index 87ae036d64145..ad462cee6bd89 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
> @@ -380,9 +380,23 @@ static bool rk_iommu_is_stall_active(struct rk_iommu *iommu)
> bool active = true;
> int i;
>
> - for (i = 0; i < iommu->num_mmu; i++)
> - active &= !!(rk_iommu_read(iommu->bases[i], RK_MMU_STATUS) &
> - RK_MMU_STATUS_STALL_ACTIVE);
> + for (i = 0; i < iommu->num_mmu; i++) {
> + u32 status = rk_iommu_read(iommu->bases[i], RK_MMU_STATUS);
> +
> + /*
> + * A bank stuck with PAGE_FAULT_ACTIVE but without STALL_ACTIVE
> + * and with IDLE set has an orphaned fault left by firmware before
> + * paging was configured. It cannot enter stall mode but has no
> + * transaction in flight, so it is already quiescent. Skip it
> + * rather than treating it as "not stalled."
> + */
> + if ((status & RK_MMU_STATUS_PAGE_FAULT_ACTIVE) &&
> + !(status & RK_MMU_STATUS_STALL_ACTIVE) &&
> + (status & RK_MMU_STATUS_IDLE))
> + continue;
[Severity: Medium]
Does skipping banks here cause a timeout if all banks are skipped?
If an IOMMU has a single bank (num_mmu == 1) and encounters this orphaned
fault, the loop skips the only bank and the active variable remains true.
When rk_iommu_disable_stall() polls for the stall to complete:
ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
!val, RK_MMU_POLL_PERIOD_US,
RK_MMU_POLL_TIMEOUT_US);
It expects rk_iommu_is_stall_active() to return false, but it will return
true, causing an unconditional timeout and a spurious error log.
> +
> + active &= !!(status & RK_MMU_STATUS_STALL_ACTIVE);
[Severity: High]
This is a pre-existing issue, but does this bitwise AND reduction cause
multi-bank disable operations to terminate their waits prematurely?
When disabling an IOMMU with multiple banks (num_mmu > 1), returning false
as soon as the first bank drops its STALL_ACTIVE status leaves subsequent
banks still active.
The same logic exists in rk_iommu_is_paging_enabled(), where the bitwise
AND causes readx_poll_timeout() to terminate its wait as soon as one bank
is disabled, rather than waiting for all banks:
for (i = 0; i < iommu->num_mmu; i++)
enable &= !!(rk_iommu_read(iommu->bases[i], RK_MMU_STATUS) &
RK_MMU_STATUS_PAGING_ENABLED);
Can this lead to modifying register state or disabling hardware clocks while
some MMU banks are still actively processing commands?
> + }
>
> return active;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260717085220.3212274-1-gahing@gahingwoo.com?part=4
^ permalink raw reply
* Re: [PATCH 1/4] regulator: dt-bindings: Add Silergy SYR82X allowed modes
From: Krzysztof Kozlowski @ 2026-07-17 9:08 UTC (permalink / raw)
To: Victor Krawiec
Cc: lgirdwood, broonie, robh, krzk+dt, conor+dt, linux-kernel,
devicetree
In-Reply-To: <20260715155141.128601-2-victor.krawiec@arturia.com>
On Wed, Jul 15, 2026 at 05:51:38PM +0200, Victor Krawiec wrote:
> Make the PWM mode configurable from devicetree. Some boards require forced
> PWM mode to keep the supply ripple within acceptable limits under light
> load conditions
>
> Indexes are starting from 1 to keep backward compatibility with existing
> device trees
>
> Signed-off-by: Victor Krawiec <victor.krawiec@arturia.com>
> ---
> .../dt-bindings/regulator/silergy,syr82x.h | 20 +++++++++++++++++++
> 1 file changed, 20 insertions(+)
> create mode 100644 include/dt-bindings/regulator/silergy,syr82x.h
>
This header should be mentioned in the binding in property description.
> diff --git a/include/dt-bindings/regulator/silergy,syr82x.h b/include/dt-bindings/regulator/silergy,syr82x.h
> new file mode 100644
> index 000000000000..6d4aa86bb5c1
> --- /dev/null
> +++ b/include/dt-bindings/regulator/silergy,syr82x.h
Some confusing name. How is your binding file called? This must be the
same.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v3 3/4] mfd: axp20x: constify axp313 and axp717 cells
From: sashiko-bot @ 2026-07-17 9:08 UTC (permalink / raw)
To: Jerome Brunet; +Cc: conor+dt, robh, devicetree
In-Reply-To: <20260717-axp318-regulator-v3-3-779dc1b97dd4@baylibre.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The commit message description is not capitalized, violating the MFD subsystem convention.
--
--- Patch [3]: [PATCH v3 3/4] mfd: axp20x: constify axp313 and axp717 cells ---
commit fa2a5821d61bb79ab715c28d8480fa7cf50eb9a0
Author: Jerome Brunet <jbrunet@baylibre.com>
mfd: axp20x: constify axp313 and axp717 cells
This commit constifies the mfd_cells arrays for the axp313 and axp717 chips
to match other supported devices.
> mfd: axp20x: constify axp313 and axp717 cells
[Severity: Low]
This isn't a bug, but the MFD subsystem guidelines request that the
description following the subsystem prefix be capitalized. Should this be
updated to "Constify axp313 and axp717 cells" to match the standard subsystem
naming conventions?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260717-axp318-regulator-v3-0-779dc1b97dd4@baylibre.com?part=3
^ permalink raw reply
* Re: [RFC PATCH 2/9] pmdomain/rockchip: add optional per-domain power-on settle delay
From: sashiko-bot @ 2026-07-17 9:07 UTC (permalink / raw)
To: Jiaxing Hu; +Cc: devicetree, dri-devel, robh, conor+dt
In-Reply-To: <20260717085220.3212274-3-gahing@gahingwoo.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Uninitialized State Overwrite in QoS registers on first power-on
--
--- Patch [2]: [RFC PATCH 2/9] pmdomain/rockchip: add optional per-domain power-on settle delay ---
commit a8d7f648552a5a45a8073245f6be06268bc14e7d
Author: Jiaxing Hu <gahing@gahingwoo.com>
pmdomain/rockchip: add optional per-domain power-on settle delay
This commit introduces a per-domain settle delay for the RK3576 NPU domains.
The delay is applied between releasing the idle request and writing to the
QoS registers to prevent an SError while the NoC is settling.
> diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
> --- a/drivers/pmdomain/rockchip/pm-domains.c
> +++ b/drivers/pmdomain/rockchip/pm-domains.c
[ ... ]
> @@ -667,6 +668,9 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
> if (ret < 0)
> goto out;
>
> + if (pd->info->delay_us)
> + udelay(pd->info->delay_us);
> +
> rockchip_pmu_restore_qos(pd);
[Severity: High]
This is a pre-existing issue, but does this unconditional restore overwrite
QoS registers with uninitialized state on the very first power-on?
If a power domain is initially OFF at boot, qos_save_regs remains
zero-initialized by devm_kcalloc(). On the first power-on request,
rockchip_pd_power() unconditionally calls rockchip_pmu_restore_qos(),
which writes these zeros directly to the hardware:
drivers/pmdomain/rockchip/pm-domains.c:rockchip_pmu_restore_qos() {
...
regmap_write(pd->qos_regmap[i], QOS_PRIORITY, pd->qos_save_regs[0][i]);
...
}
If the hardware reset defaults for QoS bandwidth or priority are non-zero,
writing zeros could throttle or block interconnect traffic, potentially causing
the associated IP block to hang when accessing memory.
Is there a mechanism to ensure the QoS state is actually populated before it
is restored, or should the driver avoid restoring QoS state if a prior state
was never saved?
> }
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260717085220.3212274-1-gahing@gahingwoo.com?part=2
^ permalink raw reply
* Re: [PATCH net-next v2 1/2] dt-bindings: net: Add Maxio MAE0621A PHY
From: Krzysztof Kozlowski @ 2026-07-17 9:05 UTC (permalink / raw)
To: Liu Changjie
Cc: Andrew Lunn, Heiner Kallweit, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, netdev, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Luo Jie, Wolfram Sang,
devicetree, linux-kernel
In-Reply-To: <MN0PR19MB6091F865EF7FE6AC1EE41C10ACC62@MN0PR19MB6091.namprd19.prod.outlook.com>
On Fri, Jul 17, 2026 at 11:44:03AM +0800, Liu Changjie wrote:
> Document the MAE0621A PHY ID and its optional 125 MHz CLKOUT
> setting. Boards which do not provide the property retain the hardware
> strap or bootloader configuration.
>
> Only the 125 MHz setting is exposed because it is the only setting
> exercised on hardware.
>
> Signed-off-by: Liu Changjie <liucj1228@outlook.com>
> ---
How did you address previous feedback?
If you ignore feedback, shall we ignore the patch?
Best regards,
Krzysztof
^ permalink raw reply
* Re: [RFC PATCH 3/9] pmdomain/rockchip: cycle optional power-domain resets on power-on
From: sashiko-bot @ 2026-07-17 9:04 UTC (permalink / raw)
To: Jiaxing Hu; +Cc: robh, conor+dt, dri-devel, devicetree
In-Reply-To: <20260717085220.3212274-4-gahing@gahingwoo.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Missing `reset_control_put()` in `rockchip_pm_remove_one_domain()` leaks reset controls on probe failure.
--
--- Patch [3]: [RFC PATCH 3/9] pmdomain/rockchip: cycle optional power-domain resets on power-on ---
commit dbabfedb9da6564f3dfbd42512d2a456cfb08c18
Author: Jiaxing Hu <gahing@gahingwoo.com>
pmdomain/rockchip: cycle optional power-domain resets on power-on
This commit adds optional reset line handling to the Rockchip power domain
driver. It explicitly asserts and deasserts the reset lines during domain
power-on to ensure hardware bus interfaces are correctly initialized.
> diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
> --- a/drivers/pmdomain/rockchip/pm-domains.c
> +++ b/drivers/pmdomain/rockchip/pm-domains.c
[ ... ]
> @@ -840,6 +848,14 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
> if (error)
> goto err_put_clocks;
>
> + pd->resets = of_reset_control_array_get_optional_exclusive(node);
> + if (IS_ERR(pd->resets)) {
> + error = PTR_ERR(pd->resets);
> + dev_err(pmu->dev, "%pOFn: failed to get resets: %d\n", node, error);
> + pd->resets = NULL;
> + goto err_unprepare_clocks;
> + }
> +
[Severity: Medium]
Since pd->resets is acquired here using a non-managed function, does it need
to be released in rockchip_pm_remove_one_domain()?
If a subsequent domain fails to probe, the error path tears down all
successfully added domains via rockchip_pm_remove_one_domain(). It looks like
that function destroys the domain and releases its clocks, but might miss
cleaning up these reset controls:
static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
{
...
clk_bulk_unprepare(pd->num_clks, pd->clks);
clk_bulk_put(pd->num_clks, pd->clks);
/* pd->resets does not appear to be freed here */
...
}
Would calling reset_control_put(pd->resets) in the removal path prevent a
resource leak here?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260717085220.3212274-1-gahing@gahingwoo.com?part=3
^ permalink raw reply
* Re: [PATCH v3 2/8] firmware: smccc: Add support for Live Firmware Activation (LFA)
From: Sudeep Holla @ 2026-07-17 9:03 UTC (permalink / raw)
To: Andre Przywara
Cc: Mark Rutland, Lorenzo Pieralisi, Sudeep Holla, Salman Nabi,
Vedashree Vidwans, Trilok Soni, Nirmoy Das, vsethi, Varun Wadekar,
linux-arm-kernel, linux-kernel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, devicetree
In-Reply-To: <20260706134455.132091-3-andre.przywara@arm.com>
On Mon, Jul 06, 2026 at 03:44:42PM +0200, Andre Przywara wrote:
> From: Salman Nabi <salman.nabi@arm.com>
>
> The Arm Live Firmware Activation (LFA) is a specification [1] to describe
> activating firmware components without a reboot. Those components
> (like TF-A's BL31, EDK-II, TF-RMM, secure paylods) would be updated the
> usual way: via fwupd, FF-A or other secure storage methods, or via some
> IMPDEF Out-Of-Bound method. The user can then activate this new firmware,
> at system runtime, without requiring a reboot.
> The specification covers the SMCCC interface to list and query available
> components and eventually trigger the activation.
>
> Add a new directory under /sys/firmware to present firmware components
> capable of live activation. Each of them is a directory under lfa/,
> and is identified via its GUID. The activation will be triggered by echoing
> "1" into the "activate" file:
> ==========================================
> /sys/firmware/lfa # ls -l . 6c*
> .:
> total 0
> drwxr-xr-x 2 0 0 0 Jan 19 11:33 47d4086d-4cfe-9846-9b95-2950cbbd5a00
> drwxr-xr-x 2 0 0 0 Jan 19 11:33 6c0762a6-12f2-4b56-92cb-ba8f633606d9
> drwxr-xr-x 2 0 0 0 Jan 19 11:33 d6d0eea7-fcea-d54b-9782-9934f234b6e4
>
> 6c0762a6-12f2-4b56-92cb-ba8f633606d9:
> total 0
> --w------- 1 0 0 4096 Jan 19 11:33 activate
> -r--r--r-- 1 0 0 4096 Jan 19 11:33 activation_capable
> -r--r--r-- 1 0 0 4096 Jan 19 11:33 activation_pending
> --w------- 1 0 0 4096 Jan 19 11:33 cancel
> -r--r--r-- 1 0 0 4096 Jan 19 11:33 cpu_rendezvous
> -r--r--r-- 1 0 0 4096 Jan 19 11:33 current_version
> -rw-r--r-- 1 0 0 4096 Jan 19 11:33 force_cpu_rendezvous
> -r--r--r-- 1 0 0 4096 Jan 19 11:33 may_reset_cpu
> -r--r--r-- 1 0 0 4096 Jan 19 11:33 name
> -r--r--r-- 1 0 0 4096 Jan 19 11:33 pending_version
> /sys/firmware/lfa/6c0762a6-12f2-4b56-92cb-ba8f633606d9 # grep . *
> grep: activate: Permission denied
> activation_capable:1
> activation_pending:1
> grep: cancel: Permission denied
> cpu_rendezvous:1
> current_version:0.0
> force_cpu_rendezvous:1
> may_reset_cpu:0
> name:TF-RMM
> pending_version:0.0
> /sys/firmware/lfa/6c0762a6-12f2-4b56-92cb-ba8f633606d9 # echo 1 > activate
> [ 2825.797871] Arm LFA: firmware activation succeeded.
> /sys/firmware/lfa/6c0762a6-12f2-4b56-92cb-ba8f633606d9 #
> ==========================================
>
> [1] https://developer.arm.com/documentation/den0147/latest/
>
> Signed-off-by: Salman Nabi <salman.nabi@arm.com>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
> drivers/firmware/smccc/Kconfig | 10 +
> drivers/firmware/smccc/Makefile | 1 +
> drivers/firmware/smccc/lfa_fw.c | 725 ++++++++++++++++++++++++++++++++
> drivers/firmware/smccc/smccc.c | 5 +
> include/linux/arm-smccc.h | 15 +
> 5 files changed, 756 insertions(+)
> create mode 100644 drivers/firmware/smccc/lfa_fw.c
>
> diff --git a/drivers/firmware/smccc/Kconfig b/drivers/firmware/smccc/Kconfig
> index 15e7466179a6..7fd646d515f8 100644
> --- a/drivers/firmware/smccc/Kconfig
> +++ b/drivers/firmware/smccc/Kconfig
> @@ -23,3 +23,13 @@ config ARM_SMCCC_SOC_ID
> help
> Include support for the SoC bus on the ARM SMCCC firmware based
> platforms providing some sysfs information about the SoC variant.
> +
> +config ARM_LFA
> + tristate "Arm Live Firmware activation support"
> + depends on HAVE_ARM_SMCCC_DISCOVERY && ARM64
> + default y
> + help
> + Include support for triggering a Live Firmware Activation (LFA),
> + which allows to upgrade certain firmware components without a reboot.
> + This is described in the Arm DEN0147 specification, and relies on
> + a firmware agent running in EL3.
> diff --git a/drivers/firmware/smccc/Makefile b/drivers/firmware/smccc/Makefile
> index 68bbff1407b8..cddf2c460ab9 100644
> --- a/drivers/firmware/smccc/Makefile
> +++ b/drivers/firmware/smccc/Makefile
> @@ -2,3 +2,4 @@
> #
> obj-$(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) += bus.o smccc.o kvm_guest.o
> obj-$(CONFIG_ARM_SMCCC_SOC_ID) += soc_id.o
> +obj-$(CONFIG_ARM_LFA) += lfa_fw.o
> diff --git a/drivers/firmware/smccc/lfa_fw.c b/drivers/firmware/smccc/lfa_fw.c
> new file mode 100644
> index 000000000000..b333b1e28c0d
> --- /dev/null
> +++ b/drivers/firmware/smccc/lfa_fw.c
> @@ -0,0 +1,725 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2025 Arm Limited
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/arm-smccc-bus.h>
> +#include <linux/array_size.h>
> +#include <linux/fs.h>
> +#include <linux/init.h>
> +#include <linux/kobject.h>
> +#include <linux/list.h>
> +#include <linux/module.h>
> +#include <linux/psci.h>
> +#include <linux/stop_machine.h>
> +#include <linux/string.h>
> +#include <linux/sysfs.h>
> +#include <linux/uuid.h>
> +#include <linux/workqueue.h>
> +
> +#include <uapi/linux/psci.h>
> +
> +#undef pr_fmt
> +#define pr_fmt(fmt) "Arm LFA: " fmt
> +
> +/* CALL_AGAIN flags (returned by SMC) */
> +#define LFA_PRIME_CALL_AGAIN BIT(0)
> +#define LFA_ACTIVATE_CALL_AGAIN BIT(0)
> +
> +/* LFA return values */
> +#define LFA_SUCCESS 0
> +#define LFA_NOT_SUPPORTED 1
> +#define LFA_BUSY 2
> +#define LFA_AUTH_ERROR 3
> +#define LFA_NO_MEMORY 4
> +#define LFA_CRITICAL_ERROR 5
> +#define LFA_DEVICE_ERROR 6
> +#define LFA_WRONG_STATE 7
> +#define LFA_INVALID_PARAMETERS 8
> +#define LFA_COMPONENT_WRONG_STATE 9
> +#define LFA_INVALID_ADDRESS 10
> +#define LFA_ACTIVATION_FAILED 11
> +
> +/*
> + * Not error codes described by the spec, but used internally when
> + * PRIME/ACTIVATE calls return with the CALL_AGAIN bit set.
> + */
> +#define LFA_TIMED_OUT 32
> +#define LFA_CALL_AGAIN 33
> +
Why do you need this if it is purely internal in the driver ?
What is the guarantee that LFA spec doesn't use these in the future ?
It shouldn't be big problem, but I do expect things may get bit complicated
during transition to a firmware version may start using it.
> +#define LFA_ERROR_STRING(name) \
> + [name] = #name
> +
> +static const char * const lfa_error_strings[] = {
> + LFA_ERROR_STRING(LFA_SUCCESS),
> + LFA_ERROR_STRING(LFA_NOT_SUPPORTED),
> + LFA_ERROR_STRING(LFA_BUSY),
> + LFA_ERROR_STRING(LFA_AUTH_ERROR),
> + LFA_ERROR_STRING(LFA_NO_MEMORY),
> + LFA_ERROR_STRING(LFA_CRITICAL_ERROR),
> + LFA_ERROR_STRING(LFA_DEVICE_ERROR),
> + LFA_ERROR_STRING(LFA_WRONG_STATE),
> + LFA_ERROR_STRING(LFA_INVALID_PARAMETERS),
> + LFA_ERROR_STRING(LFA_COMPONENT_WRONG_STATE),
> + LFA_ERROR_STRING(LFA_INVALID_ADDRESS),
> + LFA_ERROR_STRING(LFA_ACTIVATION_FAILED)
> +};
> +
> +enum image_attr_names {
> + LFA_ATTR_NAME,
> + LFA_ATTR_CURRENT_VERSION,
> + LFA_ATTR_PENDING_VERSION,
> + LFA_ATTR_ACT_CAPABLE,
> + LFA_ATTR_ACT_PENDING,
> + LFA_ATTR_MAY_RESET_CPU,
> + LFA_ATTR_CPU_RENDEZVOUS,
> + LFA_ATTR_FORCE_CPU_RENDEZVOUS,
> + LFA_ATTR_ACTIVATE,
> + LFA_ATTR_CANCEL,
> + LFA_ATTR_NR_IMAGES
> +};
> +
> +struct fw_image {
> + struct kobject kobj;
> + const char *image_name;
> + int fw_seq_id;
> + u64 current_version;
> + u64 pending_version;
> + bool activation_capable;
> + bool activation_pending;
> + bool may_reset_cpu;
> + bool cpu_rendezvous;
> + bool cpu_rendezvous_forced;
> + struct kobj_attribute image_attrs[LFA_ATTR_NR_IMAGES];
> +};
> +
> +static struct fw_image *kobj_to_fw_image(struct kobject *kobj)
> +{
> + return container_of(kobj, struct fw_image, kobj);
> +}
> +
> +/* A UUID split over two 64-bit registers */
> +struct uuid_regs {
> + u64 uuid_lo;
> + u64 uuid_hi;
> +};
> +
> +/* A list of known GUIDs, to be shown in the "name" sysfs file. */
> +static const struct fw_image_uuid {
> + const char *name;
> + const char *uuid;
> +} fw_images_uuids[] = {
> + {
> + .name = "TF-A BL31 runtime",
This doesn't make any sense to me. Why do you want kernel to assign
some random name base on UUID. Userspace is well place to deal with
UUID and give it any fancy name it wants.
[...]
> diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
> index 4de81848fe2e..956a5af96c70 100644
> --- a/include/linux/arm-smccc.h
> +++ b/include/linux/arm-smccc.h
> @@ -304,6 +304,21 @@
> ARM_SMCCC_OWNER_STANDARD, \
> 0x53)
>
> +/* Live Firmware Activation (LFA) calls (defined by ARM DEN0147) */
> +#define ARM_SMCCC_LFA_FN_BASE \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
> + ARM_SMCCC_SMC_64, \
> + ARM_SMCCC_OWNER_STANDARD, \
> + 0x2e0)
> +#define ARM_SMCCC_LFA_FN(n) (ARM_SMCCC_LFA_FN_BASE + (n))
> +#define ARM_SMCCC_LFA_GET_VERSION ARM_SMCCC_LFA_FN(0)
> +#define ARM_SMCCC_LFA_CHECK_FEATURE ARM_SMCCC_LFA_FN(1)
> +#define ARM_SMCCC_LFA_GET_INFO ARM_SMCCC_LFA_FN(2)
> +#define ARM_SMCCC_LFA_GET_INVENTORY ARM_SMCCC_LFA_FN(3)
> +#define ARM_SMCCC_LFA_PRIME ARM_SMCCC_LFA_FN(4)
> +#define ARM_SMCCC_LFA_ACTIVATE ARM_SMCCC_LFA_FN(5)
> +#define ARM_SMCCC_LFA_CANCEL ARM_SMCCC_LFA_FN(6)
> +
Do you expect these to be used outside of the driver(for now atleast) ?
If not move it into the driver.
> /*
> * Return codes defined in ARM DEN 0070A
> * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
> --
> 2.43.0
>
>
--
Regards,
Sudeep
^ permalink raw reply
* Re: [PATCH V17 4/9] iio: imu: inv_icm42607: Add SPI For icm42607
From: Uwe Kleine-König @ 2026-07-17 9:03 UTC (permalink / raw)
To: Chris Morgan
Cc: linux-iio, andy, nuno.sa, dlechner, jic23, jean-baptiste.maneyrol,
linux-rockchip, devicetree, heiko, conor+dt, krzk+dt, robh,
andriy.shevchenko, Chris Morgan
In-Reply-To: <20260716182637.24310-5-macroalpha82@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 452 bytes --]
Hello Chris,
On Thu, Jul 16, 2026 at 01:26:31PM -0500, Chris Morgan wrote:
> +#include <linux/mod_devicetable.h>
> [...]
> +#include <linux/spi/spi.h>
Please don't add an include for <linux/mod_devicetable.h>, I'm working
on removing that header. The two device-id structures you need
(of_device_id and spi_device_id) are already provided by
<linux/spi/spi.h>, so you can just remove the include line for
<linux/mod_devicetable.h>.
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v2 3/3] ASoC: Add LPASS VA CSR heartbeat pulse clock
From: Krzysztof Kozlowski @ 2026-07-17 9:02 UTC (permalink / raw)
To: Sarath Ganapathiraju
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
Srinivas Kandagatla, linux-sound, linux-arm-msm, devicetree,
linux-kernel, prasad.kumpatla, Konrad Dybcio
In-Reply-To: <20260717-master-v2-3-ae200627ad62@oss.qualcomm.com>
On Fri, Jul 17, 2026 at 01:21:17AM +0530, Sarath Ganapathiraju wrote:
> The HeartBeat Pulse (also known as RateGen Pulse) synchronizes the
> start of the DMAs and Codec Interfaces for the audio usecases
> and can serve as a periodic wakeup source for the DSP.
>
> Add the LPASS VA CSR driver that models the rate generator as a clock
> provider so it is enabled and disabled automatically alongside the
> other clocks during runtime PM resume and suspend.
>
> Signed-off-by: Sarath Ganapathiraju <sarath.ganapathiraju@oss.qualcomm.com>
> ---
> sound/soc/codecs/Kconfig | 13 ++++
> sound/soc/codecs/Makefile | 2 +
> sound/soc/codecs/lpass-va-csr.c | 143 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 158 insertions(+)
>
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 76e90144ea..5dbfa77d0e 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -2902,11 +2902,24 @@ config SND_SOC_LPASS_WSA_MACRO
> select SND_SOC_LPASS_MACRO_COMMON
> tristate "Qualcomm WSA Macro in LPASS(Low Power Audio SubSystem)"
>
> +config SND_SOC_LPASS_VA_CSR
> + depends on COMMON_CLK
> + select REGMAP_MMIO
> + tristate "Qualcomm LPASS VA CSR heartbeat pulse clock provider"
> + help
> + Qualcomm LPASS VA CSR block contains the rate generator hardware
> + that produces the HeartBeat Pulse (also known as RateGen Pulse).
> + This driver models the rate generator as a clock provider so
> + that consumers can enable or disable it via the common clock
> + framework, and it can be used to synchronize the start of DMAs
> + and Codec Interfaces or as a periodic wakeup source for the DSP.
> +
> config SND_SOC_LPASS_VA_MACRO
> depends on COMMON_CLK
> depends on PM_CLK
> select REGMAP_MMIO
> select SND_SOC_LPASS_MACRO_COMMON
> + select SND_SOC_LPASS_VA_CSR
> tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)"
>
> config SND_SOC_LPASS_RX_MACRO
> diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
> index aa0396e5b5..3e86c1bbf9 100644
> --- a/sound/soc/codecs/Makefile
> +++ b/sound/soc/codecs/Makefile
> @@ -163,6 +163,7 @@ snd-soc-lpass-rx-macro-y := lpass-rx-macro.o
> snd-soc-lpass-tx-macro-y := lpass-tx-macro.o
> snd-soc-lpass-wsa-macro-y := lpass-wsa-macro.o
> snd-soc-lpass-va-macro-y := lpass-va-macro.o
> +snd-soc-lpass-va-csr-y := lpass-va-csr.o
> snd-soc-madera-y := madera.o
> snd-soc-max9759-y := max9759.o
> snd-soc-max9768-y := max9768.o
> @@ -886,6 +887,7 @@ obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
> obj-$(CONFIG_SND_SOC_LPASS_MACRO_COMMON) += snd-soc-lpass-macro-common.o
> obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o
> obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o
> +obj-$(CONFIG_SND_SOC_LPASS_VA_CSR) += snd-soc-lpass-va-csr.o
> obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o
> obj-$(CONFIG_SND_SOC_LPASS_TX_MACRO) += snd-soc-lpass-tx-macro.o
>
> diff --git a/sound/soc/codecs/lpass-va-csr.c b/sound/soc/codecs/lpass-va-csr.c
> new file mode 100644
> index 0000000000..1d0805789e
> --- /dev/null
> +++ b/sound/soc/codecs/lpass-va-csr.c
> @@ -0,0 +1,143 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/of_clk.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
Why a clock provider driver, which has nothing to do with ASoC and uses
nothing from the ASoC, is placed in ASoC directory?
No, this is really wrong interpretation of Linux subsystems.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v3 2/4] mfd: axp20x: Add support for AXP318W PMIC
From: sashiko-bot @ 2026-07-17 9:02 UTC (permalink / raw)
To: Jerome Brunet; +Cc: conor+dt, devicetree, robh
In-Reply-To: <20260717-axp318-regulator-v3-2-779dc1b97dd4@baylibre.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] The newly added I2C device ID `axp318w` fails to use named initializers and omits the `.driver_data` field, resulting in it defaulting to `0` (`AXP152_ID`).
- [Medium] The MFD cell and resources for the power key (`axp20x-pek`) are completely omitted from `axp318_cells`, despite the commit message claiming to support it and IRQs being defined.
- [Low] The `axp318_cells` array uses a hard-coded ID of `1` for the regulator cell, which violates MFD subsystem guidelines and risks sysfs naming collisions.
--
--- Patch [2]: [PATCH v3 2/4] mfd: axp20x: Add support for AXP318W PMIC ---
commit c0a61d967fff87b52d26e4cb329e69e10684fb89
Author: Andre Przywara <andre.przywara@arm.com>
mfd: axp20x: Add support for AXP318W PMIC
This patch adds support for the AXP318W PMIC connected via I2C. It sets up
the regmap configurations, volatile ranges, interrupts, and registers the
MFD cells for the regulator devices.
> Describe the regmap and the MFD bits, along with the registers exposed
> via I2C only. This covers the regulator, interrupts and power key
> devices for now.
[Severity: Medium]
Is the power key device missing from the MFD cells array in this patch? The
commit message mentions it is covered, but there are no power key resources
or cells defined for the AXP318W.
> diff --git a/drivers/mfd/axp20x-i2c.c b/drivers/mfd/axp20x-i2c.c
> index 5c93136f977e7..4e4ebfc78525c 100644
> --- a/drivers/mfd/axp20x-i2c.c
> +++ b/drivers/mfd/axp20x-i2c.c
> @@ -83,6 +84,7 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
> { "axp221" },
> { "axp223" },
> { "axp313a" },
> + { "axp318w" },
[Severity: Medium]
Does this need named initializers to provide the .driver_data payload?
Without setting .driver_data like the of_device_id table does, won't this
default to 0, which is AXP152_ID? If this device is instantiated via legacy
I2C methods, device_get_match_data() might return AXP152_ID instead,
causing the driver to mistakenly configure it as an AXP152 variant.
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 679364189ea58..c8aeebd01bbcd 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
[ ... ]
> @@ -1061,6 +1129,10 @@ static struct mfd_cell axp313a_cells[] = {
> MFD_CELL_RES("axp313a-pek", axp313a_pek_resources),
> };
>
> +static const struct mfd_cell axp318_cells[] = {
> + MFD_CELL_BASIC("axp20x-regulator", NULL, NULL, 0, 1),
[Severity: Low]
Should this use PLATFORM_DEVID_AUTO instead of a hard-coded ID of 1?
Assigning a hardcoded ID can lead to device naming collisions in sysfs if
multiple instances of the device are present.
> +};
> +
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260717-axp318-regulator-v3-0-779dc1b97dd4@baylibre.com?part=2
^ permalink raw reply
* Re: [PATCH v2 2/3] ASoC: dt-bindings: qcom,lpass-va-macro: Add hawi heartbeatpulse clock
From: Krzysztof Kozlowski @ 2026-07-17 9:01 UTC (permalink / raw)
To: Sarath Ganapathiraju
Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
Srinivas Kandagatla, linux-sound, linux-arm-msm, devicetree,
linux-kernel, prasad.kumpatla, Konrad Dybcio
In-Reply-To: <20260717-master-v2-2-ae200627ad62@oss.qualcomm.com>
On Fri, Jul 17, 2026 at 01:21:16AM +0530, Sarath Ganapathiraju wrote:
> Extend the qcom,lpass-va-macro to add the qcom,hawi-lpass-va-macro
> compatible, which consumes an additional heartbeatpulse clock
> alongside its existing mclk, macro, and dcodec clocks, for a total
> four-clock constraint.
>
> Signed-off-by: Sarath Ganapathiraju <sarath.ganapathiraju@oss.qualcomm.com>
> ---
> .../devicetree/bindings/sound/qcom,lpass-va-macro.yaml | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
> index aea31fbdad..ae4df89678 100644
> --- a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
> +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
> @@ -19,6 +19,7 @@ properties:
> - qcom,sm8450-lpass-va-macro
> - qcom,sm8550-lpass-va-macro
> - qcom,sc8280xp-lpass-va-macro
> + - qcom,hawi-lpass-va-macro
Put this as first entry, trying to keep alphanumerical sort.
Anyway, where is any user of this? Please carefully read submitting
patches (both documents) since this breaks its rules.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 3/3] iio: dac: ad5710r: Add driver for AD5710R and AD5711R
From: Uwe Kleine-König @ 2026-07-17 9:01 UTC (permalink / raw)
To: Kim Seer Paller
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, linux-iio, linux-kernel, linux, devicetree
In-Reply-To: <20260716-iio-ad5710r-upstream-v1-3-e848a4bb701f@analog.com>
[-- Attachment #1: Type: text/plain, Size: 347 bytes --]
Hello,
On Thu, Jul 16, 2026 at 03:59:27PM +0800, Kim Seer Paller wrote:
> +#include <linux/mod_devicetable.h>
> [...]
> +#include <linux/spi/spi.h>
Please don't add <linux/mod_devicetable.h> to the list of includes. I'm
working on getting rid of that and all the *_device_id you need are
already provided by <linux/spi/spi.h>.
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v2 1/3] ASoC: dt-bindings: qcom,lpass-va-csr: Add HeartBeat pulse clock
From: Krzysztof Kozlowski @ 2026-07-17 9:00 UTC (permalink / raw)
To: sarath.ganapathiraju, Srinivas Kandagatla, Liam Girdwood,
Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jaroslav Kysela, Takashi Iwai
Cc: Srinivas Kandagatla, linux-sound, linux-arm-msm, devicetree,
linux-kernel, prasad.kumpatla, Konrad Dybcio
In-Reply-To: <20260717-master-v2-1-ae200627ad62@oss.qualcomm.com>
On 16/07/2026 21:51, Sarath Ganapathiraju via B4 Relay wrote:
> From: Sarath Ganapathiraju <sarath.ganapathiraju@oss.qualcomm.com>
>
> Add Qualcomm LPASS VA CSR rate generator node that exposes
> the lpass_heartbeat_pulse clock on hawi.
>
> The HeartBeat Pulse (also known as RateGen Pulse) synchronizes the
> start of the DMAs and Codec Interfaces for the audio usecase
> and can serve as a periodic wakeup source for the DSP.
>
> Signed-off-by: Sarath Ganapathiraju <sarath.ganapathiraju@oss.qualcomm.com>
> ---
> .../bindings/sound/qcom,lpass-va-csr.yaml | 52 ++++++++++++++++++++++
> 1 file changed, 52 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-csr.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-csr.yaml
> new file mode 100644
> index 0000000000..131debb04f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-csr.yaml
> @@ -0,0 +1,52 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/qcom,lpass-va-csr.yaml#
I do not understand why a clock controller is part of sound. This makes
little sense and desription does not help me.
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm LPASS VA CSR heartbeat pulse clock provider
> +
> +maintainers:
> + - Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> + - Sarath Ganapathiraju <sarath.ganapathiraju@oss.qualcomm.com>
> +
> +description:
> + The LPASS VA CSR block contains the rate generator hardware which
> + produces the heartbeatpulse consumed by the Bolero codec macros
> + (rx, tx, wsa, va). It is modelled as a clock provider
> + so consumers can reference it by name in their clocks list.
Drop last syntax, explain the hardware, not duplicate schema as text.
> +
> +properties:
> + compatible:
> + enum:
> + - qcom,hawi-lpass-va-csr
> +
> + reg:
> + maxItems: 1
> + description: Must cover the full VA CSR block (base 0x7EE0000, size 0xE000).
Drop description, redundant. Why would not device MMIO address range
cover full block?
> +
> + "#clock-cells":
> + const: 0
> + description:
> + Single clock output "lpass_heartbeat_pulse". Consumers reference
> + it by clock-name "heartbeatpulse" in their clocks list.
Drop description. Not even accurate. Consumers reference it however they
wish and it is not any business of the provider.
From where did you take such style?
> +
> +required:
> + - compatible
> + - reg
> + - "#clock-cells"
> +
> +unevaluatedProperties: false
And this...
> +
> +examples:
> + - |
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + va-csr@7ee0000 {
Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
If you cannot find a name matching your device, please check in kernel
sources for similar cases or you can grow the spec (via pull request to
DT spec repo).
> + compatible = "qcom,hawi-lpass-va-csr";
> + reg = <0x0 0x07ee0000 0x0 0xe000>;
> + #clock-cells = <0>;
> + };
> + };
>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [RFC PATCH 1/9] dt-bindings: npu: rockchip: add rockchip,rk3576-rknn-core
From: sashiko-bot @ 2026-07-17 8:59 UTC (permalink / raw)
To: Jiaxing Hu; +Cc: dri-devel, robh, conor+dt, devicetree
In-Reply-To: <20260717085220.3212274-2-gahing@gahingwoo.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Removing `sram-supply` from the global `required` list makes it optional for `rockchip,rk3588-rknn-core`, incorrectly weakening schema validation for existing RK3588 hardware.
--
--- Patch [1]: [RFC PATCH 1/9] dt-bindings: npu: rockchip: add rockchip,rk3576-rknn-core ---
commit 9a2dabf1434398eb090f8e36b12d42467c86de03
Author: Jiaxing Hu <gahing@gahingwoo.com>
dt-bindings: npu: rockchip: add rockchip,rk3576-rknn-core
This commit documents the RK3576 NPU core by adding the new compatible
string rockchip,rk3576-rknn-core. It also drops sram-supply from the global
required list since the RK3576 has no NPU SRAM supply.
> diff --git a/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml b/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml
> index caca2a4903cd1..d904db3bf9281 100644
> --- a/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml
> +++ b/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml
[ ... ]
> @@ -75,7 +76,6 @@ required:
> - resets
> - reset-names
> - npu-supply
> - - sram-supply
[Severity: Medium]
By dropping sram-supply from the global required list to accommodate the
RK3576, does this incorrectly weaken schema validation for existing
RK3588 hardware?
If an RK3588 device tree node is missing the sram-supply property, it
appears it will now silently pass make dtbs_check validation.
Could this instead use an allOf block with an if-then conditional to
enforce the sram-supply requirement specifically when the compatible string
is rockchip,rk3588-rknn-core?
>
> additionalProperties: false
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260717085220.3212274-1-gahing@gahingwoo.com?part=1
^ permalink raw reply
* Re: (subset) [PATCH v3 0/8] arm64: Add Axiado AX3005 SoC and EVK support
From: Bartosz Golaszewski @ 2026-07-17 8:58 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Harshit Shah,
Linus Walleij, Bartosz Golaszewski, Jan Kotas, Michal Simek,
Andi Shyti, Przemysław Gaj, Alexandre Belloni, Frank Li,
Boris Brezillon, Greg Kroah-Hartman, Jiri Slaby, Mark Brown,
Mathias Nyman, Swark Yang
Cc: Bartosz Golaszewski, devicetree, linux-arm-kernel, linux-kernel,
linux-gpio, linux-i2c, linux-i3c, linux-serial, linux-spi,
linux-usb, Conor Dooley
In-Reply-To: <20260716-upstream-axiado-ax3005-upstream-v3-0-c429095143ec@axiado.com>
On Thu, 16 Jul 2026 20:51:07 -0700, Swark Yang wrote:
> This series adds initial device tree support for the Axiado AX3005 SoC
> and its evaluation board (EVK).
>
> The AX3005 uses Cadence-derived UART/I2C/I3C/GPIO and Synopsys
> DesignWare SPI IP blocks. These are already described by
> existing bindings, so the device tree reuses the "axiado,ax3000-*",
> "cdns,*" and "snps,*" compatible strings; only a new SoC/board
> level compatible is added.
>
> [...]
Applied, thanks!
[2/8] dt-bindings: gpio: cdns: add Axiado AX3005 GPIO variant
https://git.kernel.org/brgl/c/e8a40b3566887c1c83d4cb87058d4e98ec8b4a14
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* [RFC PATCH 9/9] arm64: dts: rockchip: rk3576-rock-4d: enable NPU
From: Jiaxing Hu @ 2026-07-17 8:50 UTC (permalink / raw)
To: tomeu, heiko, robh, krzk+dt, conor+dt, joro, will, robin.murphy,
ulfh, p.zabel, ogabbay
Cc: dri-devel, linux-rockchip, iommu, linux-pm, devicetree,
linux-arm-kernel, linux-kernel, Jiaxing Hu
In-Reply-To: <20260717085220.3212274-1-gahing@gahingwoo.com>
Enable rknn_core_0 and rknn_mmu_0 on the Radxa ROCK 4D. Supply the NPU
rail (vdd_npu_s0) via npu-supply; it is marked regulator-always-on for
now because the NPU power sequencing is still being brought up (see the
cover letter) -- happy to switch to proper runtime control once the
compute path is sorted.
Signed-off-by: Jiaxing Hu <gahing@gahingwoo.com>
---
arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
index 272af1012..09d2fc98b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
@@ -442,6 +442,7 @@ regulator-state-mem {
};
vdd_npu_s0: dcdc-reg2 {
+ regulator-always-on;
regulator-boot-on;
regulator-enable-ramp-delay = <400>;
regulator-min-microvolt = <550000>;
@@ -869,3 +870,18 @@ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
remote-endpoint = <&hdmi_in_vp0>;
};
};
+
+&rknn_core_0 {
+ npu-supply = <&vdd_npu_s0>;
+ /*
+ * Power BOTH NPU domains (NPU0 + NPU1) like the vendor's single NPU node,
+ * even though rocket computes only on core 0: the CBUF->CMAC read path is
+ * only fully powered with NPU1 up. rocket attaches the multi-PD list.
+ */
+ power-domains = <&power RK3576_PD_NPU0>, <&power RK3576_PD_NPU1>;
+ status = "okay";
+};
+
+&rknn_mmu_0 {
+ status = "okay";
+};
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 8/9] arm64: dts: rockchip: rk3576: add NPU (RKNN) nodes
From: Jiaxing Hu @ 2026-07-17 8:50 UTC (permalink / raw)
To: tomeu, heiko, robh, krzk+dt, conor+dt, joro, will, robin.murphy,
ulfh, p.zabel, ogabbay
Cc: dri-devel, linux-rockchip, iommu, linux-pm, devicetree,
linux-arm-kernel, linux-kernel, Jiaxing Hu
In-Reply-To: <20260717085220.3212274-1-gahing@gahingwoo.com>
Add the RK3576 NPU: rknn_core_0/1 and rknn_mmu_0/1, with register
addresses, GIC_SPI 247/248 interrupts, clocks, resets and power-domains.
Run the full RKNN clock set (CLK_RKNN_DSU0, ACLK_RKNN0/1, HCLK_RKNN_ROOT,
ACLK/HCLK_RKNN_CBUF) during the NPU0/NPU1 power transitions and on the
MMU nodes; without the functional and CBUF clocks the block powers on but
its registers (including the IOMMU banks) read back dead. Drive the RKNN
BIU reset (SRST_A_RKNN0/1_BIU) from the power domain so it fires before
the IOMMU resumes.
Signed-off-by: Jiaxing Hu <gahing@gahingwoo.com>
---
arch/arm64/boot/dts/rockchip/rk3576.dtsi | 78 +++++++++++++++++++++++-
1 file changed, 76 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index e12a2a0cf..5033f7628 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -1070,14 +1070,22 @@ power-domain@RK3576_PD_NPUTOP {
power-domain@RK3576_PD_NPU0 {
reg = <RK3576_PD_NPU0>;
clocks = <&cru HCLK_RKNN_ROOT>,
- <&cru ACLK_RKNN0>;
+ <&cru ACLK_RKNN0>,
+ <&cru CLK_RKNN_DSU0>,
+ <&cru ACLK_RKNN_CBUF>,
+ <&cru HCLK_RKNN_CBUF>;
+ resets = <&cru SRST_A_RKNN0_BIU>;
pm_qos = <&qos_npu_m0>;
#power-domain-cells = <0>;
};
power-domain@RK3576_PD_NPU1 {
reg = <RK3576_PD_NPU1>;
clocks = <&cru HCLK_RKNN_ROOT>,
- <&cru ACLK_RKNN1>;
+ <&cru ACLK_RKNN1>,
+ <&cru CLK_RKNN_DSU0>,
+ <&cru ACLK_RKNN_CBUF>,
+ <&cru HCLK_RKNN_CBUF>;
+ resets = <&cru SRST_A_RKNN1_BIU>;
pm_qos = <&qos_npu_m1>;
#power-domain-cells = <0>;
};
@@ -1804,6 +1812,72 @@ qos_npu_m1ro: qos@27f22100 {
reg = <0x0 0x27f22100 0x0 0x20>;
};
+ rknn_core_0: npu@27700000 {
+ compatible = "rockchip,rk3576-rknn-core";
+ reg = <0x0 0x27700000 0x0 0x1000>,
+ <0x0 0x27701000 0x0 0x1000>,
+ <0x0 0x27703000 0x0 0x1000>,
+ <0x0 0x27704000 0x0 0x1000>,
+ <0x0 0x27705000 0x0 0x1000>;
+ reg-names = "pc", "cna", "core", "dpu", "dpu_rdma";
+ interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_RKNN0>, <&cru HCLK_RKNN_ROOT>,
+ <&cru CLK_RKNN_DSU0>, <&cru PCLK_NPUTOP_ROOT>,
+ <&cru ACLK_RKNN_CBUF>, <&cru HCLK_RKNN_CBUF>;
+ clock-names = "aclk", "hclk", "npu", "pclk",
+ "aclk_cbuf", "hclk_cbuf";
+ resets = <&cru SRST_A_RKNN0>;
+ reset-names = "srst_a";
+ power-domains = <&power RK3576_PD_NPU0>;
+ iommus = <&rknn_mmu_0>;
+ status = "disabled";
+ };
+
+ rknn_mmu_0: iommu@27702000 {
+ compatible = "rockchip,rk3576-iommu", "rockchip,rk3568-iommu";
+ reg = <0x0 0x27702000 0x0 0x100>,
+ <0x0 0x27702100 0x0 0x100>;
+ interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_RKNN0>, <&cru HCLK_RKNN_ROOT>,
+ <&cru CLK_RKNN_DSU0>, <&cru ACLK_RKNN_CBUF>,
+ <&cru HCLK_RKNN_CBUF>;
+ #iommu-cells = <0>;
+ power-domains = <&power RK3576_PD_NPU0>;
+ status = "disabled";
+ };
+
+ rknn_core_1: npu@27710000 {
+ compatible = "rockchip,rk3576-rknn-core";
+ reg = <0x0 0x27710000 0x0 0x1000>,
+ <0x0 0x27711000 0x0 0x1000>,
+ <0x0 0x27713000 0x0 0x1000>,
+ <0x0 0x27714000 0x0 0x1000>,
+ <0x0 0x27715000 0x0 0x1000>;
+ reg-names = "pc", "cna", "core", "dpu", "dpu_rdma";
+ interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_RKNN1>, <&cru HCLK_RKNN_ROOT>,
+ <&cru CLK_RKNN_DSU0>, <&cru PCLK_NPUTOP_ROOT>;
+ clock-names = "aclk", "hclk", "npu", "pclk";
+ resets = <&cru SRST_A_RKNN1>;
+ reset-names = "srst_a";
+ power-domains = <&power RK3576_PD_NPU1>;
+ iommus = <&rknn_mmu_1>;
+ status = "disabled";
+ };
+
+ rknn_mmu_1: iommu@2770a000 {
+ compatible = "rockchip,rk3576-iommu", "rockchip,rk3568-iommu";
+ reg = <0x0 0x2770a000 0x0 0x100>,
+ <0x0 0x2770a100 0x0 0x100>;
+ interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_RKNN1>, <&cru HCLK_RKNN_ROOT>,
+ <&cru CLK_RKNN_DSU0>, <&cru ACLK_RKNN_CBUF>,
+ <&cru HCLK_RKNN_CBUF>;
+ #iommu-cells = <0>;
+ power-domains = <&power RK3576_PD_NPU1>;
+ status = "disabled";
+ };
+
gmac0: ethernet@2a220000 {
compatible = "rockchip,rk3576-gmac", "snps,dwmac-4.20a";
reg = <0x0 0x2a220000 0x0 0x10000>;
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 7/9] accel/rocket: add RK3576 NPU (RKNN) support
From: Jiaxing Hu @ 2026-07-17 8:50 UTC (permalink / raw)
To: tomeu, heiko, robh, krzk+dt, conor+dt, joro, will, robin.murphy,
ulfh, p.zabel, ogabbay
Cc: dri-devel, linux-rockchip, iommu, linux-pm, devicetree,
linux-arm-kernel, linux-kernel, Jiaxing Hu
In-Reply-To: <20260717085220.3212274-1-gahing@gahingwoo.com>
Add RK3576 support to the rocket DRM accelerator driver (used with the
Mesa Teflon TFLite delegate).
- match rockchip,rk3576-rknn-core; iterate its nodes at probe
- add named clock IDs (aclk/hclk/npu/pclk) and the CBUF clock domain
(ACLK/HCLK_RKNN_CBUF); the CNA fills the CBUF and CORE reads from it,
so the compute path stalls if those clocks are not held for a job
- guard rocket_job_timedout() MMIO behind pm_runtime_active()
- hrtimer completion poll: OP_EN never clears on RK3576 (unlike
RK3588), so poll INTERRUPT_RAW_STATUS PC_DONE bits instead
- map the DPU (0x4000) and DPU_RDMA (0x5000) blocks and pre-arm them
- attach both NPU power domains (PD_NPU0 + PD_NPU1): the CBUF->CMAC
read path is only fully powered with NPU1 up
Tested on a Radxa ROCK 4D: the NPU probes, powers on, brings up its
IOMMUs and runs submitted jobs to completion. Full multi-layer inference
is not yet correct on this SoC (only the first operation per power
session produces valid output); see the cover letter.
Signed-off-by: Jiaxing Hu <gahing@gahingwoo.com>
---
drivers/accel/rocket/rocket_core.c | 43 +++++++-
drivers/accel/rocket/rocket_core.h | 22 +++-
drivers/accel/rocket/rocket_device.c | 4 +
drivers/accel/rocket/rocket_drv.c | 1 +
drivers/accel/rocket/rocket_job.c | 154 +++++++++++++++++++++------
5 files changed, 187 insertions(+), 37 deletions(-)
diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
index b3b2fa9ba..7b0c48e4d 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -8,6 +8,7 @@
#include <linux/err.h>
#include <linux/iommu.h>
#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
@@ -22,12 +23,23 @@ int rocket_core_init(struct rocket_core *core)
int err = 0;
core->resets[0].id = "srst_a";
- core->resets[1].id = "srst_h";
err = devm_reset_control_bulk_get_exclusive(&pdev->dev, ARRAY_SIZE(core->resets),
core->resets);
if (err)
return dev_err_probe(dev, err, "failed to get resets for core %d\n", core->index);
+ core->clks[0].id = "aclk";
+ core->clks[1].id = "hclk";
+ core->clks[2].id = "npu";
+ core->clks[3].id = "pclk";
+ /*
+ * RK3576: the CBUF (convolution buffer) has its own clock domain. The CNA
+ * fills the CBUF and CORE reads from it; without these the compute path
+ * stalls after loading one slice (RDMA, which bypasses the CBUF, still
+ * runs). The vendor keeps all NPU clocks on whenever powered.
+ */
+ core->clks[4].id = "aclk_cbuf";
+ core->clks[5].id = "hclk_cbuf";
err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
if (err)
return dev_err_probe(dev, err, "failed to get clocks for core %d\n", core->index);
@@ -50,6 +62,18 @@ int rocket_core_init(struct rocket_core *core)
return PTR_ERR(core->core_iomem);
}
+ core->dpu_iomem = devm_platform_ioremap_resource_byname(pdev, "dpu");
+ if (IS_ERR(core->dpu_iomem)) {
+ dev_warn(dev, "no DPU registers; DPU S_POINTER won't be pre-armed\n");
+ core->dpu_iomem = NULL;
+ }
+
+ core->dpu_rdma_iomem = devm_platform_ioremap_resource_byname(pdev, "dpu_rdma");
+ if (IS_ERR(core->dpu_rdma_iomem)) {
+ dev_warn(dev, "no DPU_RDMA registers; DPU_RDMA S_POINTER won't be pre-armed\n");
+ core->dpu_rdma_iomem = NULL;
+ }
+
dma_set_max_seg_size(dev, UINT_MAX);
err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
@@ -65,6 +89,23 @@ int rocket_core_init(struct rocket_core *core)
return err;
}
+ /*
+ * RK3576: the NPU spans TWO power domains (PD_NPU0 + PD_NPU1). The vendor
+ * powers BOTH from its single NPU node even when computing on one core --
+ * the CBUF->CMAC read path only works fully with NPU1 powered. The board DT
+ * lists both power-domains on rknn_core_0; a multi-PD device skips the
+ * driver-core single-PD auto-attach, so attach the list explicitly. With
+ * one PD in DT this is a no-op (returns 1) and behaves as before.
+ */
+ {
+ struct dev_pm_domain_list *pd_list;
+
+ err = devm_pm_domain_attach_list(dev, NULL, &pd_list);
+ if (err < 0)
+ return dev_err_probe(dev, err,
+ "failed to attach NPU power domains\n");
+ }
+
pm_runtime_use_autosuspend(dev);
/*
diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h
index f6d738285..e959b26dd 100644
--- a/drivers/accel/rocket/rocket_core.h
+++ b/drivers/accel/rocket/rocket_core.h
@@ -6,6 +6,7 @@
#include <drm/gpu_scheduler.h>
#include <linux/clk.h>
+#include <linux/hrtimer.h>
#include <linux/io.h>
#include <linux/mutex_types.h>
#include <linux/reset.h>
@@ -27,6 +28,16 @@
#define rocket_core_writel(core, reg, value) \
writel(value, (core)->core_iomem + (REG_CORE_##reg) - REG_CORE_S_STATUS)
+#define rocket_dpu_readl(core, reg) \
+ readl((core)->dpu_iomem + (REG_DPU_##reg) - REG_DPU_S_STATUS)
+#define rocket_dpu_writel(core, reg, value) \
+ writel(value, (core)->dpu_iomem + (REG_DPU_##reg) - REG_DPU_S_STATUS)
+
+#define rocket_dpu_rdma_readl(core, reg) \
+ readl((core)->dpu_rdma_iomem + (REG_DPU_RDMA_##reg) - REG_DPU_RDMA_RDMA_S_STATUS)
+#define rocket_dpu_rdma_writel(core, reg, value) \
+ writel(value, (core)->dpu_rdma_iomem + (REG_DPU_RDMA_##reg) - REG_DPU_RDMA_RDMA_S_STATUS)
+
struct rocket_core {
struct device *dev;
struct rocket_device *rdev;
@@ -36,8 +47,10 @@ struct rocket_core {
void __iomem *pc_iomem;
void __iomem *cna_iomem;
void __iomem *core_iomem;
- struct clk_bulk_data clks[4];
- struct reset_control_bulk_data resets[2];
+ void __iomem *dpu_iomem;
+ void __iomem *dpu_rdma_iomem;
+ struct clk_bulk_data clks[6];
+ struct reset_control_bulk_data resets[1];
struct iommu_group *iommu_group;
@@ -52,6 +65,11 @@ struct rocket_core {
atomic_t pending;
} reset;
+ /* RK3576 has no completion IRQ; poll for PC_DONE via hrtimer. */
+ struct hrtimer poll_timer;
+ struct work_struct poll_work;
+ atomic_t poll_active;
+
struct drm_gpu_scheduler sched;
u64 fence_context;
u64 emit_seqno;
diff --git a/drivers/accel/rocket/rocket_device.c b/drivers/accel/rocket/rocket_device.c
index 46e6ee1e7..bfb00f967 100644
--- a/drivers/accel/rocket/rocket_device.c
+++ b/drivers/accel/rocket/rocket_device.c
@@ -31,6 +31,10 @@ struct rocket_device *rocket_device_init(struct platform_device *pdev,
if (of_device_is_available(core_node))
num_cores++;
+ for_each_compatible_node(core_node, NULL, "rockchip,rk3576-rknn-core")
+ if (of_device_is_available(core_node))
+ num_cores++;
+
rdev->cores = devm_kcalloc(dev, num_cores, sizeof(*rdev->cores), GFP_KERNEL);
if (!rdev->cores)
return ERR_PTR(-ENOMEM);
diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
index 8bbbce594..8f6a02d50 100644
--- a/drivers/accel/rocket/rocket_drv.c
+++ b/drivers/accel/rocket/rocket_drv.c
@@ -215,6 +215,7 @@ static void rocket_remove(struct platform_device *pdev)
static const struct of_device_id dt_match[] = {
{ .compatible = "rockchip,rk3588-rknn-core" },
+ { .compatible = "rockchip,rk3576-rknn-core" },
{}
};
MODULE_DEVICE_TABLE(of, dt_match);
diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
index 2f1861f96..94461bf71 100644
--- a/drivers/accel/rocket/rocket_job.c
+++ b/drivers/accel/rocket/rocket_job.c
@@ -7,6 +7,7 @@
#include <drm/drm_file.h>
#include <drm/drm_gem.h>
#include <drm/rocket_accel.h>
+#include <linux/hrtimer.h>
#include <linux/interrupt.h>
#include <linux/iommu.h>
#include <linux/platform_device.h>
@@ -20,6 +21,16 @@
#define JOB_TIMEOUT_MS 500
+/*
+ * RK3576: INTERRUPT_MASK bits 28-29 are read-only (hardware rejects the write),
+ * so the PC_DONE completion signal cannot be routed to the GIC via the normal
+ * interrupt-mask path. We poll OPERATION_ENABLE every RK3576_POLL_INTERVAL_NS
+ * instead of waiting for a completion IRQ.
+ */
+#define PC_INTERRUPT_MASK_RK3576_PC_DONE_0 0x10000000u
+#define PC_INTERRUPT_MASK_RK3576_PC_DONE_1 0x20000000u
+#define RK3576_POLL_INTERVAL_NS 1000000LL /* 1 ms */
+
static struct rocket_job *
to_rocket_job(struct drm_sched_job *sched_job)
{
@@ -137,8 +148,21 @@ static void rocket_job_hw_submit(struct rocket_core *core, struct rocket_job *jo
rocket_pc_writel(core, REGISTER_AMOUNTS,
PC_REGISTER_AMOUNTS_PC_DATA_AMOUNT((task->regcmd_count + 1) / 2 - 1));
- rocket_pc_writel(core, INTERRUPT_MASK, PC_INTERRUPT_MASK_DPU_0 | PC_INTERRUPT_MASK_DPU_1);
- rocket_pc_writel(core, INTERRUPT_CLEAR, PC_INTERRUPT_CLEAR_DPU_0 | PC_INTERRUPT_CLEAR_DPU_1);
+ /* Enable DMA-error interrupts; PC_DONE (bits 28-29) is polled, see above. */
+ rocket_pc_writel(core, INTERRUPT_MASK,
+ PC_INTERRUPT_MASK_DPU_0 | PC_INTERRUPT_MASK_DPU_1 |
+ PC_INTERRUPT_MASK_CORE_0 | PC_INTERRUPT_MASK_CORE_1 |
+ PC_INTERRUPT_MASK_PPU_0 | PC_INTERRUPT_MASK_PPU_1 |
+ PC_INTERRUPT_MASK_CNA_CSC_0 | PC_INTERRUPT_MASK_CNA_CSC_1 |
+ PC_INTERRUPT_MASK_DMA_READ_ERROR |
+ PC_INTERRUPT_MASK_DMA_WRITE_ERROR);
+ rocket_pc_writel(core, INTERRUPT_CLEAR,
+ PC_INTERRUPT_CLEAR_DPU_0 | PC_INTERRUPT_CLEAR_DPU_1 |
+ PC_INTERRUPT_CLEAR_CORE_0 | PC_INTERRUPT_CLEAR_CORE_1 |
+ PC_INTERRUPT_CLEAR_PPU_0 | PC_INTERRUPT_CLEAR_PPU_1 |
+ PC_INTERRUPT_CLEAR_CNA_CSC_0 | PC_INTERRUPT_CLEAR_CNA_CSC_1 |
+ PC_INTERRUPT_MASK_RK3576_PC_DONE_0 |
+ PC_INTERRUPT_MASK_RK3576_PC_DONE_1);
rocket_pc_writel(core, TASK_CON, PC_TASK_CON_RESERVED_0(1) |
PC_TASK_CON_TASK_COUNT_CLEAR(1) |
@@ -149,7 +173,9 @@ static void rocket_job_hw_submit(struct rocket_core *core, struct rocket_job *jo
rocket_pc_writel(core, OPERATION_ENABLE, PC_OPERATION_ENABLE_OP_EN(1));
- dev_dbg(core->dev, "Submitted regcmd at 0x%llx to core %d", task->regcmd, core->index);
+ atomic_set(&core->poll_active, 1);
+ hrtimer_start(&core->poll_timer, ns_to_ktime(RK3576_POLL_INTERVAL_NS),
+ HRTIMER_MODE_REL);
}
static int rocket_acquire_object_fences(struct drm_gem_object **bos,
@@ -326,56 +352,99 @@ static struct dma_fence *rocket_job_run(struct drm_sched_job *sched_job)
return fence;
}
+static void rocket_job_handle_irq(struct rocket_core *core);
+
+static enum hrtimer_restart rocket_poll_timer_fn(struct hrtimer *timer)
+{
+ struct rocket_core *core = container_of(timer, struct rocket_core, poll_timer);
+
+ if (!atomic_read(&core->poll_active))
+ return HRTIMER_NORESTART;
+
+ /*
+ * On RK3576, OPERATION_ENABLE is not cleared by hardware on completion;
+ * check INTERRUPT_RAW_STATUS bits 28-29 (PC_DONE_0/1) instead.
+ */
+ if (rocket_pc_readl(core, OPERATION_ENABLE) == 0 ||
+ (rocket_pc_readl(core, INTERRUPT_RAW_STATUS) &
+ (PC_INTERRUPT_MASK_RK3576_PC_DONE_0 |
+ PC_INTERRUPT_MASK_RK3576_PC_DONE_1))) {
+ atomic_set(&core->poll_active, 0);
+ schedule_work(&core->poll_work);
+ return HRTIMER_NORESTART;
+ }
+
+ hrtimer_forward_now(timer, ns_to_ktime(RK3576_POLL_INTERVAL_NS));
+ return HRTIMER_RESTART;
+}
+
+static void rocket_poll_work_fn(struct work_struct *work)
+{
+ struct rocket_core *core = container_of(work, struct rocket_core, poll_work);
+
+ rocket_job_handle_irq(core);
+}
+
static void rocket_job_handle_irq(struct rocket_core *core)
{
+ struct rocket_job *job;
+
+ /* Stop the completion poll — we're handling it now. */
+ atomic_set(&core->poll_active, 0);
+ hrtimer_cancel(&core->poll_timer);
+
pm_runtime_mark_last_busy(core->dev);
rocket_pc_writel(core, OPERATION_ENABLE, 0x0);
- rocket_pc_writel(core, INTERRUPT_CLEAR, 0x1ffff);
-
- scoped_guard(mutex, &core->job_lock)
- if (core->in_flight_job) {
- if (core->in_flight_job->next_task_idx < core->in_flight_job->task_count) {
- rocket_job_hw_submit(core, core->in_flight_job);
- return;
- }
-
- iommu_detach_group(NULL, iommu_group_get(core->dev));
- dma_fence_signal(core->in_flight_job->done_fence);
- pm_runtime_put_autosuspend(core->dev);
- core->in_flight_job = NULL;
+ rocket_pc_writel(core, INTERRUPT_CLEAR,
+ 0x1ffff |
+ PC_INTERRUPT_MASK_RK3576_PC_DONE_0 |
+ PC_INTERRUPT_MASK_RK3576_PC_DONE_1);
+
+ scoped_guard(mutex, &core->job_lock) {
+ job = core->in_flight_job;
+ if (!job)
+ return;
+
+ if (job->next_task_idx < job->task_count) {
+ rocket_job_hw_submit(core, job);
+ return;
}
+
+ iommu_detach_group(job->domain->domain, core->iommu_group);
+ dma_fence_signal(job->done_fence);
+ pm_runtime_put_autosuspend(core->dev);
+ core->in_flight_job = NULL;
+ }
}
static void
rocket_reset(struct rocket_core *core, struct drm_sched_job *bad)
{
+ struct rocket_job *job;
+
if (!atomic_read(&core->reset.pending))
return;
+ atomic_set(&core->poll_active, 0);
+ hrtimer_cancel(&core->poll_timer);
+ cancel_work(&core->poll_work);
+
drm_sched_stop(&core->sched, bad);
- /*
- * Remaining interrupts have been handled, but we might still have
- * stuck jobs. Let's make sure the PM counters stay balanced by
- * manually calling pm_runtime_put_noidle().
- */
scoped_guard(mutex, &core->job_lock) {
- if (core->in_flight_job)
+ job = core->in_flight_job;
+ if (job) {
pm_runtime_put_noidle(core->dev);
-
- iommu_detach_group(NULL, core->iommu_group);
-
- core->in_flight_job = NULL;
+ iommu_detach_group(job->domain->domain, core->iommu_group);
+ core->in_flight_job = NULL;
+ }
}
- /* Proceed with reset now. */
rocket_core_reset(core);
- /* NPU has been reset, we can clear the reset pending bit. */
atomic_set(&core->reset.pending, 0);
- /* Restart the scheduler */
drm_sched_start(&core->sched, 0);
}
@@ -385,7 +454,14 @@ static enum drm_gpu_sched_stat rocket_job_timedout(struct drm_sched_job *sched_j
struct rocket_device *rdev = job->rdev;
struct rocket_core *core = sched_to_core(rdev, sched_job->sched);
- dev_err(core->dev, "NPU job timed out");
+ if (pm_runtime_active(core->dev))
+ dev_err(core->dev,
+ "NPU job timed out: RAW_STATUS=0x%08x MASK=0x%08x OP_EN=0x%08x\n",
+ rocket_pc_readl(core, INTERRUPT_RAW_STATUS),
+ rocket_pc_readl(core, INTERRUPT_MASK),
+ rocket_pc_readl(core, OPERATION_ENABLE));
+ else
+ dev_err(core->dev, "NPU job timed out (device not active)\n");
atomic_set(&core->reset.pending, 1);
rocket_reset(core, sched_job);
@@ -420,14 +496,16 @@ static irqreturn_t rocket_job_irq_handler(int irq, void *data)
{
struct rocket_core *core = data;
u32 raw_status = rocket_pc_readl(core, INTERRUPT_RAW_STATUS);
+ /* Only bits 0-13 (DMA errors) can raise this IRQ; PC_DONE is polled. */
+ u32 active = raw_status & 0x3fff;
+
+ if (!active)
+ return IRQ_NONE;
WARN_ON(raw_status & PC_INTERRUPT_RAW_STATUS_DMA_READ_ERROR);
WARN_ON(raw_status & PC_INTERRUPT_RAW_STATUS_DMA_WRITE_ERROR);
- if (!(raw_status & PC_INTERRUPT_RAW_STATUS_DPU_0 ||
- raw_status & PC_INTERRUPT_RAW_STATUS_DPU_1))
- return IRQ_NONE;
-
+ rocket_pc_writel(core, INTERRUPT_CLEAR, active);
rocket_pc_writel(core, INTERRUPT_MASK, 0x0);
return IRQ_WAKE_THREAD;
@@ -445,6 +523,10 @@ int rocket_job_init(struct rocket_core *core)
int ret;
INIT_WORK(&core->reset.work, rocket_reset_work);
+ INIT_WORK(&core->poll_work, rocket_poll_work_fn);
+ hrtimer_setup(&core->poll_timer, rocket_poll_timer_fn, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ atomic_set(&core->poll_active, 0);
spin_lock_init(&core->fence_lock);
mutex_init(&core->job_lock);
@@ -486,6 +568,10 @@ int rocket_job_init(struct rocket_core *core)
void rocket_job_fini(struct rocket_core *core)
{
+ atomic_set(&core->poll_active, 0);
+ hrtimer_cancel(&core->poll_timer);
+ cancel_work_sync(&core->poll_work);
+
drm_sched_fini(&core->sched);
cancel_work_sync(&core->reset.work);
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 6/9] iommu/rockchip: take all DT clocks
From: Jiaxing Hu @ 2026-07-17 8:50 UTC (permalink / raw)
To: tomeu, heiko, robh, krzk+dt, conor+dt, joro, will, robin.murphy,
ulfh, p.zabel, ogabbay
Cc: dri-devel, linux-rockchip, iommu, linux-pm, devicetree,
linux-arm-kernel, linux-kernel, Jiaxing Hu
In-Reply-To: <20260717085220.3212274-1-gahing@gahingwoo.com>
rk_iommu only enabled a fixed {aclk,iface} pair. On the RK3576 NPU the
MMU sits behind the CBUF/DSU gates, so writes to DTE_ADDR are silently
dropped until those clocks run too (reads work, writes need more clocks).
Take every clock described in the DT for the IOMMU instead of a fixed
pair, so a platform can list the full set it needs.
Signed-off-by: Jiaxing Hu <gahing@gahingwoo.com>
---
drivers/iommu/rockchip-iommu.c | 30 ++++++++++--------------------
1 file changed, 10 insertions(+), 20 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ce586919b..49c841095 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -93,11 +93,6 @@ struct rk_iommu_domain {
struct iommu_domain domain;
};
-/* list of clocks required by IOMMU */
-static const char * const rk_iommu_clocks[] = {
- "aclk", "iface",
-};
-
struct rk_iommu_ops {
phys_addr_t (*pt_address)(u32 dte);
u32 (*mk_dtentries)(dma_addr_t pt_dma);
@@ -1274,25 +1269,20 @@ static int rk_iommu_probe(struct platform_device *pdev)
iommu->reset_disabled = device_property_read_bool(dev,
"rockchip,disable-mmu-reset");
- iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
- iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
- sizeof(*iommu->clocks), GFP_KERNEL);
- if (!iommu->clocks)
- return -ENOMEM;
-
- for (i = 0; i < iommu->num_clocks; ++i)
- iommu->clocks[i].id = rk_iommu_clocks[i];
-
/*
- * iommu clocks should be present for all new devices and devicetrees
- * but there are older devicetrees without clocks out in the wild.
- * So clocks as optional for the time being.
+ * Take every clock the devicetree provides. Most IOMMU instances
+ * need exactly "aclk" + "iface", but e.g. the RK3576 NPU IOMMUs sit
+ * behind additional gates (CBUF/DSU) whose clocks must be running
+ * for register writes to land. Clocks stay optional because there
+ * are older devicetrees without clocks out in the wild.
*/
- err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks);
- if (err == -ENOENT)
+ err = devm_clk_bulk_get_all(iommu->dev, &iommu->clocks);
+ if (err == -ENOENT || err == 0)
iommu->num_clocks = 0;
- else if (err)
+ else if (err < 0)
return err;
+ else
+ iommu->num_clocks = err;
err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks);
if (err)
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 5/9] iommu/rockchip: skip orphaned-fault banks in CMD_ENABLE_STALL dispatch
From: Jiaxing Hu @ 2026-07-17 8:50 UTC (permalink / raw)
To: tomeu, heiko, robh, krzk+dt, conor+dt, joro, will, robin.murphy,
ulfh, p.zabel, ogabbay
Cc: dri-devel, linux-rockchip, iommu, linux-pm, devicetree,
linux-arm-kernel, linux-kernel, Jiaxing Hu
In-Reply-To: <20260717085220.3212274-1-gahing@gahingwoo.com>
Sending CMD_ENABLE_STALL to a bank that carries an orphaned firmware
fault (PAGE_FAULT_ACTIVE & !STALL_ACTIVE & IDLE) causes the command to
be silently dropped by that bank. The dropped command also interferes
with the other banks' stall transition, delaying them past the poll
timeout even though they would otherwise stall within a few
microseconds.
Skip such banks when issuing CMD_ENABLE_STALL, matching the skip
condition already used in rk_iommu_is_stall_active().
Signed-off-by: Jiaxing Hu <gahing@gahingwoo.com>
---
drivers/iommu/rockchip-iommu.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index f42ffcafb..ce586919b 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -434,7 +434,21 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
if (!rk_iommu_is_paging_enabled(iommu))
return 0;
- rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_STALL);
+ /*
+ * Do not send CMD_ENABLE_STALL to orphaned-fault banks
+ * (PAGE_FAULT_ACTIVE & !STALL_ACTIVE & IDLE): the command is ignored
+ * by such a bank but its presence on the shared bus delays the other
+ * banks from reaching STALL_ACTIVE within the poll timeout.
+ */
+ for (i = 0; i < iommu->num_mmu; i++) {
+ u32 status = rk_iommu_read(iommu->bases[i], RK_MMU_STATUS);
+
+ if ((status & RK_MMU_STATUS_PAGE_FAULT_ACTIVE) &&
+ !(status & RK_MMU_STATUS_STALL_ACTIVE) &&
+ (status & RK_MMU_STATUS_IDLE))
+ continue;
+ writel(RK_MMU_CMD_ENABLE_STALL, iommu->bases[i] + RK_MMU_COMMAND);
+ }
ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
val, RK_MMU_POLL_PERIOD_US,
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 4/9] iommu/rockchip: skip orphaned-fault banks in rk_iommu_is_stall_active
From: Jiaxing Hu @ 2026-07-17 8:50 UTC (permalink / raw)
To: tomeu, heiko, robh, krzk+dt, conor+dt, joro, will, robin.murphy,
ulfh, p.zabel, ogabbay
Cc: dri-devel, linux-rockchip, iommu, linux-pm, devicetree,
linux-arm-kernel, linux-kernel, Jiaxing Hu
In-Reply-To: <20260717085220.3212274-1-gahing@gahingwoo.com>
Boot firmware can leave a PAGE_FAULT_ACTIVE condition in an IOMMU bank
before the driver has configured paging. Such a bank shows:
PAGE_FAULT_ACTIVE=1 STALL_ACTIVE=0 IDLE=1
rk_iommu_is_stall_active() sees STALL_ACTIVE=0 and reports the whole
IOMMU as "not stalled", so any subsequent readx_poll_timeout() loop
waiting for the stall to complete never sees a passing result even
after the other banks have correctly entered stall mode.
Detect the orphaned-fault pattern (PAGE_FAULT_ACTIVE & !STALL_ACTIVE &
IDLE) and skip those banks in the stall check. They have no in-flight
transaction, so they are already quiescent.
Signed-off-by: Jiaxing Hu <gahing@gahingwoo.com>
---
drivers/iommu/rockchip-iommu.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 0013cf196..f42ffcafb 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -378,9 +378,23 @@ static bool rk_iommu_is_stall_active(struct rk_iommu *iommu)
bool active = true;
int i;
- for (i = 0; i < iommu->num_mmu; i++)
- active &= !!(rk_iommu_read(iommu->bases[i], RK_MMU_STATUS) &
- RK_MMU_STATUS_STALL_ACTIVE);
+ for (i = 0; i < iommu->num_mmu; i++) {
+ u32 status = rk_iommu_read(iommu->bases[i], RK_MMU_STATUS);
+
+ /*
+ * A bank stuck with PAGE_FAULT_ACTIVE but without STALL_ACTIVE
+ * and with IDLE set has an orphaned fault left by firmware before
+ * paging was configured. It cannot enter stall mode but has no
+ * transaction in flight, so it is already quiescent. Skip it
+ * rather than treating it as "not stalled."
+ */
+ if ((status & RK_MMU_STATUS_PAGE_FAULT_ACTIVE) &&
+ !(status & RK_MMU_STATUS_STALL_ACTIVE) &&
+ (status & RK_MMU_STATUS_IDLE))
+ continue;
+
+ active &= !!(status & RK_MMU_STATUS_STALL_ACTIVE);
+ }
return active;
}
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 3/9] pmdomain/rockchip: cycle optional power-domain resets on power-on
From: Jiaxing Hu @ 2026-07-17 8:50 UTC (permalink / raw)
To: tomeu, heiko, robh, krzk+dt, conor+dt, joro, will, robin.murphy,
ulfh, p.zabel, ogabbay
Cc: dri-devel, linux-rockchip, iommu, linux-pm, devicetree,
linux-arm-kernel, linux-kernel, Jiaxing Hu
In-Reply-To: <20260717085220.3212274-1-gahing@gahingwoo.com>
Some power domains contain hardware bus interfaces that require an
explicit assert/deassert edge on their reset line after the domain
is powered on. The CRU preserves reset state across power cycles
(stays deasserted), so the hardware never sees the edge it needs to
initialize unless the driver pulses it explicitly.
Add an optional resets property to rockchip_pm_domain. When present,
the resets are asserted and deasserted (with a 10 µs hold) inside
rockchip_pd_power() after the idle bits are cleared and the
delay_us settling time has elapsed, but before any device in the
domain resumes. This ordering guarantees the bus is fully
initialized before any device driver accesses registers.
Signed-off-by: Jiaxing Hu <gahing@gahingwoo.com>
---
drivers/pmdomain/rockchip/pm-domains.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
index 1787f62ba..7a88a9149 100644
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -18,6 +18,7 @@
#include <linux/of_address.h>
#include <linux/of_clk.h>
#include <linux/clk.h>
+#include <linux/reset.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/mfd/syscon.h>
@@ -102,6 +103,7 @@ struct rockchip_pm_domain {
struct clk_bulk_data *clks;
struct device_node *node;
struct regulator *supply;
+ struct reset_control *resets;
};
struct rockchip_pmu {
@@ -671,6 +673,12 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
if (pd->info->delay_us)
udelay(pd->info->delay_us);
+ if (pd->resets) {
+ reset_control_assert(pd->resets);
+ udelay(10);
+ reset_control_deassert(pd->resets);
+ }
+
rockchip_pmu_restore_qos(pd);
}
@@ -840,6 +848,14 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
if (error)
goto err_put_clocks;
+ pd->resets = of_reset_control_array_get_optional_exclusive(node);
+ if (IS_ERR(pd->resets)) {
+ error = PTR_ERR(pd->resets);
+ dev_err(pmu->dev, "%pOFn: failed to get resets: %d\n", node, error);
+ pd->resets = NULL;
+ goto err_unprepare_clocks;
+ }
+
pd->num_qos = of_count_phandle_with_args(node, "pm_qos",
NULL);
@@ -910,6 +926,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
clk_bulk_unprepare(pd->num_clks, pd->clks);
err_put_clocks:
clk_bulk_put(pd->num_clks, pd->clks);
+ reset_control_put(pd->resets);
return error;
}
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox