summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-22 07:52:50 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-22 07:52:50 -1000
commit2e51c645fee243dbcb5cee3eb063b5713317444c (patch)
treeee6bfb3eabdc46763c050c98a7549e504313a286
parent7b9a0e857b427cdda5a08b662dbea7321e6bb470 (diff)
parent0045cd6b8ab2319e9d8de46e5e329cdc35ce6d05 (diff)
Merge tag 'soc-drivers-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull SoC driver updates from Arnd Bergmann: "There are lots of minor updates for driver subsystems managed through the soc tree (turris-omnia platform, cache driver, tee drivers, arm-cci, bus, memory) as well as soc vendor specific drivers (starfive, xilinx, microchip, nxp, amlogic, imx, renesas, samsung, ti, nvidia). The more notable changes are: - Larger updates for Qualcomm SoCs including support for SM8950 (Maili) SM8975 (Hawi), Glymur, Shikra, and IPQ5424 - Added SoC support for Exynos5515, Tegra264, Tegra410, R8A774A3, and MT8167 in existing drivers - Arm SCMI firmware driver support for ACPI PCC transport and module autoloading of protocol specific drivers - Apple crash log support for CrgA embedded controller" * tag 'soc-drivers-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (176 commits) platform: cznic: turris-omnia-mcu: stop button emulation producers cache: Make cpu_cache_invalidate_memregion() error out if there are no handlers soc: mpfs: use kref cleanup on probe failure arm64: enable HAVE_SHARED_GPIOS for all ARM64 platforms bus: arm-cci: Drop cci-control-port node reference in __cci_ace_get_port() bus: arm-cci: Drop CPU node reference in cci_ace_init_ports() soc: fsl: dpio: Free the IRQ before releasing the I/O object soc: fsl: dpio: Fix cleanup on IRQ registration failure bus: fsl-mc: Annotate fsl_mc_io.portal_virt_addr with __counted_by_ptr bus: fsl-mc: drop the fwnode links of the dpmacs nodes soc: fsl: cpm1: tsa: Fix clock leak in tsa_of_parse_tdms() soc: qcom: geni-se: Drop unused icc_ddr parameter from geni_icc_get() firmware: qcom: scm: Allow QSEECOM on ThinkPad T14s Gen 7 dt-bindings: mailbox: qcom: Document Maili CPUCP mailbox controller dt-bindings: spmi: glymur-spmi-pmic-arb: Add compatible for Qualcomm Maili SoC soc: qcom: pmic_pdcharger_ulog: prevent work requeue during remove ASoC: dt-bindings: qcom,apr: Add modem_apps GLINK channel for shikra firmware: qcom: tzmem: disable SHM bridge for SM7125 platform soc: qcom: ubwc: Add Kalambo UBWC config firmware: qcom: scm: Allow QSEECOM on Kalambo CRD ...
-rw-r--r--Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml1
-rw-r--r--Documentation/devicetree/bindings/cache/qcom,llcc.yaml55
-rw-r--r--Documentation/devicetree/bindings/clock/starfive,jhb100-per0crg.yaml70
-rw-r--r--Documentation/devicetree/bindings/clock/starfive,jhb100-per1crg.yaml70
-rw-r--r--Documentation/devicetree/bindings/clock/starfive,jhb100-per2crg.yaml76
-rw-r--r--Documentation/devicetree/bindings/clock/starfive,jhb100-per3crg.yaml76
-rw-r--r--Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml63
-rw-r--r--Documentation/devicetree/bindings/clock/starfive,jhb100-sys1crg.yaml71
-rw-r--r--Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml64
-rw-r--r--Documentation/devicetree/bindings/firmware/qcom,scm.yaml4
-rw-r--r--Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml1
-rw-r--r--Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml1
-rw-r--r--Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml1
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml21
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml3
-rw-r--r--Documentation/devicetree/bindings/mfd/syscon.yaml1
-rw-r--r--Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-gx-clk-measure.yaml16
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml4
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom-stats.yaml25
-rw-r--r--Documentation/devicetree/bindings/soc/starfive/starfive,jhb100-syscon.yaml115
-rw-r--r--Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml1
-rw-r--r--Documentation/devicetree/bindings/sram/qcom,imem.yaml1
-rw-r--r--Documentation/devicetree/bindings/sram/sram.yaml3
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm/mach-at91/pm.h2
-rw-r--r--arch/arm64/Kconfig1
-rw-r--r--arch/arm64/Kconfig.platforms1
-rw-r--r--drivers/bus/arm-cci.c6
-rw-r--r--drivers/bus/fsl-mc/fsl-mc-bus.c64
-rw-r--r--drivers/bus/fsl-mc/fsl-mc-msi.c2
-rw-r--r--drivers/cache/hisi_soc_hha.c2
-rw-r--r--drivers/cache/sifive_ccache.c2
-rw-r--r--drivers/firmware/arm_scmi/bus.c109
-rw-r--r--drivers/firmware/arm_scmi/common.h61
-rw-r--r--drivers/firmware/arm_scmi/driver.c260
-rw-r--r--drivers/firmware/arm_scmi/protocols.h9
-rw-r--r--drivers/firmware/arm_scmi/raw_mode.c30
-rw-r--r--drivers/firmware/arm_scmi/reset.c36
-rw-r--r--drivers/firmware/arm_scmi/transports/Kconfig12
-rw-r--r--drivers/firmware/arm_scmi/transports/Makefile2
-rw-r--r--drivers/firmware/arm_scmi/transports/mailbox.c7
-rw-r--r--drivers/firmware/arm_scmi/transports/optee.c7
-rw-r--r--drivers/firmware/arm_scmi/transports/pcc.c875
-rw-r--r--drivers/firmware/arm_scmi/transports/smc.c10
-rw-r--r--drivers/firmware/arm_scmi/transports/virtio.c3
-rw-r--r--drivers/firmware/imx/imx-dsp.c6
-rw-r--r--drivers/firmware/microchip/mpfs-auto-update.c4
-rw-r--r--drivers/firmware/qcom/Kconfig5
-rw-r--r--drivers/firmware/qcom/qcom_scm-legacy.c2
-rw-r--r--drivers/firmware/qcom/qcom_scm.c187
-rw-r--r--drivers/firmware/qcom/qcom_tzmem.c3
-rw-r--r--drivers/firmware/ti_sci.c6
-rw-r--r--drivers/firmware/xilinx/zynqmp-ufs.c70
-rw-r--r--drivers/firmware/xilinx/zynqmp.c44
-rw-r--r--drivers/memory/brcmstb_dpfe.c41
-rw-r--r--drivers/memory/emif.c6
-rw-r--r--drivers/memory/emif.h4
-rw-r--r--drivers/memory/mtk-smi.c45
-rw-r--r--drivers/memory/renesas-rpc-if.c87
-rw-r--r--drivers/memory/samsung/exynos5422-dmc.c11
-rw-r--r--drivers/memory/stm32_omm.c2
-rw-r--r--drivers/memory/tegra/tegra264.c376
-rw-r--r--drivers/platform/cznic/turris-omnia-mcu-base.c1
-rw-r--r--drivers/platform/cznic/turris-omnia-mcu-gpio.c31
-rw-r--r--drivers/soc/Kconfig1
-rw-r--r--drivers/soc/Makefile1
-rw-r--r--drivers/soc/amlogic/meson-clk-measure.c927
-rw-r--r--drivers/soc/apple/rtkit-crashlog.c139
-rw-r--r--drivers/soc/atmel/soc.c4
-rw-r--r--drivers/soc/fsl/dpio/dpio-driver.c9
-rw-r--r--drivers/soc/fsl/qe/gpio.c67
-rw-r--r--drivers/soc/fsl/qe/tsa.c16
-rw-r--r--drivers/soc/mediatek/mt8167-mmsys.h183
-rw-r--r--drivers/soc/mediatek/mtk-regulator-coupler.c1
-rw-r--r--drivers/soc/microchip/mpfs-sys-controller.c7
-rw-r--r--drivers/soc/qcom/Kconfig1
-rw-r--r--drivers/soc/qcom/apr.c69
-rw-r--r--drivers/soc/qcom/llcc-qcom.c199
-rw-r--r--drivers/soc/qcom/pmic_glink.c3
-rw-r--r--drivers/soc/qcom/pmic_glink_altmode.c4
-rw-r--r--drivers/soc/qcom/pmic_pdcharger_ulog.c2
-rw-r--r--drivers/soc/qcom/qcom-geni-se.c65
-rw-r--r--drivers/soc/qcom/qcom_aoss.c4
-rw-r--r--drivers/soc/qcom/qcom_stats.c9
-rw-r--r--drivers/soc/qcom/rpmh-internal.h16
-rw-r--r--drivers/soc/qcom/rpmh-rsc.c4
-rw-r--r--drivers/soc/qcom/rpmh.c40
-rw-r--r--drivers/soc/qcom/smem_dramc.c81
-rw-r--r--drivers/soc/qcom/smp2p.c22
-rw-r--r--drivers/soc/qcom/smsm.c36
-rw-r--r--drivers/soc/qcom/socinfo.c3
-rw-r--r--drivers/soc/qcom/ubwc_config.c12
-rw-r--r--drivers/soc/renesas/Kconfig22
-rw-r--r--drivers/soc/renesas/r9a08g046-sysc.c1
-rw-r--r--drivers/soc/renesas/rcar-mfis.c62
-rw-r--r--drivers/soc/renesas/rcar-rst.c1
-rw-r--r--drivers/soc/renesas/renesas-soc.c3
-rw-r--r--drivers/soc/renesas/rz-sysc.c5
-rw-r--r--drivers/soc/renesas/rz-sysc.h2
-rw-r--r--drivers/soc/samsung/exynos-chipid.c1
-rw-r--r--drivers/soc/samsung/exynos-pmu.c84
-rw-r--r--drivers/soc/starfive/Kconfig6
-rw-r--r--drivers/soc/starfive/Makefile2
-rw-r--r--drivers/soc/starfive/socinfo/Kconfig13
-rw-r--r--drivers/soc/starfive/socinfo/Makefile2
-rw-r--r--drivers/soc/starfive/socinfo/jhb100-socinfo.c105
-rw-r--r--drivers/soc/tegra/cbb/tegra194-cbb.c2
-rw-r--r--drivers/soc/tegra/flowctrl.c7
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra.c12
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra30.c168
-rw-r--r--drivers/soc/tegra/fuse/fuse.h7
-rw-r--r--drivers/soc/tegra/fuse/speedo-tegra210.c22
-rw-r--r--drivers/soc/tegra/fuse/tegra-apbmisc.c51
-rw-r--r--drivers/soc/tegra/pmc.c165
-rw-r--r--drivers/soc/ti/knav_qmss_queue.c4
-rw-r--r--drivers/ufs/host/ufs-amd-versal2.c46
-rw-r--r--drivers/usb/host/fhci-hcd.c2
-rw-r--r--include/dt-bindings/arm/qcom,ids.h2
-rw-r--r--include/dt-bindings/clock/starfive,jhb100-crg.h554
-rw-r--r--include/dt-bindings/reset/starfive,jhb100-crg.h189
-rw-r--r--include/linux/device-id/apr.h21
-rw-r--r--include/linux/device-id/scmi.h17
-rw-r--r--include/linux/firmware/qcom/qcom_scm.h29
-rw-r--r--include/linux/firmware/xlnx-zynqmp-ufs.h8
-rw-r--r--include/linux/firmware/xlnx-zynqmp.h5
-rw-r--r--include/linux/fsl/mc.h2
-rw-r--r--include/linux/mod_devicetable.h1
-rw-r--r--include/linux/scmi_protocol.h20
-rw-r--r--include/linux/soc/qcom/apr.h4
-rw-r--r--include/linux/soc/qcom/geni-se.h2
-rw-r--r--include/linux/soc/qcom/llcc-qcom.h6
-rw-r--r--include/linux/soc/qcom/ubwc.h3
-rw-r--r--include/linux/soc/ti/k3-ringacc.h31
-rw-r--r--include/soc/fsl/qe/qe.h6
-rw-r--r--include/soc/tegra/fuse.h1
-rw-r--r--include/trace/events/scmi.h8
-rw-r--r--include/uapi/linux/tee.h40
-rw-r--r--lib/cache_maint.c4
-rw-r--r--scripts/mod/devicetable-offsets.c5
-rw-r--r--scripts/mod/file2alias.c12
140 files changed, 5824 insertions, 1043 deletions
diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
index f3f3feac4ce2..335a8e1a5a9e 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
@@ -32,6 +32,7 @@ properties:
- qcom,glymur-ctcu
- qcom,kaanapali-ctcu
- qcom,qcs8300-ctcu
+ - qcom,shikra-ctcu
- qcom,sm8750-ctcu
- qcom,x1e80100-ctcu
- const: qcom,sa8775p-ctcu
diff --git a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
index a1340226a0d0..2141e5d4de63 100644
--- a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
+++ b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
@@ -26,6 +26,7 @@ properties:
- qcom,hawi-llcc
- qcom,ipq5424-llcc
- qcom,kaanapali-llcc
+ - qcom,nord-llcc
- qcom,qcs615-llcc
- qcom,qcs8300-llcc
- qcom,qdu1000-llcc
@@ -56,11 +57,11 @@ properties:
reg:
minItems: 1
- maxItems: 14
+ maxItems: 18
reg-names:
minItems: 1
- maxItems: 14
+ maxItems: 18
interrupts:
maxItems: 1
@@ -355,6 +356,56 @@ allOf:
- const: llcc3_base
- const: llcc_broadcast_base
- const: llcc_broadcast_and_base
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,nord-llcc
+ then:
+ properties:
+ reg:
+ items:
+ - description: LLCC0 base register region
+ - description: LLCC1 base register region
+ - description: LLCC2 base register region
+ - description: LLCC3 base register region
+ - description: LLCC4 base register region
+ - description: LLCC5 base register region
+ - description: LLCC6 base register region
+ - description: LLCC7 base register region
+ - description: LLCC8 base register region
+ - description: LLCC9 base register region
+ - description: LLCC10 base register region
+ - description: LLCC11 base register region
+ - description: LLCC12 base register region
+ - description: LLCC13 base register region
+ - description: LLCC14 base register region
+ - description: LLCC15 base register region
+ - description: LLCC broadcast OR register region
+ - description: LLCC broadcast AND register region
+ reg-names:
+ items:
+ - const: llcc0_base
+ - const: llcc1_base
+ - const: llcc2_base
+ - const: llcc3_base
+ - const: llcc4_base
+ - const: llcc5_base
+ - const: llcc6_base
+ - const: llcc7_base
+ - const: llcc8_base
+ - const: llcc9_base
+ - const: llcc10_base
+ - const: llcc11_base
+ - const: llcc12_base
+ - const: llcc13_base
+ - const: llcc14_base
+ - const: llcc15_base
+ - const: llcc_broadcast_base
+ - const: llcc_broadcast_and_base
+
- if:
properties:
compatible:
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-per0crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-per0crg.yaml
new file mode 100644
index 000000000000..db43e03fd60c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-per0crg.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jhb100-per0crg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 Peripheral-0 Clock and Reset Generator
+
+maintainers:
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
+
+properties:
+ compatible:
+ const: starfive,jhb100-per0crg
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Main Oscillator (25 MHz)
+ - description: PLL6
+ - description: Configure 400MHz
+ - description: Configure 800MHZ
+ - description: Non Coherent NOC Initiator
+ - description: Non Coherent NOC Target
+
+ clock-names:
+ items:
+ - const: osc
+ - const: pll6
+ - const: cfg_400
+ - const: cfg_800
+ - const: ncnoc_init
+ - const: ncnoc_targ
+
+ '#clock-cells':
+ const: 1
+ description:
+ See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
+
+ '#reset-cells':
+ const: 1
+ description:
+ See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+ - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@11a08000 {
+ compatible = "starfive,jhb100-per0crg";
+ reg = <0x11a08000 0x1000>;
+ clocks = <&osc>, <&pll6>, <&sys0crg 71>,
+ <&sys0crg 72>, <&sys0crg 70>,
+ <&sys2crg 23>;
+ clock-names = "osc", "pll6", "cfg_400",
+ "cfg_800", "ncnoc_init",
+ "ncnoc_targ";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-per1crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-per1crg.yaml
new file mode 100644
index 000000000000..c72a355ceb34
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-per1crg.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jhb100-per1crg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 Peripheral-1 Clock and Reset Generator
+
+maintainers:
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
+
+properties:
+ compatible:
+ const: starfive,jhb100-per1crg
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: PLL7
+ - description: Non Coherent NOC Initiator
+ - description: Configure 800MHz
+ - description: Non Coherent NOC Target
+ - description: Configure 143MHz
+
+ clock-names:
+ items:
+ - const: pll7
+ - const: ncnoc_init
+ - const: cfg_800
+ - const: ncnoc_targ
+ - const: cfg_143
+
+ '#clock-cells':
+ const: 1
+ description:
+ See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
+
+ '#reset-cells':
+ const: 1
+ description:
+ See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+ - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@11b40000 {
+ compatible = "starfive,jhb100-per1crg";
+ reg = <0x11b40000 0x1000>;
+ clocks = <&pll7>,
+ <&sys0crg 68>,
+ <&sys0crg 69>,
+ <&sys2crg 19>,
+ <&sys2crg 22>;
+ clock-names = "pll7", "ncnoc_init",
+ "cfg_800", "ncnoc_targ",
+ "cfg_143";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-per2crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-per2crg.yaml
new file mode 100644
index 000000000000..175654645221
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-per2crg.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jhb100-per2crg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 Peripheral-2 Clock and Reset Generator
+
+maintainers:
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
+
+properties:
+ compatible:
+ const: starfive,jhb100-per2crg
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Non Coherent NOC Initiator
+ - description: Configure 400MHz
+ - description: Configure 125MHz
+ - description: GMAC2 RGMII RX
+ - description: GMAC2 RMII Reference
+ - description: GMAC3 SGMII TX
+ - description: GMAC3 SGMII RX
+ - description: Main Oscillator (25 MHz)
+
+ clock-names:
+ items:
+ - const: ncnoc_init
+ - const: cfg_400
+ - const: cfg_125
+ - const: gmac2_rgmii_rx
+ - const: gmac2_rmii_ref
+ - const: gmac3_sgmii_tx
+ - const: gmac3_sgmii_rx
+ - const: osc
+
+ '#clock-cells':
+ const: 1
+ description:
+ See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
+
+ '#reset-cells':
+ const: 1
+ description:
+ See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+ - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@11bc0000 {
+ compatible = "starfive,jhb100-per2crg";
+ reg = <0x11bc0000 0x1000>;
+ clocks = <&sys0crg 52>, <&sys0crg 54>, <&sys0crg 55>,
+ <&per2_gmac2_rgmii_rx>, <&per2_gmac2_rmii_ref>,
+ <&per2_gmac3_sgmii_tx>, <&per2_gmac3_sgmii_rx>,
+ <&osc>;
+ clock-names = "ncnoc_init", "cfg_400", "cfg_125",
+ "gmac2_rgmii_rx", "gmac2_rmii_ref",
+ "gmac3_sgmii_tx", "gmac3_sgmii_rx",
+ "osc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-per3crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-per3crg.yaml
new file mode 100644
index 000000000000..2c3b9f4146b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-per3crg.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jhb100-per3crg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 Peripheral-3 Clock and Reset Generator
+
+maintainers:
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
+
+properties:
+ compatible:
+ const: starfive,jhb100-per3crg
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Non Coherent NOC Initiator
+ - description: Non Coherent NOC Target
+ - description: Configure 125MHz
+ - description: GMAC0 RMII Reference clock
+ - description: GMAC1 SGMII TX
+ - description: GMAC1 SGMII RX
+ - description: Main Oscillator (25 MHz)
+
+ clock-names:
+ items:
+ - const: ncnoc_init
+ - const: ncnoc_targ
+ - const: cfg_125
+ - const: gmac0_rmii_rclki
+ - const: gmac1_sgmii_tx
+ - const: gmac1_sgmii_rx
+ - const: osc
+
+ '#clock-cells':
+ const: 1
+ description:
+ See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
+
+ '#reset-cells':
+ const: 1
+ description:
+ See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+ - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@11c40000 {
+ compatible = "starfive,jhb100-per3crg";
+ reg = <0x11c40000 0x1000>;
+ clocks = <&sys0crg 65>,
+ <&sys1crg 18>,
+ <&sys1crg 19>,
+ <&per3_gmac0_rmii_rclki>,
+ <&per3_gmac1_sgmii_tx>,
+ <&per3_gmac1_sgmii_rx>,
+ <&osc>;
+ clock-names = "ncnoc_init", "ncnoc_targ", "cfg_125",
+ "gmac0_rmii_rclki", "gmac1_sgmii_tx",
+ "gmac1_sgmii_rx", "osc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml
new file mode 100644
index 000000000000..cf1b0175b158
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jhb100-sys0crg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 System-0 Clock and Reset Generator
+
+maintainers:
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
+
+properties:
+ compatible:
+ const: starfive,jhb100-sys0crg
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Main Oscillator (25 MHz)
+ - description: PLL0
+ - description: PLL1
+ - description: PLL2
+
+ clock-names:
+ items:
+ - const: osc
+ - const: pll0
+ - const: pll1
+ - const: pll2
+
+ '#clock-cells':
+ const: 1
+ description:
+ See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
+
+ '#reset-cells':
+ const: 1
+ description:
+ See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+ - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@13000000 {
+ compatible = "starfive,jhb100-sys0crg";
+ reg = <0x13000000 0x4000>;
+ clocks = <&osc>, <&pll0>, <&pll1>,
+ <&syspll 0>;
+ clock-names = "osc", "pll0", "pll1", "pll2";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-sys1crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys1crg.yaml
new file mode 100644
index 000000000000..70cbfa38c100
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys1crg.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jhb100-sys1crg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 System-1 Clock and Reset Generator
+
+maintainers:
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
+
+properties:
+ compatible:
+ const: starfive,jhb100-sys1crg
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Main Oscillator (25 MHz)
+ - description: PLL0
+ - description: PLL1
+ - description: PLL2
+ - description: PLL4
+ - description: PLL5
+ - description: NPU Non Coherent NOC Initiator
+
+ clock-names:
+ items:
+ - const: osc
+ - const: pll0
+ - const: pll1
+ - const: pll2
+ - const: pll4
+ - const: pll5
+ - const: npu_ncnoc_init
+
+ '#clock-cells':
+ const: 1
+ description:
+ See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
+
+ '#reset-cells':
+ const: 1
+ description:
+ See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+ - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@13004000 {
+ compatible = "starfive,jhb100-sys1crg";
+ reg = <0x13004000 0x4000>;
+ clocks = <&osc>, <&pll0>, <&pll1>,
+ <&syspll 0>, <&syspll 2>,
+ <&syspll 3>, <&sys0crg 61>;
+ clock-names = "osc", "pll0", "pll1", "pll2",
+ "pll4", "pll5", "npu_ncnoc_init";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml
new file mode 100644
index 000000000000..a63809c72e2a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jhb100-sys2crg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 System-2 Clock and Reset Generator
+
+maintainers:
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
+
+properties:
+ compatible:
+ const: starfive,jhb100-sys2crg
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Main Oscillator (25 MHz)
+ - description: PLL1
+ - description: GPU0 Non Coherent NOC Initiator
+ - description: GPU1 Non Coherent NOC Initiator
+
+ clock-names:
+ items:
+ - const: osc
+ - const: pll1
+ - const: gpu0_ncnoc_init
+ - const: gpu1_ncnoc_init
+
+ '#clock-cells':
+ const: 1
+ description:
+ See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices.
+
+ '#reset-cells':
+ const: 1
+ description:
+ See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+ - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@13008000 {
+ compatible = "starfive,jhb100-sys2crg";
+ reg = <0x13008000 0x4000>;
+ clocks = <&osc>, <&pll1>, <&sys0crg 73>,
+ <&sys0crg 74>;
+ clock-names = "osc", "pll1", "gpu0_ncnoc_init",
+ "gpu1_ncnoc_init";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
index 037d4ad8f718..40a267c54b00 100644
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
@@ -37,6 +37,7 @@ properties:
- qcom,scm-ipq9574
- qcom,scm-ipq9650
- qcom,scm-kaanapali
+ - qcom,scm-kuno
- qcom,scm-maili
- qcom,scm-mdm9607
- qcom,scm-milos
@@ -44,6 +45,7 @@ properties:
- qcom,scm-msm8660
- qcom,scm-msm8916
- qcom,scm-msm8937
+ - qcom,scm-msm8952
- qcom,scm-msm8953
- qcom,scm-msm8960
- qcom,scm-msm8974
@@ -152,6 +154,7 @@ allOf:
- qcom,scm-msm8660
- qcom,scm-msm8916
- qcom,scm-msm8937
+ - qcom,scm-msm8952
- qcom,scm-msm8953
- qcom,scm-msm8960
- qcom,scm-msm8974
@@ -198,6 +201,7 @@ allOf:
- qcom,scm-msm8226
- qcom,scm-msm8916
- qcom,scm-msm8937
+ - qcom,scm-msm8952
- qcom,scm-msm8953
- qcom,scm-msm8974
- qcom,scm-msm8976
diff --git a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml
index b9cdfe52b62f..619faf33214b 100644
--- a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml
+++ b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml
@@ -25,6 +25,7 @@ properties:
- items:
- enum:
- samsung,exynos2200-chipid
+ - samsung,exynos5515-chipid
- samsung,exynos7885-chipid
- samsung,exynos8895-chipid
- samsung,exynos9610-chipid
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml
index 21b4e04727de..f6969910bded 100644
--- a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml
+++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml
@@ -50,6 +50,7 @@ properties:
- enum:
- qcom,eliza-llcc-bwmon
- qcom,hawi-llcc-bwmon
+ - qcom,milos-cpu-bwmon
- qcom,qcs615-llcc-bwmon
- qcom,qcs8300-llcc-bwmon
- qcom,sa8775p-llcc-bwmon
diff --git a/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml
index 03359479d926..2185920e1b5d 100644
--- a/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml
+++ b/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml
@@ -21,6 +21,7 @@ properties:
- qcom,glymur-cpucp-mbox
- qcom,hawi-cpucp-mbox
- qcom,kaanapali-cpucp-mbox
+ - qcom,maili-cpucp-mbox
- qcom,nord-cpucp-mbox
- qcom,sm8750-cpucp-mbox
- const: qcom,x1e80100-cpucp-mbox
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
index 0762e0ff66ef..33c989f7fc33 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
@@ -16,7 +16,7 @@ description: |
MediaTek SMI have two generations of HW architecture, here is the list
which generation the SoCs use:
generation 1: mt2701 and mt7623.
- generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8188, mt8192 and mt8195.
+ generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8188, mt8189, mt8192 and mt8195.
There's slight differences between the two SMI, for generation 2, the
register which control the iommu port is at each larb's register base. But
@@ -25,6 +25,21 @@ description: |
SMI generation 1 to transform the smi clock into emi clock domain, but that is
not needed for SMI generation 2.
+ The smi-common connects with smi-larb and IOMMU. The maximum inputs number of
+ a smi-common is 8. In SMI generation 2, the engines number may be over 8.
+ In this case, we use a smi-sub-common to merge some larbs.
+ The block diagram something is like:
+
+ IOMMU
+ | |
+ smi-common
+ ---------------------------
+ | | ...
+ larb0 sub-common ... <-max number is 8
+ ----------------
+ | | ...
+ larb1 larbX ... <-max number is 8
+
properties:
compatible:
oneOf:
@@ -40,6 +55,8 @@ properties:
- mediatek,mt8186-smi-common
- mediatek,mt8188-smi-common-vdo
- mediatek,mt8188-smi-common-vpp
+ - mediatek,mt8189-smi-common
+ - mediatek,mt8189-smi-sub-common
- mediatek,mt8192-smi-common
- mediatek,mt8195-smi-common-vdo
- mediatek,mt8195-smi-common-vpp
@@ -108,6 +125,7 @@ allOf:
compatible:
contains:
enum:
+ - mediatek,mt8189-smi-sub-common
- mediatek,mt8195-smi-sub-common
then:
required:
@@ -157,6 +175,7 @@ allOf:
- mediatek,mt6795-smi-common
- mediatek,mt8167-smi-common
- mediatek,mt8173-smi-common
+ - mediatek,mt8189-smi-common
then:
properties:
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
index 2e7fac4b5094..9a5dafd7c07e 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -27,6 +27,7 @@ properties:
- mediatek,mt8183-smi-larb
- mediatek,mt8186-smi-larb
- mediatek,mt8188-smi-larb
+ - mediatek,mt8189-smi-larb
- mediatek,mt8192-smi-larb
- mediatek,mt8195-smi-larb
@@ -85,6 +86,7 @@ allOf:
- mediatek,mt8183-smi-larb
- mediatek,mt8186-smi-larb
- mediatek,mt8188-smi-larb
+ - mediatek,mt8189-smi-larb
- mediatek,mt8195-smi-larb
then:
@@ -119,6 +121,7 @@ allOf:
- mediatek,mt6779-smi-larb
- mediatek,mt8186-smi-larb
- mediatek,mt8188-smi-larb
+ - mediatek,mt8189-smi-larb
- mediatek,mt8192-smi-larb
- mediatek,mt8195-smi-larb
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index 945a168b613d..33e0b1bad5ab 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -107,6 +107,7 @@ properties:
- nxp,s32g3-gpr
- qcom,apq8064-mmss-sfpb
- qcom,apq8064-sps-sic
+ - qcom,msm8960-sps-sic
- rockchip,px30-qos
- rockchip,rk3036-qos
- rockchip,rk3066-qos
diff --git a/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-gx-clk-measure.yaml b/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-gx-clk-measure.yaml
index b1200e6940ac..16893f427532 100644
--- a/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-gx-clk-measure.yaml
+++ b/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-gx-clk-measure.yaml
@@ -16,15 +16,21 @@ maintainers:
properties:
compatible:
enum:
- - amlogic,meson-gx-clk-measure
- - amlogic,meson8-clk-measure
- - amlogic,meson8b-clk-measure
+ - amlogic,a1-clk-measure
+ - amlogic,a4-clk-measure
+ - amlogic,a5-clk-measure
+ - amlogic,a9-clk-measure
+ - amlogic,c3-clk-measure
- amlogic,meson-axg-clk-measure
- amlogic,meson-g12a-clk-measure
+ - amlogic,meson-gx-clk-measure
- amlogic,meson-sm1-clk-measure
- - amlogic,c3-clk-measure
+ - amlogic,meson8-clk-measure
+ - amlogic,meson8b-clk-measure
- amlogic,s4-clk-measure
- - amlogic,a1-clk-measure
+ - amlogic,s6-clk-measure
+ - amlogic,s7-clk-measure
+ - amlogic,s7d-clk-measure
- amlogic,t7-clk-measure
reg:
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml
index e51acdcaafaf..01250b556985 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml
@@ -120,7 +120,9 @@ allOf:
properties:
qcom,glink-channels:
items:
- - const: adsp_apps
+ - enum:
+ - adsp_apps
+ - modem_apps
power-domains: false
else:
properties:
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom-stats.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom-stats.yaml
index 686a7ef2f48a..b384a5983d43 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom-stats.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom-stats.yaml
@@ -18,15 +18,22 @@ description:
properties:
compatible:
- enum:
- - qcom,rpmh-stats
- - qcom,sdm845-rpmh-stats
- - qcom,rpm-stats
- # For older RPM firmware versions with fixed offset for the sleep stats
- - qcom,apq8084-rpm-stats
- - qcom,msm8226-rpm-stats
- - qcom,msm8916-rpm-stats
- - qcom,msm8974-rpm-stats
+ oneOf:
+ - enum:
+ - qcom,rpmh-stats
+ - qcom,sdm845-rpmh-stats
+ - qcom,rpm-stats
+ # For older RPM firmware versions with fixed offset for the sleep stats
+ - qcom,apq8084-rpm-stats
+ - qcom,msm8226-rpm-stats
+ - qcom,msm8916-rpm-stats
+ - qcom,msm8974-rpm-stats
+ # SoC-specific compatibles that also read subsystem-level stats,
+ # falling back to "qcom,rpm-stats" for SoC-level stats only
+ - items:
+ - enum:
+ - qcom,shikra-rpm-stats
+ - const: qcom,rpm-stats
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/soc/starfive/starfive,jhb100-syscon.yaml b/Documentation/devicetree/bindings/soc/starfive/starfive,jhb100-syscon.yaml
new file mode 100644
index 000000000000..000f53acab34
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/starfive/starfive,jhb100-syscon.yaml
@@ -0,0 +1,115 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/starfive/starfive,jhb100-syscon.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 SoC system controller
+
+maintainers:
+ - Kevin Xie <kevin.xie@starfivetech.com>
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
+
+description:
+ The StarFive JHB100 SoC system controller contains MMIO registers used by
+ other hardware modules (e.g., PLL, eMMC, PCIe). These modules access
+ specific register offsets, bit masks, and shifts within the system
+ controller region for configuration and status.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - starfive,jhb100-b2h-syscon
+ - starfive,jhb100-gpu-syscon
+ - starfive,jhb100-h2b-syscon
+ - starfive,jhb100-host-syscon
+ - starfive,jhb100-husb-syscon
+ - starfive,jhb100-husbcmn-syscon
+ - starfive,jhb100-husbd-syscon
+ - starfive,jhb100-npu-syscon
+ - starfive,jhb100-pcieep-ecsr-syscon
+ - starfive,jhb100-pcierp-ecsr-syscon
+ - starfive,jhb100-pcierp-syscon
+ - starfive,jhb100-per0-syscon
+ - starfive,jhb100-per1-syscon
+ - starfive,jhb100-per2-syscon
+ - starfive,jhb100-per3-syscon
+ - starfive,jhb100-sfc-filter-syscon
+ - starfive,jhb100-strap-syscon
+ - starfive,jhb100-sys0-syscon
+ - starfive,jhb100-sys1-syscon
+ - starfive,jhb100-sys2-syscon
+ - starfive,jhb100-usb-syscon
+ - starfive,jhb100-vout-syscon
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+ '#reset-cells':
+ const: 1
+
+required:
+ - compatible
+ - reg
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - starfive,jhb100-per0-syscon
+ - starfive,jhb100-per1-syscon
+ - starfive,jhb100-sys0-syscon
+ then:
+ required:
+ - clocks
+ - '#clock-cells'
+ else:
+ properties:
+ clocks: false
+ '#clock-cells': false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: starfive,jhb100-pcierp-syscon
+ then:
+ required:
+ - '#reset-cells'
+ else:
+ properties:
+ '#reset-cells': false
+
+additionalProperties: false
+
+examples:
+ - |
+ syscon@13010000 {
+ compatible = "starfive,jhb100-sys0-syscon", "syscon";
+ reg = <0x13010000 0x2000>;
+ clocks = <&osc>;
+ #clock-cells = <1>;
+ };
+
+ syscon@13014000 {
+ compatible = "starfive,jhb100-sys1-syscon", "syscon";
+ reg = <0x13014000 0x4000>;
+ };
+
+ syscon@11719000 {
+ compatible = "starfive,jhb100-pcierp-syscon", "syscon";
+ reg = <0x11719000 0x1000>;
+ #reset-cells = <1>;
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml
index 1593a1183a36..44c864fd5fc7 100644
--- a/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml
+++ b/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml
@@ -27,6 +27,7 @@ properties:
- enum:
- qcom,hawi-spmi-pmic-arb
- qcom,kaanapali-spmi-pmic-arb
+ - qcom,maili-spmi-pmic-arb
- const: qcom,glymur-spmi-pmic-arb
- enum:
- qcom,glymur-spmi-pmic-arb
diff --git a/Documentation/devicetree/bindings/sram/qcom,imem.yaml b/Documentation/devicetree/bindings/sram/qcom,imem.yaml
index b4f082f2af3a..2f120376a8f4 100644
--- a/Documentation/devicetree/bindings/sram/qcom,imem.yaml
+++ b/Documentation/devicetree/bindings/sram/qcom,imem.yaml
@@ -18,7 +18,6 @@ properties:
items:
- enum:
- qcom,apq8064-imem
- - qcom,ipq5424-imem
- qcom,msm8226-imem
- qcom,msm8974-imem
- qcom,msm8976-imem
diff --git a/Documentation/devicetree/bindings/sram/sram.yaml b/Documentation/devicetree/bindings/sram/sram.yaml
index b83fc6831947..6ee0b1464722 100644
--- a/Documentation/devicetree/bindings/sram/sram.yaml
+++ b/Documentation/devicetree/bindings/sram/sram.yaml
@@ -37,12 +37,14 @@ properties:
- qcom,eliza-imem
- qcom,glymur-imem
- qcom,hawi-imem
+ - qcom,ipq5424-imem
- qcom,kaanapali-imem
- qcom,maili-imem
- qcom,milos-imem
- qcom,rpm-msg-ram
- qcom,shikra-imem
- rockchip,rk3288-pmu-sram
+ - samsung,exynos850-acpm-sram
reg:
maxItems: 1
@@ -159,6 +161,7 @@ if:
enum:
- qcom,rpm-msg-ram
- rockchip,rk3288-pmu-sram
+ - samsung,exynos850-acpm-sram
then:
required:
- "#address-cells"
diff --git a/MAINTAINERS b/MAINTAINERS
index 43e47cadc158..763442505f5e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3444,6 +3444,7 @@ F: include/linux/soc/qcom/
ARM/QUALCOMM SUPPORT
M: Bjorn Andersson <andersson@kernel.org>
M: Konrad Dybcio <konradybcio@kernel.org>
+R: Abel Vesa <abelvesa@kernel.org>
L: linux-arm-msm@vger.kernel.org
S: Maintained
C: irc://irc.oftc.net/linux-msm
@@ -26774,6 +26775,7 @@ F: drivers/pmdomain/arm/
F: drivers/powercap/arm_scmi_powercap.c
F: drivers/regulator/scmi-regulator.c
F: drivers/reset/reset-scmi.c
+F: include/linux/device-id/scmi.h
F: include/linux/sc[mp]i_protocol.h
F: include/trace/events/scmi.h
F: include/uapi/linux/virtio_scmi.h
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 50c3a425d140..2193e1ab9847 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -25,7 +25,7 @@
#define AT91_PM_ULP1 0x03
#define AT91_PM_BACKUP 0x04
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
struct at91_pm_data {
void __iomem *pmc;
void __iomem *ramc[2];
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a8507da58eeb..d5ccf1d040c6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -197,6 +197,7 @@ config ARM64
if DYNAMIC_FTRACE_WITH_ARGS
select HAVE_SAMPLE_FTRACE_DIRECT
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
+ select HAVE_SHARED_GPIOS
select HAVE_BUILDTIME_MCOUNT_SORT
select HAVE_EFFICIENT_UNALIGNED_ACCESS
select HAVE_GUP_FAST
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index d09bced3b0f5..49dcd7be82ce 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -336,7 +336,6 @@ config ARCH_QCOM
select GPIOLIB
select PINCTRL
select HAVE_PWRCTRL if PCI
- select HAVE_SHARED_GPIOS
help
This enables support for the ARMv8 based Qualcomm chipsets.
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 7f2baf057128..435952602d06 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -167,9 +167,12 @@ static int __cci_ace_get_port(struct device_node *dn, int type)
cci_portn = of_parse_phandle(dn, "cci-control-port", 0);
for (i = 0; i < nb_cci_ports; i++) {
ace_match = ports[i].type == type;
- if (ace_match && cci_portn == ports[i].dn)
+ if (ace_match && cci_portn == ports[i].dn) {
+ of_node_put(cci_portn);
return i;
+ }
}
+ of_node_put(cci_portn);
return -ENODEV;
}
@@ -199,6 +202,7 @@ static void cci_ace_init_ports(void)
continue;
port = __cci_ace_get_port(cpun, ACE_PORT);
+ of_node_put(cpun);
if (port < 0)
continue;
diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index 66a4fa73c5b8..0c37b6780c84 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -11,6 +11,7 @@
#define pr_fmt(fmt) "fsl-mc: " fmt
#include <linux/module.h>
+#include <linux/fwnode.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/ioport.h>
@@ -797,6 +798,10 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
}
dev_set_name(&mc_dev->dev, "%s.%d", obj_desc->type, obj_desc->id);
+ mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK;
+ mc_dev->dev.dma_mask = &mc_dev->dma_mask;
+ mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask;
+
if (strcmp(obj_desc->type, "dprc") == 0) {
struct fsl_mc_io *mc_io2;
@@ -838,9 +843,6 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
* parent's ICID.
*/
mc_dev->icid = parent_mc_dev->icid;
- mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK;
- mc_dev->dev.dma_mask = &mc_dev->dma_mask;
- mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask;
}
/*
@@ -1032,6 +1034,20 @@ static int fsl_mc_firmware_check(struct platform_device *pdev)
return 0;
}
+static void fsl_mc_purge_dpmac_fwnode_links(struct device *dev)
+{
+ struct device_node *dpmacs, *child;
+
+ dpmacs = of_get_child_by_name(dev->of_node, "dpmacs");
+ if (!dpmacs)
+ return;
+
+ for_each_child_of_node(dpmacs, child)
+ fwnode_links_purge(of_fwnode_handle(child));
+
+ of_node_put(dpmacs);
+}
+
/*
* fsl_mc_bus_probe - callback invoked when the root MC bus is being
* added
@@ -1133,6 +1149,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
&mc->num_translation_ranges);
if (error < 0)
goto error_cleanup_mc_io;
+
+ fsl_mc_purge_dpmac_fwnode_links(&pdev->dev);
}
error = dprc_get_container_id(mc_io, 0, &container_id);
@@ -1264,35 +1282,43 @@ static int __init fsl_mc_bus_driver_init(void)
error = bus_register(&fsl_mc_bus_type);
if (error < 0) {
pr_err("bus type registration failed: %d\n", error);
- goto error_cleanup_cache;
+ return error;
}
- error = platform_driver_register(&fsl_mc_bus_driver);
- if (error < 0) {
- pr_err("platform_driver_register() failed: %d\n", error);
+ error = bus_register_notifier(&platform_bus_type, &fsl_mc_nb);
+ if (error < 0)
goto error_cleanup_bus;
- }
+
+ return 0;
+
+error_cleanup_bus:
+ bus_unregister(&fsl_mc_bus_type);
+ return error;
+}
+postcore_initcall(fsl_mc_bus_driver_init);
+
+static int __init fsl_mc_bus_drivers_init(void)
+{
+ int error;
error = dprc_driver_init();
if (error < 0)
- goto error_cleanup_driver;
+ return error;
error = fsl_mc_allocator_driver_init();
if (error < 0)
goto error_cleanup_dprc_driver;
- return bus_register_notifier(&platform_bus_type, &fsl_mc_nb);
+ error = platform_driver_register(&fsl_mc_bus_driver);
+ if (error < 0) {
+ pr_err("platform_driver_register() failed: %d\n", error);
+ goto error_cleanup_dprc_driver;
+ }
+
+ return 0;
error_cleanup_dprc_driver:
dprc_driver_exit();
-
-error_cleanup_driver:
- platform_driver_unregister(&fsl_mc_bus_driver);
-
-error_cleanup_bus:
- bus_unregister(&fsl_mc_bus_type);
-
-error_cleanup_cache:
return error;
}
-postcore_initcall(fsl_mc_bus_driver_init);
+subsys_initcall_sync(fsl_mc_bus_drivers_init);
diff --git a/drivers/bus/fsl-mc/fsl-mc-msi.c b/drivers/bus/fsl-mc/fsl-mc-msi.c
index be38b43803de..7d760bfa63c1 100644
--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -57,7 +57,7 @@ static void fsl_mc_write_msi_msg(struct msi_desc *msi_desc, struct msi_msg *msg)
}
} else {
/*
- * IRQ is for for a child device of mc_bus_dev
+ * IRQ is for a child device of mc_bus_dev
*/
error = dprc_set_obj_irq(mc_bus_dev->mc_io,
MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
diff --git a/drivers/cache/hisi_soc_hha.c b/drivers/cache/hisi_soc_hha.c
index 756c43398515..f0f6c0354108 100644
--- a/drivers/cache/hisi_soc_hha.c
+++ b/drivers/cache/hisi_soc_hha.c
@@ -170,7 +170,7 @@ static void hisi_soc_hha_remove(struct platform_device *pdev)
}
static const struct acpi_device_id hisi_soc_hha_ids[] = {
- { "HISI0511", },
+ { .id = "HISI0511" },
{ }
};
MODULE_DEVICE_TABLE(acpi, hisi_soc_hha_ids);
diff --git a/drivers/cache/sifive_ccache.c b/drivers/cache/sifive_ccache.c
index 2acb8bdf06d5..71d3f94987fa 100644
--- a/drivers/cache/sifive_ccache.c
+++ b/drivers/cache/sifive_ccache.c
@@ -275,7 +275,7 @@ static int sifive_ccache_probe(struct platform_device *pdev)
rc = devm_request_irq(dev, g_irq[i], ccache_int_handler, 0, "ccache_ecc", NULL);
if (rc)
- return dev_err_probe(dev, rc, "Could not request IRQ %d\n", g_irq[i]);
+ return rc;
}
return 0;
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index e060edbe7e83..25197197db8e 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -9,14 +9,15 @@
#include <linux/types.h>
#include <linux/module.h>
-#include <linux/of.h>
+#include <linux/property.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/device.h>
#include "common.h"
-#define SCMI_UEVENT_MODALIAS_FMT "%s:%02x:%s"
+#define SCMI_UEVENT_MODALIAS_FMT SCMI_MODULE_PREFIX "%02x:%s"
BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
@@ -185,7 +186,7 @@ static int scmi_protocol_table_register(const struct scmi_device_id *id_table)
const struct scmi_device_id *entry;
int ret;
- for (entry = id_table; entry->name; entry++) {
+ for (entry = id_table; entry->name[0]; entry++) {
ret = scmi_protocol_device_request(entry);
if (ret)
goto err_unrequest;
@@ -205,7 +206,7 @@ scmi_protocol_table_unregister(const struct scmi_device_id *id_table)
{
const struct scmi_device_id *entry;
- for (entry = id_table; entry->name; entry++)
+ for (entry = id_table; entry->name[0]; entry++)
scmi_protocol_device_unrequest(entry);
}
@@ -219,10 +220,10 @@ static int __scmi_dev_match_by_id_table(struct scmi_device *scmi_dev,
const struct scmi_device_id *id_table,
bool skip_transport)
{
- if (!id_table || !id_table->name)
+ if (!id_table || !id_table->name[0])
return 0;
- for (; id_table->protocol_id && id_table->name; id_table++)
+ for (; id_table->protocol_id && id_table->name[0]; id_table++)
if (id_table->protocol_id == scmi_dev->protocol_id &&
!(skip_transport && scmi_device_is_transport(scmi_dev)) &&
!strcmp(id_table->name, scmi_dev->name))
@@ -266,7 +267,7 @@ scmi_child_dev_find_get(struct device *parent, int prot_id, const char *name)
struct device *dev;
id_table[0].protocol_id = prot_id;
- id_table[0].name = name;
+ strscpy(id_table[0].name, name, sizeof(id_table[0].name));
dev = device_find_child(parent, &id_table, scmi_match_by_id_table);
if (!dev)
@@ -300,8 +301,7 @@ static int scmi_device_uevent(const struct device *dev, struct kobj_uevent_env *
const struct scmi_device *scmi_dev = to_scmi_dev(dev);
return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT,
- dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
- scmi_dev->name);
+ scmi_dev->protocol_id, scmi_dev->name);
}
static ssize_t modalias_show(struct device *dev,
@@ -309,9 +309,8 @@ static ssize_t modalias_show(struct device *dev,
{
struct scmi_device *scmi_dev = to_scmi_dev(dev);
- return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT,
- dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
- scmi_dev->name);
+ return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT "\n",
+ scmi_dev->protocol_id, scmi_dev->name);
}
static DEVICE_ATTR_RO(modalias);
@@ -429,17 +428,16 @@ static void scmi_device_release(struct device *dev)
struct scmi_device *scmi_dev = to_scmi_dev(dev);
scmi_device_release_resources(scmi_dev);
- of_node_put(dev->of_node);
+ fwnode_handle_put(dev_fwnode(dev));
kfree_const(scmi_dev->name);
kfree(scmi_dev);
}
static void __scmi_device_destroy(struct scmi_device *scmi_dev)
{
- pr_debug("(%pOF) Destroying SCMI device '%s' for protocol 0x%x (%s)\n",
- scmi_dev->dev.parent->of_node,
- dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
- scmi_dev->name);
+ pr_debug("(%pfwf) Destroying SCMI device '%s' for protocol 0x%x (%s)\n",
+ dev_fwnode(&scmi_dev->dev), dev_name(&scmi_dev->dev),
+ scmi_dev->protocol_id, scmi_dev->name);
device_del(&scmi_dev->dev);
scmi_device_release_resources(scmi_dev);
@@ -447,7 +445,7 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
}
static struct scmi_device *
-__scmi_device_create(struct device_node *np, struct device *parent,
+__scmi_device_create(struct fwnode_handle *fwnode, struct device *parent,
int protocol, const char *name)
{
int id, retval;
@@ -458,7 +456,7 @@ __scmi_device_create(struct device_node *np, struct device *parent,
* If the same protocol/name device already exist under the same parent
* (i.e. SCMI instance) just return the existent device.
* This avoids any race between the SCMI driver, creating devices for
- * each DT defined protocol at probe time, and the concurrent
+ * each fwnode defined protocol at probe time, and the concurrent
* registration of SCMI drivers.
*/
scmi_dev = scmi_child_dev_find_get(parent, protocol, name);
@@ -495,7 +493,7 @@ __scmi_device_create(struct device_node *np, struct device *parent,
scmi_dev->id = id;
scmi_dev->dev.parent = parent;
- device_set_node(&scmi_dev->dev, of_fwnode_handle(of_node_get(np)));
+ device_set_node(&scmi_dev->dev, fwnode_handle_get(fwnode));
scmi_dev->dev.bus = &scmi_bus_type;
scmi_dev->dev.release = scmi_device_release;
dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
@@ -504,8 +502,8 @@ __scmi_device_create(struct device_node *np, struct device *parent,
if (retval)
goto put_dev;
- pr_debug("(%pOF) Created SCMI device '%s' for protocol 0x%x (%s)\n",
- parent->of_node, dev_name(&scmi_dev->dev), protocol, name);
+ pr_debug("(%pfwf) Created SCMI device '%s' - protocol 0x%x (%s)\n",
+ fwnode, dev_name(&scmi_dev->dev), protocol, name);
return scmi_dev;
put_dev:
@@ -521,23 +519,51 @@ free_dev:
}
static struct scmi_device *
-_scmi_device_create(struct device_node *np, struct device *parent,
+_scmi_device_create(struct fwnode_handle *fwnode, struct device *parent,
int protocol, const char *name)
{
struct scmi_device *sdev;
- sdev = __scmi_device_create(np, parent, protocol, name);
+ sdev = __scmi_device_create(fwnode, parent, protocol, name);
if (!sdev)
- pr_err("(%pOF) Failed to create device for protocol 0x%x (%s)\n",
- parent->of_node, protocol, name);
+ pr_err("(%pfwf) Failed to create device - protocol 0x%x (%s)\n",
+ fwnode, protocol, name);
return sdev;
}
+/* Standard protocols table */
+static const struct scmi_device_id scmi_std_id_table[] = {
+ { SCMI_PROTOCOL_POWER, "genpd" },
+ { SCMI_PROTOCOL_SYSTEM, "syspower" },
+ { SCMI_PROTOCOL_PERF, "perf" },
+ { SCMI_PROTOCOL_PERF, "cpufreq" },
+ { SCMI_PROTOCOL_CLOCK, "clocks" },
+ { SCMI_PROTOCOL_SENSOR, "hwmon" },
+ { SCMI_PROTOCOL_SENSOR, "iiodev" },
+ { SCMI_PROTOCOL_RESET, "reset" },
+ { SCMI_PROTOCOL_VOLTAGE, "regulator" },
+ { SCMI_PROTOCOL_POWERCAP, "powercap" },
+ { SCMI_PROTOCOL_PINCTRL, "pinctrl" },
+ { SCMI_PROTOCOL_PINCTRL, "pinctrl-imx" },
+ { },
+};
+
+static bool scmi_device_id_in_std_id_table(const struct scmi_device_id *id)
+{
+ for (int i = 0; scmi_std_id_table[i].name[0]; i++) {
+ if (scmi_std_id_table[i].protocol_id == id->protocol_id &&
+ !strcmp(scmi_std_id_table[i].name, id->name))
+ return true;
+ }
+
+ return false;
+}
+
/**
* scmi_device_create - A method to create one or more SCMI devices
*
- * @np: A reference to the device node to use for the new device(s)
+ * @fwnode: A reference to the device node to use for the new device(s)
* @parent: The parent device to use identifying a specific SCMI instance
* @protocol: The SCMI protocol to be associated with this device
* @name: The requested-name of the device to be created; this is optional
@@ -557,30 +583,47 @@ _scmi_device_create(struct device_node *np, struct device *parent,
* could have been potentially created for a whole protocol, unless no
* device was found to have been requested for that specific protocol.
*/
-struct scmi_device *scmi_device_create(struct device_node *np,
+struct scmi_device *scmi_device_create(struct fwnode_handle *fwnode,
struct device *parent, int protocol,
const char *name)
{
struct list_head *phead;
struct scmi_requested_dev *rdev;
- struct scmi_device *scmi_dev = NULL;
+ struct scmi_device *sdev, *scmi_dev = NULL;
if (name)
- return _scmi_device_create(np, parent, protocol, name);
+ return _scmi_device_create(fwnode, parent, protocol, name);
+
+ /*
+ * Always create devices for standard protocols, even if the device-ids
+ * have not been registered into scmi_requested_devices yet. This allows
+ * auto-loading of SCMI protocol driver modules for standard protocols.
+ */
+ for (int i = 0; scmi_std_id_table[i].name[0]; i++) {
+ if (scmi_std_id_table[i].protocol_id != protocol)
+ continue;
+
+ sdev = _scmi_device_create(fwnode, parent, protocol,
+ scmi_std_id_table[i].name);
+ if (sdev)
+ scmi_dev = sdev;
+ }
mutex_lock(&scmi_requested_devices_mtx);
phead = idr_find(&scmi_requested_devices, protocol);
/* Nothing to do. */
if (!phead) {
mutex_unlock(&scmi_requested_devices_mtx);
- return NULL;
+ return scmi_dev;
}
/* Walk the list of requested devices for protocol and create them */
list_for_each_entry(rdev, phead, node) {
- struct scmi_device *sdev;
+ /* Standard proto matches already have their dev created above */
+ if (scmi_device_id_in_std_id_table(rdev->id_table))
+ continue;
- sdev = _scmi_device_create(np, parent,
+ sdev = _scmi_device_create(fwnode, parent,
rdev->id_table->protocol_id,
rdev->id_table->name);
if (sdev)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index fe8c22cfb9f7..af5b025ee072 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -9,6 +9,7 @@
#ifndef _SCMI_COMMON_H
#define _SCMI_COMMON_H
+#include <linux/acpi.h>
#include <linux/bitfield.h>
#include <linux/completion.h>
#include <linux/device.h>
@@ -152,7 +153,7 @@ extern const struct bus_type scmi_bus_type;
#define SCMI_BUS_NOTIFY_DEVICE_UNREQUEST 1
extern struct blocking_notifier_head scmi_requested_devices_nh;
-struct scmi_device *scmi_device_create(struct device_node *np,
+struct scmi_device *scmi_device_create(struct fwnode_handle *fwnode,
struct device *parent, int protocol,
const char *name);
void scmi_device_destroy(struct device *parent, int protocol, const char *name);
@@ -206,7 +207,8 @@ struct scmi_chan_info {
* @poll_done: Callback to poll transfer status
*/
struct scmi_transport_ops {
- bool (*chan_available)(struct device_node *of_node, int idx);
+ bool (*chan_available)(struct fwnode_handle *fwnode, int prot_id,
+ int idx);
int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev,
bool tx);
int (*chan_free)(int id, void *p, void *data);
@@ -232,7 +234,7 @@ struct scmi_transport_ops {
* be pending simultaneously in the system. May be overridden by the
* get_max_msg op.
* @max_msg_size: Maximum size of data payload per message that can be handled.
- * @atomic_threshold: Optional system wide DT-configured threshold, expressed
+ * @atomic_threshold: Optional system wide fwnode-configured threshold, expressed
* in microseconds, for atomic operations.
* Only SCMI synchronous commands reported by the platform
* to have an execution latency lesser-equal to the threshold
@@ -240,7 +242,8 @@ struct scmi_transport_ops {
* decision is finally left up to the SCMI drivers.
* @no_completion_irq: Flag to indicate that this transport has no completion
* interrupt and has to be polled. This is similar to the
- * force_polling below, except this is set via DT property.
+ * force_polling below, except this is set via fwnode
+ * property.
* @force_polling: Flag to force this whole transport to use SCMI core polling
* mechanism instead of completion interrupts even if available.
* @sync_cmds_completed_on_ret: Flag to indicate that the transport assures
@@ -284,6 +287,28 @@ static inline bool is_polling_enabled(struct scmi_chan_info *cinfo,
is_transport_polling_capable(desc);
}
+/**
+ * scmi_xfer_async_response_arm - Arm the delayed response completion
+ *
+ * @xfer: A reference to the xfer to arm
+ * @async_done: The completion to signal upon reception of a delayed response,
+ * or NULL to disarm @xfer.
+ */
+static inline void scmi_xfer_async_response_arm(struct scmi_xfer *xfer,
+ struct completion *async_done)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&xfer->lock, flags);
+ xfer->async_done = async_done;
+ spin_unlock_irqrestore(&xfer->lock, flags);
+}
+
+static inline void scmi_xfer_async_response_disarm(struct scmi_xfer *xfer)
+{
+ scmi_xfer_async_response_arm(xfer, NULL);
+}
+
void scmi_xfer_raw_put(const struct scmi_handle *handle,
struct scmi_xfer *xfer);
struct scmi_xfer *scmi_xfer_raw_get(const struct scmi_handle *handle);
@@ -465,6 +490,17 @@ struct scmi_transport_core_operations {
const struct scmi_message_operations *msg;
};
+struct scmi_dsd_info {
+ u32 protocol_id;
+ const char *const property_name;
+};
+
+static const struct scmi_dsd_info scmi_dsd_info_list[] __maybe_unused = {
+ { SCMI_PROTOCOL_BASE, "arm-arml0001-transport-pcc" },
+ { SCMI_PROTOCOL_POWERCAP, "arm-arml0001-protocol-pcap" },
+ { SCMI_PROTOCOL_TELEMETRY, "arm-arml0001-protocol-telemetry" },
+};
+
/**
* struct scmi_transport_handle - Transport instance handle
* @supplier_get: A helper to retrieve the device descriptor, identifying the
@@ -615,7 +651,8 @@ struct scmi_transport_supplier __supplier = { \
.th.supplier_put = scmi_transport_supplier_put, \
}
-#define DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, __core_ops)\
+#define __DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __of_match, \
+ __acpi_match, __core_ops) \
static void __tag##_dev_free(void *data) \
{ \
struct platform_device *spdev = data; \
@@ -649,7 +686,10 @@ static int __tag##_probe(struct platform_device *pdev) \
goto err_mem; \
} \
\
- device_set_of_node_from_dev(&spdev->dev, dev); \
+ if (dev_of_node(dev)) \
+ platform_device_set_of_node_from_dev(spdev, dev); \
+ else \
+ platform_device_set_fwnode(spdev, dev_fwnode(dev)); \
\
strans.supplier = supplier; \
memcpy(&strans.desc, &(__desc), sizeof(strans.desc)); \
@@ -678,11 +718,18 @@ err_mem: \
static struct platform_driver __drv = { \
.driver = { \
.name = #__tag "_transport", \
- .of_match_table = __match, \
+ .of_match_table = __of_match, \
+ .acpi_match_table = ACPI_PTR(__acpi_match), \
}, \
.probe = __tag##_probe, \
}
+#define DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, __core_ops)\
+ __DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, NULL, __core_ops)
+
+#define DEFINE_SCMI_ACPI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, __core_ops)\
+ __DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, NULL, __match, __core_ops)
+
void scmi_notification_instance_data_set(const struct scmi_handle *handle,
void *priv);
void *scmi_notification_instance_data_get(const struct scmi_handle *handle);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index a666ad39acdf..1e6f69b14321 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -16,6 +16,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/acpi.h>
#include <linux/bitmap.h>
#include <linux/cleanup.h>
#include <linux/debugfs.h>
@@ -30,7 +31,7 @@
#include <linux/hashtable.h>
#include <linux/list.h>
#include <linux/module.h>
-#include <linux/of.h>
+#include <linux/property.h>
#include <linux/platform_device.h>
#include <linux/processor.h>
#include <linux/rcupdate.h>
@@ -102,7 +103,7 @@ struct scmi_xfers_info {
* initialization code to identify this instance.
*
* Each protocol is initialized independently once for each SCMI platform in
- * which is defined by DT and implemented by the SCMI server fw.
+ * which is defined by fwnode and implemented by the SCMI server fw.
*/
struct scmi_protocol_instance {
const struct scmi_handle *handle;
@@ -137,8 +138,9 @@ struct scmi_protocol_instance {
* @protocols_imp: List of protocols implemented, currently maximum of
* scmi_base_info.num_protocols elements allocated by the
* base protocol
- * @active_protocols: IDR storing device_nodes for protocols actually defined
- * in the DT and confirmed as implemented by fw.
+ * @active_protocols: IDR storing fwnodes for protocols actually defined
+ * in the firmware description and confirmed as implemented
+ * by fw.
* @notify_priv: Pointer to private data structure specific to notifications.
* @node: List head
* @users: Number of users of this instance
@@ -416,19 +418,19 @@ EXPORT_SYMBOL_GPL(scmi_protocol_unregister);
* scmi_create_protocol_devices - Create devices for all pending requests for
* this SCMI instance.
*
- * @np: The device node describing the protocol
+ * @fwnode: The firmware node describing the protocol
* @info: The SCMI instance descriptor
* @prot_id: The protocol ID
* @name: The optional name of the device to be created: if not provided this
* call will lead to the creation of all the devices currently requested
* for the specified protocol.
*/
-static void scmi_create_protocol_devices(struct device_node *np,
+static void scmi_create_protocol_devices(struct fwnode_handle *fwnode,
struct scmi_info *info,
int prot_id, const char *name)
{
mutex_lock(&info->devreq_mtx);
- scmi_device_create(np, info->dev, prot_id, name);
+ scmi_device_create(fwnode, info->dev, prot_id, name);
mutex_unlock(&info->devreq_mtx);
}
@@ -718,6 +720,7 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle,
refcount_set(&xfer->users, 1);
atomic_set(&xfer->busy, SCMI_XFER_FREE);
+ xfer->async_done = NULL;
spin_unlock_irqrestore(&minfo->xfer_lock, flags);
return xfer;
@@ -752,9 +755,10 @@ struct scmi_xfer *scmi_xfer_raw_get(const struct scmi_handle *handle)
* @protocol_id: Identifier of the protocol
*
* Note that in a regular SCMI stack, usually, a protocol has to be defined in
- * the DT to have an associated channel and be usable; but in Raw mode any
- * protocol in range is allowed, re-using the Base channel, so as to enable
- * fuzzing on any protocol without the need of a fully compiled DT.
+ * the firmware description to have an associated channel and be usable; but in
+ * Raw mode any protocol in range is allowed, re-using the Base channel, so as
+ * to enable fuzzing on any protocol without the need of a fully compiled
+ * firmware description.
*
* Return: A reference to the channel to use, or an ERR_PTR
*/
@@ -768,7 +772,7 @@ scmi_xfer_raw_channel_get(const struct scmi_handle *handle, u8 protocol_id)
if (!cinfo) {
if (protocol_id == SCMI_PROTOCOL_BASE)
return ERR_PTR(-EINVAL);
- /* Use Base channel for protocols not defined for DT */
+ /* Use Base channel for protocols not defined for fwnode */
cinfo = idr_find(&info->tx_idr, SCMI_PROTOCOL_BASE);
if (!cinfo)
return ERR_PTR(-EINVAL);
@@ -1064,6 +1068,29 @@ static inline void scmi_xfer_command_release(struct scmi_info *info,
__scmi_xfer_put(&info->tx_minfo, xfer);
}
+/**
+ * scmi_xfer_async_response_complete - Signal a received delayed response
+ *
+ * @xfer: A reference to the xfer whose delayed response was received
+ *
+ * Return: True if a completion was still armed on @xfer and has been
+ * signalled, false if a waiter has already disarmed it due to
+ * timeout or other error.
+ */
+static bool scmi_xfer_async_response_complete(struct scmi_xfer *xfer)
+{
+ unsigned long flags;
+ struct completion *async_done;
+
+ spin_lock_irqsave(&xfer->lock, flags);
+ async_done = xfer->async_done;
+ if (async_done)
+ complete(async_done);
+ spin_unlock_irqrestore(&xfer->lock, flags);
+
+ return !!async_done;
+}
+
static inline void scmi_clear_channel(struct scmi_info *info,
struct scmi_chan_info *cinfo)
{
@@ -1167,8 +1194,12 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) {
scmi_clear_channel(info, cinfo);
- complete(xfer->async_done);
- scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK);
+ if (scmi_xfer_async_response_complete(xfer))
+ scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK);
+ else
+ dev_err(cinfo->dev,
+ "Delayed Response for %d (protocol 0x%X msg 0x%X) received after waiter was disarmed, dropping\n",
+ xfer->hdr.seq, xfer->hdr.protocol_id, xfer->hdr.id);
} else {
complete(&xfer->done);
scmi_inc_count(info->dbg, RESPONSE_OK);
@@ -1510,7 +1541,7 @@ static int do_xfer_with_response(const struct scmi_protocol_handle *ph,
int ret, timeout = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT);
DECLARE_COMPLETION_ONSTACK(async_response);
- xfer->async_done = &async_response;
+ scmi_xfer_async_response_arm(xfer, &async_response);
/*
* Delayed responses should not be polled, so an async command should
@@ -1522,7 +1553,7 @@ static int do_xfer_with_response(const struct scmi_protocol_handle *ph,
ret = do_xfer(ph, xfer);
if (!ret) {
- if (!wait_for_completion_timeout(xfer->async_done, timeout)) {
+ if (!wait_for_completion_timeout(&async_response, timeout)) {
dev_err(ph->dev,
"timed out in delayed resp(caller: %pS)\n",
(void *)_RET_IP_);
@@ -1532,7 +1563,7 @@ static int do_xfer_with_response(const struct scmi_protocol_handle *ph,
}
}
- xfer->async_done = NULL;
+ scmi_xfer_async_response_disarm(xfer);
return ret;
}
@@ -2749,7 +2780,7 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo)
return ret;
}
-static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
+static int scmi_chan_setup(struct scmi_info *info, struct fwnode_handle *fwnode,
int prot_id, bool tx)
{
int ret, idx;
@@ -2765,7 +2796,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
if (idr_find(idr, prot_id))
return -EEXIST;
- if (!info->desc->ops->chan_available(of_node, idx)) {
+ if (!info->desc->ops->chan_available(fwnode, prot_id, idx)) {
cinfo = idr_find(idr, SCMI_PROTOCOL_BASE);
if (unlikely(!cinfo)) /* Possible only if platform has no Rx */
return -EINVAL;
@@ -2785,7 +2816,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
snprintf(name, sizeof(name), SCMI_TRANSPORT_DEVNAME_PREFIX "_%s_%02X",
idx ? "rx" : "tx", prot_id);
/* Create a uniquely named, dedicated transport device for this chan */
- tdev = scmi_device_create(of_node, info->dev, prot_id, name);
+ tdev = scmi_device_create(fwnode, info->dev, prot_id, name);
if (!tdev) {
dev_err(info->dev,
"failed to create transport device (%s)\n", name);
@@ -2831,14 +2862,14 @@ idr_alloc:
}
static inline int
-scmi_txrx_setup(struct scmi_info *info, struct device_node *of_node,
+scmi_txrx_setup(struct scmi_info *info, struct fwnode_handle *fwnode,
int prot_id)
{
- int ret = scmi_chan_setup(info, of_node, prot_id, true);
+ int ret = scmi_chan_setup(info, fwnode, prot_id, true);
if (!ret) {
/* Rx is optional, report only memory errors */
- ret = scmi_chan_setup(info, of_node, prot_id, false);
+ ret = scmi_chan_setup(info, fwnode, prot_id, false);
if (ret && ret != -ENOMEM)
ret = 0;
}
@@ -2855,44 +2886,57 @@ scmi_txrx_setup(struct scmi_info *info, struct device_node *of_node,
*
* @info: The SCMI instance descriptor.
*
- * Initialize all the channels found described in the DT against the underlying
- * configured transport using custom defined dedicated devices instead of
- * borrowing devices from the SCMI drivers; this way channels are initialized
+ * Initialize all the channels found described in the fwnode against the
+ * underlying configured transport using custom defined dedicated devices instead
+ * of borrowing devices from the SCMI drivers; this way channels are initialized
* upfront during core SCMI stack probing and are no more coupled with SCMI
* devices used by SCMI drivers.
*
* Note that, even though a pair of TX/RX channels is associated to each
- * protocol defined in the DT, a distinct freshly initialized channel is
- * created only if the DT node for the protocol at hand describes a dedicated
+ * protocol defined in the fwnode, a distinct freshly initialized channel is
+ * created only if the fwnode for the protocol at hand describes a dedicated
* channel: in all the other cases the common BASE protocol channel is reused.
*
* Return: 0 on Success
*/
static int scmi_channels_setup(struct scmi_info *info)
{
- int ret;
- struct device_node *top_np = info->dev->of_node;
+ int ret, idx;
+ struct fwnode_handle *fwnode = dev_fwnode(info->dev);
/* Initialize a common generic channel at first */
- ret = scmi_txrx_setup(info, top_np, SCMI_PROTOCOL_BASE);
+ ret = scmi_txrx_setup(info, fwnode, SCMI_PROTOCOL_BASE);
if (ret)
return ret;
- for_each_available_child_of_node_scoped(top_np, child) {
- u32 prot_id;
+ if (!is_acpi_node(fwnode)) {
+ fwnode_for_each_available_child_node_scoped(fwnode, child) {
+ u32 prot_id;
- if (of_property_read_u32(child, "reg", &prot_id))
- continue;
+ if (fwnode_property_read_u32(child, "reg", &prot_id))
+ continue;
+
+ if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) {
+ dev_err(info->dev,
+ "Out of range protocol %d\n", prot_id);
+ continue;
+ }
- if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) {
- dev_err(info->dev,
- "Out of range protocol %d\n", prot_id);
- continue;
+ ret = scmi_txrx_setup(info, child, prot_id);
+ if (ret)
+ return ret;
}
+ } else {
+ for (idx = 0; idx < ARRAY_SIZE(scmi_dsd_info_list); idx++) {
+ int prot_id = scmi_dsd_info_list[idx].protocol_id;
- ret = scmi_txrx_setup(info, child, prot_id);
- if (ret)
- return ret;
+ if (prot_id == SCMI_PROTOCOL_BASE)
+ continue;
+
+ ret = scmi_txrx_setup(info, fwnode, prot_id);
+ if (ret)
+ return ret;
+ }
}
return 0;
@@ -2969,14 +3013,14 @@ static int scmi_bus_notifier(struct notifier_block *nb,
static int scmi_device_request_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
- struct device_node *np;
+ struct fwnode_handle *fwnode;
struct scmi_device_id *id_table = data;
struct scmi_info *info = req_nb_to_scmi_info(nb);
rcu_read_lock();
- np = idr_find(&info->active_protocols, id_table->protocol_id);
+ fwnode = idr_find(&info->active_protocols, id_table->protocol_id);
rcu_read_unlock();
- if (!np)
+ if (!fwnode)
return NOTIFY_DONE;
dev_dbg(info->dev, "%sRequested device (%s) for protocol 0x%x\n",
@@ -2985,7 +3029,7 @@ static int scmi_device_request_notifier(struct notifier_block *nb,
switch (action) {
case SCMI_BUS_NOTIFY_DEVICE_REQUEST:
- scmi_create_protocol_devices(np, info, id_table->protocol_id,
+ scmi_create_protocol_devices(fwnode, info, id_table->protocol_id,
id_table->name);
break;
case SCMI_BUS_NOTIFY_DEVICE_UNREQUEST:
@@ -3061,6 +3105,15 @@ static void scmi_debugfs_common_cleanup(void *d)
kfree(dbg->type);
}
+static const char *scmi_acpi_device_hid(struct acpi_device *adev)
+{
+#ifdef CONFIG_ACPI
+ return adev ? acpi_device_hid(adev) : "unknown";
+#else
+ return "unknown";
+#endif
+}
+
static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info)
{
char top_dir[16];
@@ -3072,13 +3125,16 @@ static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info)
if (!dbg)
return NULL;
- dbg->name = kstrdup(of_node_full_name(info->dev->of_node), GFP_KERNEL);
+ dbg->name = kstrdup(fwnode_get_name(dev_fwnode(info->dev)), GFP_KERNEL);
if (!dbg->name) {
devm_kfree(info->dev, dbg);
return NULL;
}
- of_property_read_string(info->dev->of_node, "compatible", &c_ptr);
+ if (fwnode_property_read_string(dev_fwnode(info->dev), "compatible",
+ &c_ptr))
+ c_ptr = scmi_acpi_device_hid(ACPI_COMPANION(info->dev));
+
dbg->type = kstrdup(c_ptr, GFP_KERNEL);
if (!dbg->type) {
kfree(dbg->name);
@@ -3184,23 +3240,23 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev)
dev_info(dev, "Using %s\n", dev_driver_string(trans->supplier));
- ret = of_property_read_u32(dev->of_node, "arm,max-rx-timeout-ms",
- &trans->desc.max_rx_timeout_ms);
+ ret = fwnode_property_read_u32(dev_fwnode(dev), "arm,max-rx-timeout-ms",
+ &trans->desc.max_rx_timeout_ms);
if (ret && ret != -EINVAL)
- dev_err(dev, "Malformed arm,max-rx-timeout-ms DT property.\n");
+ dev_err(dev, "Malformed arm,max-rx-timeout-ms property.\n");
- ret = of_property_read_u32(dev->of_node, "arm,max-msg-size",
- &trans->desc.max_msg_size);
+ ret = fwnode_property_read_u32(dev_fwnode(dev), "arm,max-msg-size",
+ &trans->desc.max_msg_size);
if (ret && ret != -EINVAL)
- dev_err(dev, "Malformed arm,max-msg-size DT property.\n");
+ dev_err(dev, "Malformed arm,max-msg-size property.\n");
- ret = of_property_read_u32(dev->of_node, "arm,max-msg",
- &trans->desc.max_msg);
+ ret = fwnode_property_read_u32(dev_fwnode(dev), "arm,max-msg",
+ &trans->desc.max_msg);
if (ret && ret != -EINVAL)
- dev_err(dev, "Malformed arm,max-msg DT property.\n");
+ dev_err(dev, "Malformed arm,max-msg property.\n");
- trans->desc.no_completion_irq = of_property_read_bool(dev->of_node,
- "arm,no-completion-irq");
+ trans->desc.no_completion_irq =
+ fwnode_property_read_bool(dev_fwnode(dev), "arm,no-completion-irq");
dev_info(dev,
"SCMI max-rx-timeout: %dms / max-msg-size: %dbytes / max-msg: %d\n",
@@ -3208,8 +3264,8 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev)
trans->desc.max_msg);
/* System wide atomic threshold for atomic ops .. if any */
- if (!of_property_read_u32(dev->of_node, "atomic-threshold-us",
- &trans->desc.atomic_threshold))
+ if (!fwnode_property_read_u32(dev_fwnode(dev), "atomic-threshold-us",
+ &trans->desc.atomic_threshold))
dev_info(dev,
"SCMI System wide atomic threshold set to %u us\n",
trans->desc.atomic_threshold);
@@ -3229,16 +3285,52 @@ static void scmi_enable_matching_quirks(struct scmi_info *info)
rev->sub_vendor_id, rev->impl_ver);
}
-static int scmi_probe(struct platform_device *pdev)
+static void scmi_device_check_create(struct fwnode_handle *fwnode, int prot_id,
+ struct scmi_info *info, bool report_missing)
{
int ret;
+ struct device *dev = info->dev;
+ struct scmi_handle *handle = &info->handle;
+
+ if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) {
+ dev_err(dev, "Out of range protocol %d\n", prot_id);
+ return;
+ }
+
+ if (!scmi_is_protocol_implemented(handle, prot_id)) {
+ if (!report_missing)
+ return;
+
+ dev_err(dev, "SCMI protocol %d not implemented\n", prot_id);
+ return;
+ }
+
+ /*
+ * Save this valid fwnode protocol descriptor amongst
+ * @active_protocols for this SCMI instance.
+ */
+ ret = idr_alloc(&info->active_protocols, fwnode,
+ prot_id, prot_id + 1, GFP_KERNEL);
+ if (ret != prot_id) {
+ dev_err(dev, "SCMI protocol %d already activated. Skip\n",
+ prot_id);
+ return;
+ }
+
+ scmi_create_protocol_devices(fwnode_handle_get(fwnode), info, prot_id,
+ NULL);
+}
+
+static int scmi_probe(struct platform_device *pdev)
+{
+ int ret, idx;
char *err_str = "probe failure\n";
struct scmi_handle *handle;
const struct scmi_desc *desc;
struct scmi_info *info;
bool coex = IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX);
struct device *dev = &pdev->dev;
- struct device_node *child, *np = dev->of_node;
+ struct fwnode_handle *child;
desc = scmi_transport_setup(dev);
if (!desc) {
@@ -3277,7 +3369,7 @@ static int scmi_probe(struct platform_device *pdev)
handle->devm_protocol_put = scmi_devm_protocol_put;
handle->is_transport_atomic = scmi_is_transport_atomic;
- /* Setup all channels described in the DT at first */
+ /* Setup all channels described in the fwnode at first */
ret = scmi_channels_setup(info);
if (ret) {
err_str = "failed to setup channels\n";
@@ -3352,37 +3444,25 @@ static int scmi_probe(struct platform_device *pdev)
scmi_enable_matching_quirks(info);
- for_each_available_child_of_node(np, child) {
- u32 prot_id;
+ if (!is_acpi_node(dev_fwnode(dev))) {
+ fwnode_for_each_available_child_node(dev_fwnode(dev), child) {
+ u32 prot_id;
- if (of_property_read_u32(child, "reg", &prot_id))
- continue;
+ if (fwnode_property_read_u32(child, "reg", &prot_id))
+ continue;
- if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) {
- dev_err(dev, "Out of range protocol %d\n", prot_id);
- continue;
+ scmi_device_check_create(child, prot_id, info, true);
}
+ } else {
+ for (idx = 0; idx < ARRAY_SIZE(scmi_dsd_info_list); idx++) {
+ int prot_id = scmi_dsd_info_list[idx].protocol_id;
- if (!scmi_is_protocol_implemented(handle, prot_id)) {
- dev_err(dev, "SCMI protocol %d not implemented\n",
- prot_id);
- continue;
- }
+ if (prot_id == SCMI_PROTOCOL_BASE)
+ continue;
- /*
- * Save this valid DT protocol descriptor amongst
- * @active_protocols for this SCMI instance/
- */
- ret = idr_alloc(&info->active_protocols, child,
- prot_id, prot_id + 1, GFP_KERNEL);
- if (ret != prot_id) {
- dev_err(dev, "SCMI protocol %d already activated. Skip\n",
- prot_id);
- continue;
+ scmi_device_check_create(dev_fwnode(dev), prot_id,
+ info, false);
}
-
- of_node_get(child);
- scmi_create_protocol_devices(child, info, prot_id, NULL);
}
return 0;
@@ -3409,7 +3489,7 @@ static void scmi_remove(struct platform_device *pdev)
{
int id;
struct scmi_info *info = platform_get_drvdata(pdev);
- struct device_node *child;
+ struct fwnode_handle *child;
if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT))
scmi_raw_mode_cleanup(info->raw);
@@ -3434,7 +3514,7 @@ static void scmi_remove(struct platform_device *pdev)
mutex_unlock(&info->protocols_mtx);
idr_for_each_entry(&info->active_protocols, child, id)
- of_node_put(child);
+ fwnode_handle_put(child);
idr_destroy(&info->active_protocols);
bus_unregister_notifier(&scmi_bus_type, &info->bus_nb);
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index 15ad5162e37a..8583159059e6 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -100,7 +100,10 @@ struct scmi_msg_hdr {
* message. If request-ACK protocol is used, we can reuse the same
* buffer for the rx path as we use for the tx path.
* @done: command message transmit completion event
- * @async_done: pointer to delayed response message received event completion
+ * @async_done: pointer to delayed response message received event completion,
+ * or NULL when no delayed response is expected. Protected by
+ * @lock, since the completion is owned by the waiter and can
+ * vanish once the wait times out.
* @pending: True for xfers added to @pending_xfers hashtable
* @node: An hlist_node reference used to store this xfer, alternatively, on
* the free list @free_xfers or in the @pending_xfers hashtable
@@ -121,7 +124,7 @@ struct scmi_msg_hdr {
* - SCMI_XFER_SENT_OK -> SCMI_XFER_DRESP_OK
* (Missing synchronous response is assumed OK and ignored)
* @flags: Optional flags associated to this xfer.
- * @lock: A spinlock to protect state and busy fields.
+ * @lock: A spinlock to protect state, busy and async_done fields.
* @priv: A pointer for transport private usage.
*/
struct scmi_xfer {
@@ -147,7 +150,7 @@ struct scmi_xfer {
#define SCMI_XFER_IS_CHAN_SET(x) \
((x)->flags & SCMI_XFER_FLAG_CHAN_SET)
int flags;
- /* A lock to protect state and busy fields */
+ /* A lock to protect state, busy and async_done fields */
spinlock_t lock;
void *priv;
};
diff --git a/drivers/firmware/arm_scmi/raw_mode.c b/drivers/firmware/arm_scmi/raw_mode.c
index 1f6e51670208..f01bf2f6ce1d 100644
--- a/drivers/firmware/arm_scmi/raw_mode.c
+++ b/drivers/firmware/arm_scmi/raw_mode.c
@@ -198,6 +198,8 @@ struct scmi_raw_mode_info {
* @async_response: A completion to be, optionally, used for async waits: it
* will be setup by @scmi_do_xfer_raw_start, if needed, to be
* pointed at by xfer->async_done.
+ * @async: True if @async_response was armed on @xfer, i.e. if a delayed
+ * response has to be waited for.
* @node: A list node.
*/
struct scmi_xfer_raw_waiter {
@@ -205,6 +207,7 @@ struct scmi_xfer_raw_waiter {
struct scmi_chan_info *cinfo;
struct scmi_xfer *xfer;
struct completion async_response;
+ bool async;
struct list_head node;
};
@@ -346,9 +349,10 @@ scmi_xfer_raw_waiter_get(struct scmi_raw_mode_info *raw, struct scmi_xfer *xfer,
if (async) {
reinit_completion(&rw->async_response);
- xfer->async_done = &rw->async_response;
+ scmi_xfer_async_response_arm(xfer, &rw->async_response);
}
+ rw->async = async;
rw->cinfo = cinfo;
rw->xfer = xfer;
}
@@ -361,8 +365,16 @@ static void scmi_xfer_raw_waiter_put(struct scmi_raw_mode_info *raw,
struct scmi_xfer_raw_waiter *rw)
{
if (rw->xfer) {
- rw->xfer->async_done = NULL;
+ /*
+ * Disarm the delayed response before this waiter, and its
+ * embedded completion, can be picked up again for a new
+ * transaction: a delayed response received late, after the
+ * related wait timed out, must not signal a completion which
+ * has been in the meantime re-armed on a different xfer.
+ */
+ scmi_xfer_async_response_disarm(rw->xfer);
rw->xfer = NULL;
+ rw->async = false;
}
mutex_lock(&raw->free_mtx);
@@ -479,18 +491,23 @@ static void scmi_xfer_raw_worker(struct work_struct *work)
ret, scmi_inflight_count(raw->handle));
/* Wait also for an async delayed response if needed */
- if (!ret && xfer->async_done) {
+ if (!ret && rw->async) {
unsigned long tmo = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT);
- if (!wait_for_completion_timeout(xfer->async_done, tmo))
+ if (!wait_for_completion_timeout(&rw->async_response, tmo))
dev_err(dev,
"timed out in RAW delayed resp - HDR:%08X\n",
pack_scmi_header(&xfer->hdr));
}
- /* Release waiter and xfer */
- scmi_xfer_raw_put(raw->handle, xfer);
+ /*
+ * Release the waiter first: this disarms the delayed response
+ * while we still hold a reference on the xfer, so that the xfer
+ * cannot be recycled by a new transaction while it still points
+ * at this waiter's completion.
+ */
scmi_xfer_raw_waiter_put(raw, rw);
+ scmi_xfer_raw_put(raw->handle, xfer);
} while (1);
}
@@ -694,6 +711,7 @@ static int scmi_raw_message_send(struct scmi_raw_mode_info *raw,
} else {
dev_err(raw->handle->dev,
"Failed to send RAW message - Polling NOT supported\n");
+ scmi_xfer_raw_put(raw->handle, xfer);
return -EINVAL;
}
}
diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c
index 4bc5c24c2d72..2cdddc28ba47 100644
--- a/drivers/firmware/arm_scmi/reset.c
+++ b/drivers/firmware/arm_scmi/reset.c
@@ -60,8 +60,7 @@ struct scmi_reset_issued_notify_payld {
struct reset_dom_info {
bool async_reset;
bool reset_notify;
- u32 latency_us;
- char name[SCMI_MAX_STR_SIZE];
+ struct scmi_reset_domain_info info;
};
struct scmi_reset_info {
@@ -134,10 +133,10 @@ scmi_reset_domain_attributes_get(const struct scmi_protocol_handle *ph,
if (pinfo->notify_reset_cmd)
dom_info->reset_notify =
SUPPORTS_NOTIFY_RESET(attributes);
- dom_info->latency_us = le32_to_cpu(attr->latency);
- if (dom_info->latency_us == U32_MAX)
- dom_info->latency_us = 0;
- strscpy(dom_info->name, attr->name, SCMI_SHORT_NAME_MAX_SIZE);
+ dom_info->info.latency_us = le32_to_cpu(attr->latency);
+ if (dom_info->info.latency_us == U32_MAX)
+ dom_info->info.latency_us = 0;
+ strscpy(dom_info->info.name, attr->name, SCMI_SHORT_NAME_MAX_SIZE);
}
ph->xops->xfer_put(ph, t);
@@ -149,7 +148,7 @@ scmi_reset_domain_attributes_get(const struct scmi_protocol_handle *ph,
if (!ret && PROTOCOL_REV_MAJOR(ph->version) >= 0x3 &&
SUPPORTS_EXTENDED_NAMES(attributes))
ph->hops->extended_name_get(ph, RESET_DOMAIN_NAME_GET, domain,
- NULL, dom_info->name,
+ NULL, dom_info->info.name,
SCMI_MAX_STR_SIZE);
return ret;
@@ -162,28 +161,16 @@ static int scmi_reset_num_domains_get(const struct scmi_protocol_handle *ph)
return pi->num_domains;
}
-static const char *
-scmi_reset_name_get(const struct scmi_protocol_handle *ph, u32 domain)
+static const struct scmi_reset_domain_info *
+scmi_reset_info_get(const struct scmi_protocol_handle *ph, u32 domain)
{
struct reset_dom_info *dom_info;
dom_info = scmi_reset_domain_lookup(ph, domain);
if (IS_ERR(dom_info))
- return "unknown";
-
- return dom_info->name;
-}
-
-static int scmi_reset_latency_get(const struct scmi_protocol_handle *ph,
- u32 domain)
-{
- struct reset_dom_info *dom_info;
-
- dom_info = scmi_reset_domain_lookup(ph, domain);
- if (IS_ERR(dom_info))
- return PTR_ERR(dom_info);
+ return NULL;
- return dom_info->latency_us;
+ return &dom_info->info;
}
static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
@@ -241,8 +228,7 @@ scmi_reset_domain_deassert(const struct scmi_protocol_handle *ph, u32 domain)
static const struct scmi_reset_proto_ops reset_proto_ops = {
.num_domains_get = scmi_reset_num_domains_get,
- .name_get = scmi_reset_name_get,
- .latency_get = scmi_reset_latency_get,
+ .info_get = scmi_reset_info_get,
.reset = scmi_reset_domain_reset,
.assert = scmi_reset_domain_assert,
.deassert = scmi_reset_domain_deassert,
diff --git a/drivers/firmware/arm_scmi/transports/Kconfig b/drivers/firmware/arm_scmi/transports/Kconfig
index 57eccf316e26..0e34fbf25053 100644
--- a/drivers/firmware/arm_scmi/transports/Kconfig
+++ b/drivers/firmware/arm_scmi/transports/Kconfig
@@ -77,6 +77,18 @@ config ARM_SCMI_TRANSPORT_OPTEE
This driver can also be built as a module. If so, the module
will be called scmi_transport_optee.
+config ARM_SCMI_TRANSPORT_PCC
+ tristate "SCMI transport based on ACPI PCC"
+ depends on PCC
+ select ARM_SCMI_HAVE_TRANSPORT
+ help
+ This enables the ACPI PCC mailbox based transport for SCMI.
+
+ If you want the ARM SCMI PROTOCOL stack to include support for a
+ transport based on ACPI PCC mailboxes, answer Y.
+ This driver can also be built as a module. If so, the module
+ will be called scmi_transport_pcc.
+
config ARM_SCMI_TRANSPORT_VIRTIO
tristate "SCMI transport based on VirtIO"
depends on VIRTIO
diff --git a/drivers/firmware/arm_scmi/transports/Makefile b/drivers/firmware/arm_scmi/transports/Makefile
index 3ba3d3bee151..e7c4b8de6251 100644
--- a/drivers/firmware/arm_scmi/transports/Makefile
+++ b/drivers/firmware/arm_scmi/transports/Makefile
@@ -7,6 +7,8 @@ scmi_transport_mailbox-objs := mailbox.o
obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o
scmi_transport_optee-objs := optee.o
obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o
+scmi_transport_pcc-objs := pcc.o
+obj-$(CONFIG_ARM_SCMI_TRANSPORT_PCC) += scmi_transport_pcc.o
scmi_transport_virtio-objs := virtio.o
obj-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += scmi_transport_virtio.o
diff --git a/drivers/firmware/arm_scmi/transports/mailbox.c b/drivers/firmware/arm_scmi/transports/mailbox.c
index 308736c3ead9..56af2cb0f424 100644
--- a/drivers/firmware/arm_scmi/transports/mailbox.c
+++ b/drivers/firmware/arm_scmi/transports/mailbox.c
@@ -77,9 +77,14 @@ static void rx_callback(struct mbox_client *cl, void *m)
core->shmem->read_header(smbox->shmem), NULL);
}
-static bool mailbox_chan_available(struct device_node *of_node, int idx)
+static bool
+mailbox_chan_available(struct fwnode_handle *fwnode, int prot_id, int idx)
{
int num_mb;
+ struct device_node *of_node = to_of_node(fwnode);
+
+ if (!of_node)
+ return false;
/*
* Just check if bidirrectional channels are involved, and check the
diff --git a/drivers/firmware/arm_scmi/transports/optee.c b/drivers/firmware/arm_scmi/transports/optee.c
index dbe32e141748..6022f74d28f3 100644
--- a/drivers/firmware/arm_scmi/transports/optee.c
+++ b/drivers/firmware/arm_scmi/transports/optee.c
@@ -314,9 +314,14 @@ static int invoke_process_msg_channel(struct scmi_optee_channel *channel, size_t
return 0;
}
-static bool scmi_optee_chan_available(struct device_node *of_node, int idx)
+static bool
+scmi_optee_chan_available(struct fwnode_handle *fwnode, int prot_id, int idx)
{
u32 channel_id;
+ struct device_node *of_node = to_of_node(fwnode);
+
+ if (!of_node)
+ return false;
return !of_property_read_u32_index(of_node, "linaro,optee-channel-id",
idx, &channel_id);
diff --git a/drivers/firmware/arm_scmi/transports/pcc.c b/drivers/firmware/arm_scmi/transports/pcc.c
new file mode 100644
index 000000000000..86d4a097d8ec
--- /dev/null
+++ b/drivers/firmware/arm_scmi/transports/pcc.c
@@ -0,0 +1,875 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Message ACPI PCC
+ * Transport Driver
+ *
+ * This transport uses ACPI PCC (PCCT Type 3/4) subspaces via the Linux
+ * PCC mailbox controller to exchange SCMI messages over the standard
+ * SCMI Shared Memory Transport (SMT) layout.
+ *
+ * PCC subspace selection is conveyed via ACPI SCMI namespace device.
+ * described in ACPI for System Control and Management Interface Platform
+ * Design Document[1]
+ *
+ * [1] https://support.arm.com/documentation/111115/latest
+ *
+ * Copyright (C) 2026
+ */
+
+#include <linux/acpi.h>
+#include <linux/cleanup.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/hashtable.h>
+#include <linux/io.h>
+#include <linux/limits.h>
+#include <linux/list.h>
+#include <linux/mailbox_client.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <acpi/pcc.h>
+
+#include "../common.h"
+
+#define SCMI_TRANSPORT_PACKAGE_MAX_VERSION (1)
+#define SCMI_PROTOCOL_PACKAGE_MAX_VERSION (1)
+#define SCMI_TRANSPORT_SHARED_CHANNEL BIT_ULL(0)
+#define SCMI_TRANSPORT_P2A_CHANNEL BIT_ULL(1)
+#define SCMI_TRANSPORT_FLAGS_MASK (SCMI_TRANSPORT_SHARED_CHANNEL | \
+ SCMI_TRANSPORT_P2A_CHANNEL)
+
+#define SCMI_DSD_GUID_ENTRY_COUNT 2
+#define SCMI_PROTOCOL_MAX_TRANSPORTS 2
+
+enum scmi_dsd_property_index {
+ SCMI_DSD_PROPERTY_NAME,
+ SCMI_DSD_PROPERTY_VALUE,
+ SCMI_DSD_PROPERTY_COUNT,
+};
+
+enum scmi_pcc_transport_index {
+ SCMI_PCC_TRANSPORT_REVISION,
+ SCMI_PCC_TRANSPORT_COUNT,
+ SCMI_PCC_TRANSPORT_DESCRIPTORS,
+};
+
+enum scmi_pcc_descriptor_index {
+ SCMI_PCC_DESCRIPTOR_PCCT_INDEX,
+ SCMI_PCC_DESCRIPTOR_TRANSPORT_UID,
+ SCMI_PCC_DESCRIPTOR_FLAGS,
+ SCMI_PCC_DESCRIPTOR_COUNT,
+};
+
+enum scmi_protocol_property_index {
+ SCMI_PROTOCOL_PROPERTY_REVISION,
+ SCMI_PROTOCOL_PROPERTY_TRANSPORTS,
+ SCMI_PROTOCOL_PROPERTY_ASSOCIATIONS,
+ SCMI_PROTOCOL_PROPERTY_COUNT,
+};
+
+enum scmi_protocol_transport_index {
+ SCMI_PROTOCOL_TRANSPORT_UID,
+ SCMI_PROTOCOL_TRANSPORT_FLAGS,
+ SCMI_PROTOCOL_TRANSPORT_COUNT,
+};
+
+/*
+ * SCMI specification requires all parameters, message headers, return
+ * arguments or any protocol data to be expressed in little endian
+ * format only.
+ */
+struct pcc_shared_mem {
+ struct acpi_pcct_ext_pcc_shared_memory header;
+ u8 msg_payload[];
+};
+
+#define SCMI_PCC_MSG_HEADER_SIZE sizeof(u32)
+#define SCMI_PCC_STATUS_SIZE sizeof(u32)
+#define SCMI_PCC_RESPONSE_OVERHEAD (SCMI_PCC_MSG_HEADER_SIZE + \
+ SCMI_PCC_STATUS_SIZE)
+#define SCMI_PCC_SHMEM_OVERHEAD (sizeof(struct pcc_shared_mem) + \
+ SCMI_PCC_STATUS_SIZE)
+
+/**
+ * struct scmi_pcc - Structure representing a SCMI mailbox transport
+ *
+ * @cl: Mailbox Client
+ * @pchan: Transmit/Receive PCC/mailbox channel
+ * @cinfo: SCMI channel info
+ */
+struct scmi_pcc {
+ struct mbox_client cl;
+ struct pcc_mbox_chan *pchan;
+ struct scmi_chan_info *cinfo;
+};
+
+struct pcc_transport {
+ u64 uid;
+ u64 flags;
+ u32 pcc_ss_id;
+ u32 protocol_id;
+ struct hlist_node hnode;
+};
+
+struct pcc_transport_map {
+ struct fwnode_handle *fwnode;
+ struct device *dev;
+ struct list_head node;
+ DECLARE_HASHTABLE(table, ilog2(MAX_PCC_SUBSPACES / 8));
+};
+
+#define client_to_scmi_pcc(c) container_of(c, struct scmi_pcc, cl)
+
+static struct scmi_transport_core_operations *core;
+static LIST_HEAD(pcc_transport_maps);
+static DEFINE_MUTEX(pcc_transport_maps_lock);
+
+static void acpi_scmi_clear_transport_map(struct pcc_transport_map *map)
+{
+ struct pcc_transport *p;
+ struct hlist_node *tmp;
+ int idx;
+
+ hash_for_each_safe(map->table, idx, tmp, p, hnode) {
+ hash_del(&p->hnode);
+ kfree(p);
+ }
+}
+
+static void acpi_scmi_destroy_transport_map(struct pcc_transport_map *map)
+{
+ acpi_scmi_clear_transport_map(map);
+ if (map->fwnode)
+ fwnode_handle_put(map->fwnode);
+ kfree(map);
+}
+
+static void pcc_transport_map_release(void *data)
+{
+ struct pcc_transport_map *map = data;
+
+ guard(mutex)(&pcc_transport_maps_lock);
+ list_del(&map->node);
+ acpi_scmi_destroy_transport_map(map);
+}
+
+static void acpi_scmi_clear_transport_maps(void)
+{
+ struct pcc_transport_map *map, *tmp;
+
+ guard(mutex)(&pcc_transport_maps_lock);
+ list_for_each_entry_safe(map, tmp, &pcc_transport_maps, node) {
+ list_del(&map->node);
+ acpi_scmi_destroy_transport_map(map);
+ }
+}
+
+static const union acpi_object *
+acpi_scmi_pkg_elements(const union acpi_object *obj, unsigned int count)
+{
+ if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != count)
+ return NULL;
+
+ return obj->package.elements;
+}
+
+static int
+acpi_scmi_pkg_u64(const union acpi_object *pkg, unsigned int idx, u64 *val)
+{
+ const union acpi_object *elem = &pkg->package.elements[idx];
+
+ if (elem->type != ACPI_TYPE_INTEGER)
+ return -EINVAL;
+
+ *val = elem->integer.value;
+
+ return 0;
+}
+
+static int acpi_scmi_property(const union acpi_object *properties,
+ unsigned int idx, const char **name,
+ const union acpi_object **value)
+{
+ const union acpi_object *property;
+ const union acpi_object *elems;
+
+ property = &properties->package.elements[idx];
+ elems = acpi_scmi_pkg_elements(property, SCMI_DSD_PROPERTY_COUNT);
+ if (!elems)
+ return -EINVAL;
+ if (elems[SCMI_DSD_PROPERTY_NAME].type != ACPI_TYPE_STRING ||
+ !elems[SCMI_DSD_PROPERTY_NAME].string.pointer)
+ return -EINVAL;
+
+ *name = elems[SCMI_DSD_PROPERTY_NAME].string.pointer;
+ *value = &elems[SCMI_DSD_PROPERTY_VALUE];
+
+ return 0;
+}
+
+static int
+acpi_scmi_dsd_parse_transport_package(struct pcc_transport_map *map,
+ const union acpi_object *obj)
+{
+ u64 revision, pkg_cnt;
+ bool common_a2p = false, common_p2a = false;
+
+ if (obj->type != ACPI_TYPE_PACKAGE ||
+ obj->package.count < SCMI_PCC_TRANSPORT_DESCRIPTORS ||
+ acpi_scmi_pkg_u64(obj, SCMI_PCC_TRANSPORT_REVISION, &revision) ||
+ acpi_scmi_pkg_u64(obj, SCMI_PCC_TRANSPORT_COUNT, &pkg_cnt))
+ return -EINVAL;
+ if (revision != SCMI_TRANSPORT_PACKAGE_MAX_VERSION)
+ return -EINVAL;
+ if (pkg_cnt != obj->package.count - SCMI_PCC_TRANSPORT_DESCRIPTORS)
+ return -EINVAL;
+
+ for (u32 idx = 0; idx < pkg_cnt; idx++) {
+ struct pcc_transport *p, *tmp;
+ union acpi_object *pack;
+ u64 pcc_ss_id, uid, flags;
+
+ pack = &obj->package.elements[idx +
+ SCMI_PCC_TRANSPORT_DESCRIPTORS];
+ if (!acpi_scmi_pkg_elements(pack, SCMI_PCC_DESCRIPTOR_COUNT)) {
+ pr_info("Invalid transport properties pkg %u\n", idx);
+ return -EINVAL;
+ }
+ if (acpi_scmi_pkg_u64(pack, SCMI_PCC_DESCRIPTOR_PCCT_INDEX,
+ &pcc_ss_id) ||
+ acpi_scmi_pkg_u64(pack, SCMI_PCC_DESCRIPTOR_TRANSPORT_UID,
+ &uid) ||
+ acpi_scmi_pkg_u64(pack, SCMI_PCC_DESCRIPTOR_FLAGS, &flags))
+ return -EINVAL;
+ if (pcc_ss_id > INT_MAX ||
+ flags & ~SCMI_TRANSPORT_FLAGS_MASK)
+ return -EINVAL;
+
+ hash_for_each_possible(map->table, tmp, hnode, uid) {
+ if (tmp->uid == uid) {
+ pr_info("Duplicate UID %llu\n", uid);
+ return -EEXIST;
+ }
+ }
+
+ if (flags & SCMI_TRANSPORT_SHARED_CHANNEL) {
+ if (flags & SCMI_TRANSPORT_P2A_CHANNEL) {
+ if (common_p2a)
+ return -EINVAL;
+ common_p2a = true;
+ } else {
+ if (common_a2p)
+ return -EINVAL;
+ common_a2p = true;
+ }
+ }
+
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+
+ p->uid = uid;
+ p->pcc_ss_id = pcc_ss_id;
+ p->flags = flags;
+ if (p->flags & SCMI_TRANSPORT_SHARED_CHANNEL)
+ p->protocol_id = SCMI_PROTOCOL_BASE;
+
+ hash_add(map->table, &p->hnode, uid);
+ }
+
+ if (!common_a2p)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int
+acpi_scmi_dsd_parse_protocol_subpackage(struct pcc_transport_map *map,
+ const union acpi_object *obj,
+ int prot_id)
+{
+ struct pcc_transport *p;
+ unsigned int pkg_cnt = obj->package.count;
+ bool found, tx_found = false, rx_found = false;
+ u64 uid;
+
+ if (pkg_cnt > SCMI_PROTOCOL_MAX_TRANSPORTS) {
+ pr_warn("Found %u protocol channels, at most %u allowed\n",
+ pkg_cnt, SCMI_PROTOCOL_MAX_TRANSPORTS);
+ return -EINVAL;
+ }
+
+ for (u32 idx = 0; idx < pkg_cnt; idx++) {
+ union acpi_object *pack = &obj->package.elements[idx];
+ u64 flags;
+
+ if (!acpi_scmi_pkg_elements(pack, SCMI_PROTOCOL_TRANSPORT_COUNT) ||
+ acpi_scmi_pkg_u64(pack, SCMI_PROTOCOL_TRANSPORT_UID, &uid) ||
+ acpi_scmi_pkg_u64(pack, SCMI_PROTOCOL_TRANSPORT_FLAGS,
+ &flags))
+ return -EINVAL;
+ if (flags)
+ return -EINVAL;
+
+ found = false;
+ hash_for_each_possible(map->table, p, hnode, uid) {
+ if (p->uid != uid)
+ continue;
+
+ found = true;
+ if (p->flags & SCMI_TRANSPORT_SHARED_CHANNEL) {
+ pr_info("Protocol package references common PCC subspace %u\n",
+ p->pcc_ss_id);
+ return -EINVAL;
+ }
+ if (p->protocol_id && p->protocol_id != prot_id)
+ return -EINVAL;
+
+ if (p->flags & SCMI_TRANSPORT_P2A_CHANNEL) {
+ if (rx_found)
+ return -EINVAL;
+ rx_found = true;
+ } else {
+ if (tx_found)
+ return -EINVAL;
+ tx_found = true;
+ }
+ p->protocol_id = prot_id;
+ break;
+ }
+
+ if (!found)
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
+static int
+acpi_scmi_dsd_parse_protocol_package(struct pcc_transport_map *map,
+ const union acpi_object *obj, int prot_id)
+{
+ const union acpi_object *elems;
+ const union acpi_object *pack;
+ u64 revision;
+ int ret;
+
+ elems = acpi_scmi_pkg_elements(obj, SCMI_PROTOCOL_PROPERTY_COUNT);
+ if (!elems ||
+ acpi_scmi_pkg_u64(obj, SCMI_PROTOCOL_PROPERTY_REVISION, &revision))
+ return -EINVAL;
+
+ pack = &elems[SCMI_PROTOCOL_PROPERTY_TRANSPORTS];
+
+ if (revision != SCMI_PROTOCOL_PACKAGE_MAX_VERSION)
+ return -EINVAL;
+
+ if (pack->type != ACPI_TYPE_PACKAGE) {
+ pr_info("Invalid protocol transport package\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Document 111115A v1.0, Sections 2.2.2.1 and 2.2.3 permit an empty
+ * protocol transport package when common transport channels exist.
+ */
+ if (pack->package.count != 0) {
+ ret = acpi_scmi_dsd_parse_protocol_subpackage(map, pack, prot_id);
+ if (ret)
+ return ret;
+ }
+
+ pack = &elems[SCMI_PROTOCOL_PROPERTY_ASSOCIATIONS];
+ if (pack->type != ACPI_TYPE_PACKAGE) {
+ pr_info("Invalid protocol transport association package\n");
+ return -EINVAL;
+ }
+
+ if (pack->package.count != 0) {
+ pr_info("Non-empty association package not supported\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ACPI SCMI _DSD UUID: "84a2d1c6-86b6-4199-8dac-9c17449d5e03" */
+static const guid_t acpi_scmi_uuid = GUID_INIT(0x84a2d1c6, 0x86b6, 0x4199,
+ 0x8d, 0xac, 0x9c, 0x17,
+ 0x44, 0x9d, 0x5e, 0x03);
+
+static int acpi_scmi_lookup_protocol_id(const char *name)
+{
+ for (size_t i = 0; i < ARRAY_SIZE(scmi_dsd_info_list); i++) {
+ if (!strcmp(name, scmi_dsd_info_list[i].property_name))
+ return scmi_dsd_info_list[i].protocol_id;
+ }
+ return -ENOENT;
+}
+
+static int acpi_scmi_parse_properties(struct pcc_transport_map *map,
+ const union acpi_object *properties)
+{
+ bool transport_found = false;
+
+ if (properties->type != ACPI_TYPE_PACKAGE)
+ return -EINVAL;
+
+ /*
+ * Protocol properties reference TransportUIDs declared by the transport
+ * property. Parse the transport first because _DSD property ordering is
+ * not defined.
+ */
+ for (u32 i = 0; i < properties->package.count; i++) {
+ const union acpi_object *v;
+ const char *name;
+ int prot_id, ret;
+
+ ret = acpi_scmi_property(properties, i, &name, &v);
+ if (ret)
+ return ret;
+
+ prot_id = acpi_scmi_lookup_protocol_id(name);
+ if (prot_id < 0)
+ continue;
+ if (prot_id != SCMI_PROTOCOL_BASE)
+ continue;
+ if (v->type != ACPI_TYPE_PACKAGE)
+ return -EINVAL;
+ if (transport_found)
+ return -EEXIST;
+
+ ret = acpi_scmi_dsd_parse_transport_package(map, v);
+ if (ret)
+ return ret;
+ transport_found = true;
+ }
+
+ if (!transport_found)
+ return -ENOENT;
+
+ for (u32 i = 0; i < properties->package.count; i++) {
+ const union acpi_object *v;
+ const char *name;
+ int prot_id, ret;
+
+ ret = acpi_scmi_property(properties, i, &name, &v);
+ if (ret)
+ return ret;
+
+ prot_id = acpi_scmi_lookup_protocol_id(name);
+ if (prot_id < 0 || prot_id == SCMI_PROTOCOL_BASE)
+ continue;
+ if (v->type != ACPI_TYPE_PACKAGE)
+ return -EINVAL;
+
+ ret = acpi_scmi_dsd_parse_protocol_package(map, v, prot_id);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int acpi_scmi_namespace_fwnode_parse(struct fwnode_handle *fwnode,
+ struct pcc_transport_map *map)
+{
+ struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_device *adev = to_acpi_device_node(fwnode);
+ union acpi_object *desc;
+ acpi_status status;
+ int ret = -ENOENT;
+
+ if (!adev || !adev->handle)
+ return -EINVAL;
+
+ status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
+ ACPI_TYPE_PACKAGE);
+ if (ACPI_FAILURE(status))
+ return -EINVAL;
+
+ desc = buf.pointer;
+ if (desc->package.count % SCMI_DSD_GUID_ENTRY_COUNT) {
+ ret = -EINVAL;
+ goto out_free;
+ }
+
+ /* Look for the device properties GUID. */
+ for (u32 i = 0; i < desc->package.count;
+ i += SCMI_DSD_GUID_ENTRY_COUNT) {
+ const union acpi_object *guid;
+ const union acpi_object *properties;
+
+ guid = &desc->package.elements[i];
+ properties = &desc->package.elements[i + 1];
+
+ /*
+ * The first element must be a GUID and the second one must be
+ * a package.
+ */
+ if (guid->type != ACPI_TYPE_BUFFER ||
+ guid->buffer.length != UUID_SIZE ||
+ properties->type != ACPI_TYPE_PACKAGE)
+ continue;
+
+ if (!guid_equal((guid_t *)guid->buffer.pointer,
+ &acpi_scmi_uuid))
+ continue;
+
+ ret = acpi_scmi_parse_properties(map, properties);
+ break;
+ }
+
+out_free:
+ ACPI_FREE(buf.pointer);
+ return ret;
+}
+
+static bool
+pcc_transport_map_has_ss_id(struct pcc_transport_map *map, u32 pcc_ss_id)
+{
+ struct pcc_transport *p;
+ int idx;
+
+ hash_for_each(map->table, idx, p, hnode) {
+ if (p->pcc_ss_id == pcc_ss_id)
+ return true;
+ }
+
+ return false;
+}
+
+static int pcc_transport_map_validate(struct pcc_transport_map *map)
+{
+ struct pcc_transport_map *iter;
+ struct pcc_transport *p;
+ int idx;
+
+ list_for_each_entry(iter, &pcc_transport_maps, node) {
+ hash_for_each(map->table, idx, p, hnode) {
+ if (pcc_transport_map_has_ss_id(iter, p->pcc_ss_id))
+ return -EEXIST;
+ }
+ }
+
+ return 0;
+}
+
+static
+struct pcc_transport_map *pcc_transport_map_find(struct fwnode_handle *fwnode)
+{
+ struct pcc_transport_map *map;
+
+ list_for_each_entry(map, &pcc_transport_maps, node) {
+ if (map->fwnode == fwnode)
+ return map;
+ }
+
+ return NULL;
+}
+
+static
+struct pcc_transport_map *pcc_transport_map_get(struct fwnode_handle *fwnode)
+{
+ struct pcc_transport_map *map;
+ int ret;
+
+ map = pcc_transport_map_find(fwnode);
+ if (map)
+ return map;
+
+ map = kzalloc_obj(*map, GFP_KERNEL);
+ if (!map)
+ return ERR_PTR(-ENOMEM);
+
+ hash_init(map->table);
+ ret = acpi_scmi_namespace_fwnode_parse(fwnode, map);
+ if (ret)
+ goto err_free_map;
+
+ ret = pcc_transport_map_validate(map);
+ if (ret)
+ goto err_free_map;
+
+ map->fwnode = fwnode_handle_get(fwnode);
+ list_add_tail(&map->node, &pcc_transport_maps);
+
+ return map;
+
+err_free_map:
+ acpi_scmi_clear_transport_map(map);
+ kfree(map);
+ return ERR_PTR(ret);
+}
+
+static int pcc_transport_map_manage(struct pcc_transport_map *map,
+ struct device *dev)
+{
+ int ret;
+
+ if (!dev || map->dev == dev)
+ return 0;
+ if (map->dev)
+ return -EBUSY;
+
+ /*
+ * Release the cached map after the SCMI remove path tears down channels.
+ */
+ ret = devm_add_action(dev, pcc_transport_map_release, map);
+ if (ret)
+ return ret;
+
+ map->dev = dev;
+
+ return 0;
+}
+
+static int pcc_lookup_ss_id(struct pcc_transport_map *map, u32 prot_id, bool tx)
+{
+ struct pcc_transport *p;
+ int idx;
+
+ hash_for_each(map->table, idx, p, hnode) {
+ if (p->protocol_id != prot_id)
+ continue;
+
+ if ((!tx && (p->flags & SCMI_TRANSPORT_P2A_CHANNEL)) ||
+ (tx && !(p->flags & SCMI_TRANSPORT_P2A_CHANNEL)))
+ return p->pcc_ss_id;
+ }
+
+ return -ENOENT;
+}
+
+static int pcc_get_ss_id(struct fwnode_handle *fwnode, u32 prot_id, bool tx,
+ struct device *dev)
+{
+ struct pcc_transport_map *map;
+ int ret;
+
+ if (!fwnode)
+ return -EINVAL;
+
+ guard(mutex)(&pcc_transport_maps_lock);
+ map = pcc_transport_map_get(fwnode);
+ if (IS_ERR(map))
+ return PTR_ERR(map);
+
+ ret = pcc_transport_map_manage(map, dev);
+ if (ret)
+ return ret;
+
+ return pcc_lookup_ss_id(map, prot_id, tx);
+}
+
+static bool
+pcc_chan_available(struct fwnode_handle *fwnode, int prot_id, int idx)
+{
+ return pcc_get_ss_id(fwnode, prot_id, !idx, NULL) >= 0;
+}
+
+static void tx_prepare(struct mbox_client *cl, void *m)
+{
+ struct scmi_pcc *smbox = client_to_scmi_pcc(cl);
+ struct pcc_shared_mem __iomem *shmem = smbox->pchan->shmem;
+ struct scmi_xfer *xfer = m;
+
+ /*
+ * PCC take cares not to call tx_prepare until last transmit is done.
+ * Request platform interrupt notification if available.
+ */
+ if (xfer->tx.buf)
+ memcpy_toio(shmem->msg_payload, xfer->tx.buf, xfer->tx.len);
+ iowrite32(SCMI_PCC_MSG_HEADER_SIZE + xfer->tx.len,
+ &shmem->header.length);
+ iowrite32(pack_scmi_header(&xfer->hdr), &shmem->header.command);
+ iowrite32(smbox->pchan->mchan->mbox->txdone_irq ?
+ PCC_CMD_COMPLETION_NOTIFY : 0, &shmem->header.flags);
+}
+
+static void rx_callback(struct mbox_client *cl, void *m)
+{
+ struct scmi_pcc *smbox = client_to_scmi_pcc(cl);
+ struct pcc_shared_mem __iomem *shmem = smbox->pchan->shmem;
+
+ core->rx_callback(smbox->cinfo, ioread32(&shmem->header.command), NULL);
+}
+
+static int pcc_chan_validate_shmem(struct scmi_chan_info *cinfo,
+ struct scmi_pcc *smbox, int ss_id)
+{
+ struct pcc_shared_mem __iomem *shmem = smbox->pchan->shmem;
+ u32 valid_signature = ss_id + PCC_SIGNATURE;
+
+ if (smbox->pchan->shmem_size < SCMI_PCC_SHMEM_OVERHEAD ||
+ smbox->pchan->shmem_size - SCMI_PCC_SHMEM_OVERHEAD <
+ cinfo->max_msg_size) {
+ dev_err(cinfo->dev, "misconfigured SCMI PCC shared memory\n");
+ return -ENOSPC;
+ }
+
+ if (ioread32(&shmem->header.signature) != valid_signature) {
+ dev_err(cinfo->dev, "invalid PCC shared memory signature\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int pcc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+ bool tx)
+{
+ const char *desc = tx ? "Tx" : "Rx";
+ struct device *cdev = cinfo->dev;
+ struct scmi_pcc *smbox;
+ struct mbox_client *cl;
+ int ret, ss_id;
+
+ smbox = devm_kzalloc(dev, sizeof(*smbox), GFP_KERNEL);
+ if (!smbox)
+ return -ENOMEM;
+
+ cl = &smbox->cl;
+ cl->dev = cdev;
+ cl->tx_prepare = tx ? tx_prepare : NULL;
+ cl->rx_callback = rx_callback;
+ cl->tx_block = false;
+
+ ss_id = pcc_get_ss_id(dev_fwnode(cinfo->dev), cinfo->id, tx, dev);
+ if (ss_id < 0)
+ return ss_id;
+
+ smbox->pchan = pcc_mbox_request_channel(cl, ss_id);
+ if (IS_ERR(smbox->pchan)) {
+ ret = PTR_ERR(smbox->pchan);
+ if (ret != -EPROBE_DEFER)
+ dev_err(cdev,
+ "failed to request SCMI %s mailbox\n", desc);
+ return ret;
+ }
+
+ ret = pcc_chan_validate_shmem(cinfo, smbox, ss_id);
+ if (ret) {
+ pcc_mbox_free_channel(smbox->pchan);
+ return ret;
+ }
+
+ cinfo->transport_info = smbox;
+ smbox->cinfo = cinfo;
+
+ return 0;
+}
+
+static int pcc_chan_free(int id, void *p, void *data)
+{
+ struct scmi_chan_info *cinfo = p;
+ struct scmi_pcc *smbox = cinfo->transport_info;
+
+ if (!smbox || IS_ERR_OR_NULL(smbox->pchan))
+ return 0;
+
+ pcc_mbox_free_channel(smbox->pchan);
+ cinfo->transport_info = NULL;
+ smbox->pchan = NULL;
+ smbox->cinfo = NULL;
+
+ return 0;
+}
+
+static int
+pcc_send_message(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
+{
+ struct scmi_pcc *smbox = cinfo->transport_info;
+ int ret;
+
+ /*
+ * The mailbox layer has its own queue. However the mailbox queue
+ * confuses the per message SCMI timeouts since the clock starts when
+ * the message is submitted into the mailbox queue. So when multiple
+ * messages are queued up the clock starts on all messages instead of
+ * only the one inflight.
+ */
+ ret = mbox_send_message(smbox->pchan->mchan, xfer);
+ /* mbox_send_message returns non-negative value on success */
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static void pcc_fetch_response(struct scmi_chan_info *cinfo,
+ struct scmi_xfer *xfer)
+{
+ struct scmi_pcc *smbox = cinfo->transport_info;
+ struct pcc_shared_mem __iomem *shmem = smbox->pchan->shmem;
+ size_t len = ioread32(&shmem->header.length);
+ size_t payload_len;
+
+ xfer->hdr.status = ioread32(shmem->msg_payload);
+ payload_len = len > SCMI_PCC_RESPONSE_OVERHEAD ?
+ len - SCMI_PCC_RESPONSE_OVERHEAD : 0;
+ xfer->rx.len = min(xfer->rx.len, payload_len);
+
+ /* msg_payload starts after the header, so skip only the status here. */
+ memcpy_fromio(xfer->rx.buf, shmem->msg_payload + SCMI_PCC_STATUS_SIZE,
+ xfer->rx.len);
+}
+
+static void pcc_fetch_notification(struct scmi_chan_info *cinfo, size_t max_len,
+ struct scmi_xfer *xfer)
+{
+ struct scmi_pcc *smbox = cinfo->transport_info;
+ struct pcc_shared_mem __iomem *shmem = smbox->pchan->shmem;
+ size_t len = ioread32(&shmem->header.length);
+ size_t payload_len;
+
+ payload_len = len > SCMI_PCC_MSG_HEADER_SIZE ?
+ len - SCMI_PCC_MSG_HEADER_SIZE : 0;
+ xfer->rx.len = min(max_len, payload_len);
+ memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);
+}
+
+static const struct scmi_transport_ops scmi_pcc_ops = {
+ .chan_available = pcc_chan_available,
+ .chan_setup = pcc_chan_setup,
+ .chan_free = pcc_chan_free,
+ .send_message = pcc_send_message,
+ .fetch_response = pcc_fetch_response,
+ .fetch_notification = pcc_fetch_notification,
+};
+
+static struct scmi_desc scmi_pcc_desc = {
+ .ops = &scmi_pcc_ops,
+ .max_rx_timeout_ms = 30,
+ .max_msg = MBOX_TX_QUEUE_LEN,
+ .max_msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE,
+};
+
+static const struct acpi_device_id scmi_acpi_ids[] = {
+ { .id = "ARML0001" },
+ { }
+};
+
+MODULE_DEVICE_TABLE(acpi, scmi_acpi_ids);
+
+DEFINE_SCMI_ACPI_TRANSPORT_DRIVER(scmi_pcc, scmi_pcc_driver,
+ scmi_pcc_desc, scmi_acpi_ids, core);
+
+static int __init scmi_pcc_init(void)
+{
+ return platform_driver_register(&scmi_pcc_driver);
+}
+
+static void __exit scmi_pcc_exit(void)
+{
+ platform_driver_unregister(&scmi_pcc_driver);
+ acpi_scmi_clear_transport_maps();
+}
+module_init(scmi_pcc_init);
+module_exit(scmi_pcc_exit);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@kernel.org>");
+MODULE_DESCRIPTION("SCMI ACPI PCC Transport driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/arm_scmi/transports/smc.c b/drivers/firmware/arm_scmi/transports/smc.c
index 1fce3ccdeb7f..7fb2736247a3 100644
--- a/drivers/firmware/arm_scmi/transports/smc.c
+++ b/drivers/firmware/arm_scmi/transports/smc.c
@@ -84,10 +84,16 @@ static irqreturn_t smc_msg_done_isr(int irq, void *data)
return IRQ_HANDLED;
}
-static bool smc_chan_available(struct device_node *of_node, int idx)
+static bool
+smc_chan_available(struct fwnode_handle *fwnode, int prot_id, int idx)
{
+ struct device_node *of_node = to_of_node(fwnode);
+
+ if (!of_node)
+ return false;
+
struct device_node *np __free(device_node) =
- of_parse_phandle(of_node, "shmem", 0);
+ of_parse_phandle(of_node, "shmem", 0);
if (!np)
return false;
diff --git a/drivers/firmware/arm_scmi/transports/virtio.c b/drivers/firmware/arm_scmi/transports/virtio.c
index 3282d8271839..3d608c8c4fe8 100644
--- a/drivers/firmware/arm_scmi/transports/virtio.c
+++ b/drivers/firmware/arm_scmi/transports/virtio.c
@@ -375,7 +375,8 @@ static unsigned int virtio_get_max_msg(struct scmi_chan_info *base_cinfo)
return vioch->max_msg;
}
-static bool virtio_chan_available(struct device_node *of_node, int idx)
+static bool
+virtio_chan_available(struct fwnode_handle *fwnode, int prot_id, int idx)
{
struct scmi_vio_channel *channels, *vioch = NULL;
diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c
index ed79e823157a..7e3f45ddf0c1 100644
--- a/drivers/firmware/imx/imx-dsp.c
+++ b/drivers/firmware/imx/imx-dsp.c
@@ -99,8 +99,10 @@ static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc)
else
chan_name = kasprintf(GFP_KERNEL, "rxdb%d", i - 2);
- if (!chan_name)
- return -ENOMEM;
+ if (!chan_name) {
+ ret = -ENOMEM;
+ goto out;
+ }
dsp_chan = &dsp_ipc->chans[i];
dsp_chan->name = chan_name;
diff --git a/drivers/firmware/microchip/mpfs-auto-update.c b/drivers/firmware/microchip/mpfs-auto-update.c
index 1211fd8d0463..b97d34bd2354 100644
--- a/drivers/firmware/microchip/mpfs-auto-update.c
+++ b/drivers/firmware/microchip/mpfs-auto-update.c
@@ -156,7 +156,7 @@ static int mpfs_auto_update_verify_image(struct fw_upload *fw_uploader)
{
struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
u32 *response_msg __free(kfree) =
- kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL);
+ kzalloc_objs(*response_msg, AUTO_UPDATE_FEATURE_RESP_SIZE);
struct mpfs_mss_response *response __free(kfree) =
kzalloc_obj(struct mpfs_mss_response);
struct mpfs_mss_msg *message __free(kfree) =
@@ -358,7 +358,7 @@ static const struct fw_upload_ops mpfs_auto_update_ops = {
static int mpfs_auto_update_available(struct mpfs_auto_update_priv *priv)
{
u32 *response_msg __free(kfree) =
- kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL);
+ kzalloc_objs(*response_msg, AUTO_UPDATE_FEATURE_RESP_SIZE);
struct mpfs_mss_response *response __free(kfree) =
kzalloc_obj(struct mpfs_mss_response);
struct mpfs_mss_msg *message __free(kfree) =
diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index 95b968d88dc3..3ad22f8fc3e5 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -7,7 +7,7 @@
menu "Qualcomm firmware drivers"
config QCOM_PAS
- tristate "Qualcomm generic PAS interface driver"
+ tristate "Qualcomm generic PAS interface driver" if COMPILE_TEST
help
Enable the generic Peripheral Authentication Service (PAS) provided
by the firmware. It acts as the common layer with different TZ
@@ -16,6 +16,7 @@ config QCOM_PAS
config QCOM_PAS_TEE
tristate "Qualcomm PAS TEE interface driver"
+ depends on ARCH_QCOM || COMPILE_TEST
select QCOM_PAS
depends on TEE
depends on !CPU_BIG_ENDIAN
@@ -25,7 +26,7 @@ config QCOM_PAS_TEE
by the firmware TEE implementation as the backend.
config QCOM_SCM
- tristate "Qualcomm PAS SCM interface driver"
+ tristate "Qualcomm PAS SCM interface driver" if ARCH_QCOM || COMPILE_TEST
select QCOM_PAS
select QCOM_TZMEM
default y if ARCH_QCOM
diff --git a/drivers/firmware/qcom/qcom_scm-legacy.c b/drivers/firmware/qcom/qcom_scm-legacy.c
index 029e6d117cb8..fe751ee512da 100644
--- a/drivers/firmware/qcom/qcom_scm-legacy.c
+++ b/drivers/firmware/qcom/qcom_scm-legacy.c
@@ -219,7 +219,7 @@ out:
* @res: SCM call return values
*
* This shall only be used with commands that are guaranteed to be
- * uninterruptable, atomic and SMP safe.
+ * uninterruptible, atomic and SMP safe.
*/
int scm_legacy_call_atomic(struct device *unused,
const struct qcom_scm_desc *desc,
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 3eaa4c9ccf3c..43e250faea75 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -576,26 +576,6 @@ static void qcom_scm_set_download_mode(struct qcom_scm *scm, u32 dload_mode)
writel_relaxed(minidump_dest, scm->minidump_sram);
}
-struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev,
- u32 pas_id,
- phys_addr_t mem_phys,
- size_t mem_size)
-{
- struct qcom_pas_context *ctx;
-
- ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return ERR_PTR(-ENOMEM);
-
- ctx->dev = dev;
- ctx->pas_id = pas_id;
- ctx->mem_phys = mem_phys;
- ctx->mem_size = mem_size;
-
- return (struct qcom_scm_pas_context *)ctx;
-}
-EXPORT_SYMBOL_GPL(devm_qcom_scm_pas_context_alloc);
-
static int __qcom_scm_pas_init_image(struct device *dev, u32 pas_id,
dma_addr_t mdata_phys,
struct qcom_scm_res *res)
@@ -653,9 +633,9 @@ static int qcom_scm_pas_prep_and_init_image(struct device *dev,
return ret ? : res.result[0];
}
-static int __qcom_scm_pas_init_image2(struct device *dev, u32 pas_id,
- const void *metadata, size_t size,
- struct qcom_pas_context *ctx)
+static int qcom_scm_pas_init_image(struct device *dev, u32 pas_id,
+ const void *metadata, size_t size,
+ struct qcom_pas_context *ctx)
{
struct qcom_scm_res res;
dma_addr_t mdata_phys;
@@ -695,16 +675,8 @@ static int __qcom_scm_pas_init_image2(struct device *dev, u32 pas_id,
return ret ? : res.result[0];
}
-int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
- struct qcom_scm_pas_context *ctx)
-{
- return __qcom_scm_pas_init_image2(__scm->dev, pas_id, metadata, size,
- (struct qcom_pas_context *)ctx);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image);
-
-static void __qcom_scm_pas_metadata_release(struct device *dev,
- struct qcom_pas_context *ctx)
+static void qcom_scm_pas_metadata_release(struct device *dev,
+ struct qcom_pas_context *ctx)
{
if (ctx->use_tzmem)
qcom_tzmem_free(ctx->ptr);
@@ -714,15 +686,8 @@ static void __qcom_scm_pas_metadata_release(struct device *dev,
ctx->ptr = NULL;
}
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx)
-{
- __qcom_scm_pas_metadata_release(__scm->dev,
- (struct qcom_pas_context *)ctx);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
-
-static int __qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id,
- phys_addr_t addr, phys_addr_t size)
+static int qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id,
+ phys_addr_t addr, phys_addr_t size)
{
int ret;
struct qcom_scm_desc desc = {
@@ -753,12 +718,6 @@ disable_clk:
return ret ? : res.result[0];
}
-int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
-{
- return __qcom_scm_pas_mem_setup(__scm->dev, pas_id, addr, size);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup);
-
static void *__qcom_scm_pas_get_rsc_table(struct device *dev, u32 pas_id,
void *input_rt_tzm,
size_t input_rt_size,
@@ -812,11 +771,10 @@ free_output_rt:
return ret ? ERR_PTR(ret) : output_rt_tzm;
}
-static void *__qcom_scm_pas_get_rsc_table2(struct device *dev,
- struct qcom_pas_context *ctx,
- void *input_rt,
- size_t input_rt_size,
- size_t *output_rt_size)
+static void *qcom_scm_pas_get_rsc_table(struct device *dev,
+ struct qcom_pas_context *ctx,
+ void *input_rt, size_t input_rt_size,
+ size_t *output_rt_size)
{
struct resource_table empty_rsc = {};
size_t size = SZ_16K;
@@ -854,17 +812,27 @@ static void *__qcom_scm_pas_get_rsc_table2(struct device *dev,
output_rt_tzm = __qcom_scm_pas_get_rsc_table(dev, ctx->pas_id,
input_rt_tzm,
input_rt_size, &size);
- if (PTR_ERR(output_rt_tzm) == -EOVERFLOW)
- /* Try again with the size requested by the TZ */
+ if (PTR_ERR(output_rt_tzm) == -EOVERFLOW) {
+ /* Try again with a page-aligned size requested by the TZ. */
+ size = PAGE_ALIGN(size);
output_rt_tzm = __qcom_scm_pas_get_rsc_table(dev, ctx->pas_id,
input_rt_tzm,
input_rt_size,
&size);
+ }
if (IS_ERR(output_rt_tzm)) {
ret = PTR_ERR(output_rt_tzm);
goto free_input_rt;
}
+ *output_rt_size = size;
+
+ /* A zero-sized table means that TrustZone has no resource table. */
+ if (!size) {
+ tbl_ptr = NULL;
+ goto free_output_rt;
+ }
+
tbl_ptr = kmemdup(output_rt_tzm, size, GFP_KERNEL);
if (!tbl_ptr) {
qcom_tzmem_free(output_rt_tzm);
@@ -872,7 +840,7 @@ static void *__qcom_scm_pas_get_rsc_table2(struct device *dev,
goto free_input_rt;
}
- *output_rt_size = size;
+free_output_rt:
qcom_tzmem_free(output_rt_tzm);
free_input_rt:
@@ -887,19 +855,7 @@ disable_clk:
return ret ? ERR_PTR(ret) : tbl_ptr;
}
-struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx,
- void *input_rt,
- size_t input_rt_size,
- size_t *output_rt_size)
-{
- return __qcom_scm_pas_get_rsc_table2(__scm->dev,
- (struct qcom_pas_context *)ctx,
- input_rt, input_rt_size,
- output_rt_size);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_get_rsc_table);
-
-static int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id)
+static int qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
@@ -928,14 +884,8 @@ disable_clk:
return ret ? : res.result[0];
}
-int qcom_scm_pas_auth_and_reset(u32 pas_id)
-{
- return __qcom_scm_pas_auth_and_reset(__scm->dev, pas_id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_reset);
-
-static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
- struct qcom_pas_context *ctx)
+static int qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
+ struct qcom_pas_context *ctx)
{
u64 handle;
int ret;
@@ -946,7 +896,7 @@ static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
* memory region and then invokes a call to TrustZone to authenticate.
*/
if (!ctx->use_tzmem)
- return __qcom_scm_pas_auth_and_reset(dev, ctx->pas_id);
+ return qcom_scm_pas_auth_and_reset(dev, ctx->pas_id);
/*
* When Linux runs @ EL2 Linux must create the shmbridge itself and then
@@ -956,21 +906,14 @@ static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
if (ret)
return ret;
- ret = __qcom_scm_pas_auth_and_reset(dev, ctx->pas_id);
+ ret = qcom_scm_pas_auth_and_reset(dev, ctx->pas_id);
qcom_tzmem_shm_bridge_delete(handle);
return ret;
}
-int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx)
-{
- return __qcom_scm_pas_prepare_and_auth_reset(__scm->dev,
- (struct qcom_pas_context *)ctx);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_prepare_and_auth_reset);
-
-static int __qcom_scm_pas_set_remote_state(struct device *dev, u32 state,
- u32 pas_id)
+static int qcom_scm_pas_set_remote_state(struct device *dev, u32 state,
+ u32 pas_id)
{
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_BOOT,
@@ -988,13 +931,7 @@ static int __qcom_scm_pas_set_remote_state(struct device *dev, u32 state,
return ret ? : res.result[0];
}
-int qcom_scm_set_remote_state(u32 state, u32 id)
-{
- return __qcom_scm_pas_set_remote_state(__scm->dev, state, id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_set_remote_state);
-
-static int __qcom_scm_pas_shutdown(struct device *dev, u32 pas_id)
+static int qcom_scm_pas_shutdown(struct device *dev, u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
@@ -1023,13 +960,7 @@ disable_clk:
return ret ? : res.result[0];
}
-int qcom_scm_pas_shutdown(u32 pas_id)
-{
- return __qcom_scm_pas_shutdown(__scm->dev, pas_id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_shutdown);
-
-static bool __qcom_scm_pas_supported(struct device *dev, u32 pas_id)
+static bool qcom_scm_pas_supported(struct device *dev, u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
@@ -1050,23 +981,17 @@ static bool __qcom_scm_pas_supported(struct device *dev, u32 pas_id)
return ret ? false : !!res.result[0];
}
-bool qcom_scm_pas_supported(u32 pas_id)
-{
- return __qcom_scm_pas_supported(__scm->dev, pas_id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_supported);
-
static struct qcom_pas_ops qcom_pas_ops_scm = {
.drv_name = "qcom_scm",
- .supported = __qcom_scm_pas_supported,
- .init_image = __qcom_scm_pas_init_image2,
- .mem_setup = __qcom_scm_pas_mem_setup,
- .get_rsc_table = __qcom_scm_pas_get_rsc_table2,
- .auth_and_reset = __qcom_scm_pas_auth_and_reset,
- .prepare_and_auth_reset = __qcom_scm_pas_prepare_and_auth_reset,
- .set_remote_state = __qcom_scm_pas_set_remote_state,
- .shutdown = __qcom_scm_pas_shutdown,
- .metadata_release = __qcom_scm_pas_metadata_release,
+ .supported = qcom_scm_pas_supported,
+ .init_image = qcom_scm_pas_init_image,
+ .mem_setup = qcom_scm_pas_mem_setup,
+ .get_rsc_table = qcom_scm_pas_get_rsc_table,
+ .auth_and_reset = qcom_scm_pas_auth_and_reset,
+ .prepare_and_auth_reset = qcom_scm_pas_prepare_and_auth_reset,
+ .set_remote_state = qcom_scm_pas_set_remote_state,
+ .shutdown = qcom_scm_pas_shutdown,
+ .metadata_release = qcom_scm_pas_metadata_release,
};
/**
@@ -2302,6 +2227,7 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_send);
static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
{ .compatible = "asus,vivobook-s15" },
{ .compatible = "asus,vivobook-s15-x1p4" },
+ { .compatible = "asus,zenbook-a14-ux3407na" },
{ .compatible = "asus,zenbook-a14-ux3407qa" },
{ .compatible = "asus,zenbook-a14-ux3407ra" },
{ .compatible = "asus,zenbook-a16-ux3607oa" },
@@ -2311,14 +2237,17 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
{ .compatible = "ecs,liva-qc710" },
{ .compatible = "honor,magicbook-art-14-snapdragon" },
{ .compatible = "hp,elitebook-ultra-g1q" },
+ { .compatible = "hp,elitebook-x-g2q" },
{ .compatible = "hp,omnibook-x14" },
{ .compatible = "huawei,gaokun3" },
{ .compatible = "lenovo,flex-5g" },
{ .compatible = "lenovo,ideacentre-mini-01q8x10" },
{ .compatible = "lenovo,thinkbook-16" },
{ .compatible = "lenovo,thinkpad-t14s" },
+ { .compatible = "lenovo,thinkpad-t14s-gen7" },
{ .compatible = "lenovo,thinkpad-x13s", },
{ .compatible = "lenovo,yoga-slim7x" },
+ { .compatible = "lenovo,yoga-slim7x-gen11" },
{ .compatible = "medion,sprchrgd14s1" },
{ .compatible = "microsoft,arcata", },
{ .compatible = "microsoft,surface-pro-12in", },
@@ -2327,7 +2256,9 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
{ .compatible = "microsoft,romulus13", },
{ .compatible = "microsoft,romulus15", },
{ .compatible = "qcom,glymur-crd" },
+ { .compatible = "qcom,glymur-qcb" },
{ .compatible = "qcom,hamoa-iot-evk" },
+ { .compatible = "qcom,kalambo-crd" },
{ .compatible = "qcom,mahua-crd" },
{ .compatible = "qcom,purwa-iot-evk" },
{ .compatible = "qcom,sc8180x-primus" },
@@ -2844,17 +2775,15 @@ static int qcom_scm_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = of_reserved_mem_device_init(scm->dev);
+ ret = devm_of_reserved_mem_device_init(scm->dev);
if (ret && ret != -ENODEV)
return dev_err_probe(scm->dev, ret,
"Failed to setup the reserved memory region for TZ mem\n");
ret = qcom_tzmem_enable(scm->dev);
- if (ret) {
- ret = dev_err_probe(scm->dev, ret,
- "Failed to enable the TrustZone memory allocator\n");
- goto err_rmem;
- }
+ if (ret)
+ return dev_err_probe(scm->dev, ret,
+ "Failed to enable the TrustZone memory allocator\n");
memset(&pool_config, 0, sizeof(pool_config));
pool_config.initial_size = 0;
@@ -2862,11 +2791,9 @@ static int qcom_scm_probe(struct platform_device *pdev)
pool_config.max_size = SZ_256K;
scm->mempool = devm_qcom_tzmem_pool_new(scm->dev, &pool_config);
- if (IS_ERR(scm->mempool)) {
- ret = dev_err_probe(scm->dev, PTR_ERR(scm->mempool),
- "Failed to create the SCM memory pool\n");
- goto err_rmem;
- }
+ if (IS_ERR(scm->mempool))
+ return dev_err_probe(scm->dev, PTR_ERR(scm->mempool),
+ "Failed to create the SCM memory pool\n");
ret = qcom_scm_query_waitq_count(scm);
scm->wq_cnt = ret < 0 ? QCOM_SCM_DEFAULT_WAITQ_COUNT : ret;
@@ -2942,10 +2869,6 @@ static int qcom_scm_probe(struct platform_device *pdev)
qcom_scm_gunyah_wdt_init(scm);
return 0;
-
-err_rmem:
- of_reserved_mem_device_release(scm->dev);
- return ret;
}
static void qcom_scm_shutdown(struct platform_device *pdev)
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
index 322fa928234b..e1d944d0eb63 100644
--- a/drivers/firmware/qcom/qcom_tzmem.c
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -82,6 +82,7 @@ static const char *const qcom_tzmem_blacklist[] = {
"qcom,sc8180x",
"qcom,sdm670", /* failure in GPU firmware loading */
"qcom,sdm845", /* reset in rmtfs memory assignment */
+ "qcom,sm7125", /* hang in rmtfs memory assignment */
"qcom,sm7150", /* reset in rmtfs memory assignment */
"qcom,sm8150", /* reset in rmtfs memory assignment */
NULL
@@ -516,7 +517,7 @@ int qcom_tzmem_enable(struct device *dev)
static int result;
qcom_tzmem_dev = dev;
- DO_ONCE(qcom_tzmem_do_init, &result);
+ DO_ONCE_SLEEPABLE(qcom_tzmem_do_init, &result);
return result;
}
EXPORT_SYMBOL_GPL(qcom_tzmem_enable);
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 33d7c4a4181e..5fa63ff7c74a 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -4050,7 +4050,7 @@ static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
.default_host_id = 2,
/* Conservative duration */
.max_rx_timeout_ms = 1000,
- /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
+ /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle up to 128 messages! */
.max_msgs = 20,
.max_msg_size = 64,
};
@@ -4060,7 +4060,7 @@ static const struct ti_sci_desc ti_sci_pmmc_am654_desc = {
.default_host_id = 12,
/* Conservative duration */
.max_rx_timeout_ms = 10000,
- /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
+ /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle up to 128 messages! */
.max_msgs = 20,
.max_msg_size = 60,
};
@@ -4132,7 +4132,7 @@ static int ti_sci_probe(struct platform_device *pdev)
/* Pre-initialize the buffer pointer to pre-allocated buffers */
for (i = 0, xfer = minfo->xfer_block; i < desc->max_msgs; i++, xfer++) {
- xfer->xfer_buf = devm_kcalloc(dev, 1, desc->max_msg_size,
+ xfer->xfer_buf = devm_kzalloc(dev, desc->max_msg_size,
GFP_KERNEL);
if (!xfer->xfer_buf)
return -ENOMEM;
diff --git a/drivers/firmware/xilinx/zynqmp-ufs.c b/drivers/firmware/xilinx/zynqmp-ufs.c
index 85da8a822f3a..81ccf61a037c 100644
--- a/drivers/firmware/xilinx/zynqmp-ufs.c
+++ b/drivers/firmware/xilinx/zynqmp-ufs.c
@@ -5,6 +5,7 @@
* Copyright (C) 2025 Advanced Micro Devices, Inc.
*/
+#include <linux/delay.h>
#include <linux/firmware/xlnx-zynqmp.h>
#include <linux/module.h>
@@ -33,7 +34,7 @@
*
* Return: Returns 0 on success or error value on failure.
*/
-int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready)
+static int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready)
{
u32 regval;
int ret;
@@ -53,7 +54,6 @@ int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready)
return ret;
}
-EXPORT_SYMBOL_GPL(zynqmp_pm_is_mphy_tx_rx_config_ready);
/**
* zynqmp_pm_is_sram_init_done - check SRAM initialization
@@ -61,7 +61,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_is_mphy_tx_rx_config_ready);
*
* Return: Returns 0 on success or error value on failure.
*/
-int zynqmp_pm_is_sram_init_done(bool *is_done)
+static int zynqmp_pm_is_sram_init_done(bool *is_done)
{
u32 regval;
int ret;
@@ -81,7 +81,69 @@ int zynqmp_pm_is_sram_init_done(bool *is_done)
return ret;
}
-EXPORT_SYMBOL_GPL(zynqmp_pm_is_sram_init_done);
+
+/**
+ * zynqmp_pm_wait_mphy_tx_rx_config_ready - wait for M-PHY TX-RX config ready
+ * @timeout_us: Caller-supplied timeout budget in microseconds
+ *
+ * Poll the M-PHY TX-RX configuration-ready status until it settles or the
+ * timeout elapses. The poll loop is EEMI-specific (legacy firmware only offers
+ * the per-read status primitive), so it lives here in the firmware driver
+ * rather than in the UFS controller driver; an SCMI-based backend can instead
+ * offload the wait to the platform in a single call. The timeout budget is
+ * owned by the caller (UFS driver), keeping the policy with the consumer.
+ *
+ * Return: Returns 0 once ready, -ETIMEDOUT on timeout, or error value.
+ */
+int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us)
+{
+ bool is_ready;
+ int ret;
+
+ while (timeout_us--) {
+ ret = zynqmp_pm_is_mphy_tx_rx_config_ready(&is_ready);
+ if (ret)
+ return ret;
+
+ if (!is_ready)
+ return 0;
+
+ usleep_range(1, 5);
+ }
+
+ return -ETIMEDOUT;
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_wait_mphy_tx_rx_config_ready);
+
+/**
+ * zynqmp_pm_wait_sram_init_done - wait for SRAM initialization to complete
+ * @timeout_us: Caller-supplied timeout budget in microseconds
+ *
+ * Poll the SRAM initialization-done status until it is set or the timeout
+ * elapses. As with the M-PHY wait, the poll loop is EEMI-specific and kept in
+ * the firmware driver so the UFS controller driver stays backend-agnostic.
+ *
+ * Return: Returns 0 once done, -ETIMEDOUT on timeout, or error value.
+ */
+int zynqmp_pm_wait_sram_init_done(u32 timeout_us)
+{
+ bool is_done;
+ int ret;
+
+ while (timeout_us--) {
+ ret = zynqmp_pm_is_sram_init_done(&is_done);
+ if (ret)
+ return ret;
+
+ if (is_done)
+ return 0;
+
+ usleep_range(1, 5);
+ }
+
+ return -ETIMEDOUT;
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_wait_sram_init_done);
/**
* zynqmp_pm_set_sram_bypass - Set SRAM bypass Control
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index fe650747ac91..d76660c55354 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -1527,7 +1527,6 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_request_wake);
*/
int zynqmp_pm_start_rpu(const u32 node, const u64 bootaddr)
{
- enum rpu_boot_mem bootmem;
int ret;
/*
@@ -1536,22 +1535,55 @@ int zynqmp_pm_start_rpu(const u32 node, const u64 bootaddr)
* starts at the base-address and subsequent vectors are on 4-byte
* boundaries.
*
+ * The Cortex-R5 cores can boot from TCM and OCM memories.
* Exception vectors can start either from 0x0000_0000 (LOVEC) or
* from 0xFFFF_0000 (HIVEC) which is mapped in the OCM (On-Chip Memory)
*
* Usually firmware will put Exception vectors at LOVEC.
*
+ * The Cortex-R52 cores can boot from DDR and TCM.
+ * That means vector table can be at address 0x0 or at any DDR address
+ * that is in the 32-bit address range. Note that booting from DDR
+ * address 0x0 is not supported and the user must always assume that if
+ * 0x0 address is passed, then it will be TCM boot.
+ *
* It is not recommend that you change the exception vector.
* Changing the EVP to HIVEC will result in increased interrupt latency
* and jitter. Also, if the OCM is secured and the Cortex-R5F processor
* is non-secured, then the Cortex-R5F processor cannot access the
* HIVEC exception vectors in the OCM.
*/
- bootmem = (bootaddr >= 0xFFFC0000) ?
- PM_RPU_BOOTMEM_HIVEC : PM_RPU_BOOTMEM_LOVEC;
+ if (upper_32_bits(bootaddr)) {
+ pr_err("invalid bootaddr = 0x%llx\n", bootaddr);
+ return -EINVAL;
+ }
- pr_debug("RPU boot addr 0x%llx from %s.", bootaddr,
- bootmem == PM_RPU_BOOTMEM_HIVEC ? "OCM" : "TCM");
+ /*
+ * New platforms can boot from DDR and require the DDR address
+ * to be configured explicitly. If the correct version of the
+ * IOCTL_RPU_BOOT_ADDR_CONFIG ioctl is not supported, do not
+ * treat it as a failure. If a DDR address is passed on other
+ * platforms, the PM request wake EEMI call will still fail and
+ * the RPU won't boot.
+ */
+ ret = zynqmp_pm_is_function_supported(PM_IOCTL,
+ IOCTL_RPU_BOOT_ADDR_CONFIG);
+ if (!ret) {
+ /* config ddr boot address */
+ ret = zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3,
+ node,
+ IOCTL_RPU_BOOT_ADDR_CONFIG,
+ bootaddr);
+ if (ret < 0) {
+ pr_err("failed to set RPU Boot address 0x%llx\n",
+ bootaddr);
+ return ret;
+ }
+ } else if (ret != -EOPNOTSUPP && ret != -ENODATA) {
+ pr_err("ioctl rpu boot addr config ver check failed %d\n",
+ ret);
+ return ret;
+ }
/* Request node before starting RPU core if new version of API is supported */
if (zynqmp_pm_feature(PM_REQUEST_NODE) > PM_API_VERSION_1) {
@@ -1565,7 +1597,7 @@ int zynqmp_pm_start_rpu(const u32 node, const u64 bootaddr)
}
ret = zynqmp_pm_request_wake(node, true,
- bootmem, ZYNQMP_PM_REQUEST_ACK_NO);
+ bootaddr, ZYNQMP_PM_REQUEST_ACK_NO);
if (ret)
pr_err("failed to start RPU = 0x%x\n", node);
return ret;
diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c
index 08d9e05b1b33..04ae3cfb449e 100644
--- a/drivers/memory/brcmstb_dpfe.c
+++ b/drivers/memory/brcmstb_dpfe.c
@@ -182,6 +182,8 @@ struct brcmstb_dpfe_priv {
void __iomem *regs;
void __iomem *dmem;
void __iomem *imem;
+ resource_size_t regs_size;
+ resource_size_t dmem_size;
struct device *dev;
const struct dpfe_api *dpfe_api;
struct mutex lock;
@@ -401,9 +403,14 @@ static void __iomem *get_msg_ptr(struct brcmstb_dpfe_priv *priv, u32 response,
*/
switch (msg_type) {
case 1:
+ if (DCPU_MSG_RAM_START + offset + DRAM_VENDOR_ERROR +
+ sizeof(u32) > priv->regs_size)
+ goto bad_offset;
ptr = priv->regs + DCPU_MSG_RAM_START + offset;
break;
case 0:
+ if (offset + DRAM_VENDOR_ERROR + sizeof(u32) > priv->dmem_size)
+ goto bad_offset;
ptr = priv->dmem + offset;
break;
default:
@@ -415,6 +422,12 @@ static void __iomem *get_msg_ptr(struct brcmstb_dpfe_priv *priv, u32 response,
}
return ptr;
+
+bad_offset:
+ dev_err(priv->dev, "DCPU returned out-of-range offset %#x\n", offset);
+ if (buf && size)
+ *size = sprintf(buf, "ERROR: DCPU offset out of range\n");
+ return NULL;
}
static void __finalize_command(struct brcmstb_dpfe_priv *priv)
@@ -490,6 +503,8 @@ static int __send_command(struct brcmstb_dpfe_priv *priv, unsigned int cmd,
for (i = 0; i < MSG_FIELD_MAX; i++)
result[i] = readl_relaxed(regs + DCPU_MSG_RAM(i));
chksum_idx = result[MSG_ARG_COUNT] + MSG_ARG_COUNT + 1;
+ if (chksum_idx >= MSG_FIELD_MAX)
+ ret = -EINVAL;
}
/* Tell DCPU we are done */
@@ -518,9 +533,15 @@ static int __verify_firmware(struct init_data *init,
const struct firmware *fw)
{
const struct dpfe_firmware_header *header = (void *)fw->data;
- unsigned int dmem_size, imem_size, total_size;
+ unsigned int dmem_size, imem_size;
bool is_big_endian = false;
const u32 *chksum_ptr;
+ size_t payload_size;
+
+ if (fw->size < sizeof(*header) + sizeof(*chksum_ptr))
+ return ERR_INVALID_SIZE;
+
+ payload_size = fw->size - sizeof(*header) - sizeof(*chksum_ptr);
if (header->magic == DPFE_BE_MAGIC)
is_big_endian = true;
@@ -539,13 +560,8 @@ static int __verify_firmware(struct init_data *init,
if ((dmem_size % sizeof(u32)) != 0 || (imem_size % sizeof(u32)) != 0)
return ERR_INVALID_SIZE;
- /*
- * The header + the data section + the instruction section + the
- * checksum must be equal to the total firmware size.
- */
- total_size = dmem_size + imem_size + sizeof(*header) +
- sizeof(*chksum_ptr);
- if (total_size != fw->size)
+ /* The data and instruction sections must fill the payload exactly. */
+ if (dmem_size > payload_size || imem_size != payload_size - dmem_size)
return ERR_INVALID_SIZE;
/* The checksum comes at the very end. */
@@ -858,6 +874,7 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct brcmstb_dpfe_priv *priv;
+ struct resource *res;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -869,17 +886,21 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev)
mutex_init(&priv->lock);
platform_set_drvdata(pdev, priv);
- priv->regs = devm_platform_ioremap_resource_byname(pdev, "dpfe-cpu");
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dpfe-cpu");
+ priv->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(priv->regs)) {
dev_err(dev, "couldn't map DCPU registers\n");
return -ENODEV;
}
+ priv->regs_size = resource_size(res);
- priv->dmem = devm_platform_ioremap_resource_byname(pdev, "dpfe-dmem");
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dpfe-dmem");
+ priv->dmem = devm_ioremap_resource(dev, res);
if (IS_ERR(priv->dmem)) {
dev_err(dev, "Couldn't map DCPU data memory\n");
return -ENOENT;
}
+ priv->dmem_size = resource_size(res);
priv->imem = devm_platform_ioremap_resource_byname(pdev, "dpfe-imem");
if (IS_ERR(priv->imem)) {
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index 2fadad0666b1..886c2ca0dc19 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -922,6 +922,7 @@ static struct emif_data *of_get_memory_device_details(
if (!emif || !pd || !dev_info) {
dev_err(dev, "%s: Out of memory!!\n",
__func__);
+ of_node_put(np_ddr);
goto error;
}
@@ -946,6 +947,7 @@ static struct emif_data *of_get_memory_device_details(
pd->device_info->io_width, pd->phy_type, pd->ip_rev,
emif->dev)) {
dev_err(dev, "%s: invalid device data!!\n", __func__);
+ of_node_put(np_ddr);
goto error;
}
/*
@@ -1062,7 +1064,8 @@ static struct emif_data *get_device_details(
}
if (pd->min_tck) {
- temp = devm_kzalloc(dev, sizeof(*pd->min_tck), GFP_KERNEL);
+ temp = devm_kzalloc(dev, sizeof(struct lpddr2_min_tck),
+ GFP_KERNEL);
if (temp) {
memcpy(temp, pd->min_tck, sizeof(*pd->min_tck));
pd->min_tck = temp;
@@ -1140,6 +1143,7 @@ static void emif_remove(struct platform_device *pdev)
struct emif_data *emif = platform_get_drvdata(pdev);
emif_debugfs_exit(emif);
+ of_node_put(emif->np_ddr);
}
static void emif_shutdown(struct platform_device *pdev)
diff --git a/drivers/memory/emif.h b/drivers/memory/emif.h
index 55aeb36a5bf2..5dfb09adb096 100644
--- a/drivers/memory/emif.h
+++ b/drivers/memory/emif.h
@@ -558,7 +558,7 @@
#define EMIF_SRAM_AM33_REG_LAYOUT 0x00000000
#define EMIF_SRAM_AM43_REG_LAYOUT 0x00000001
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
/*
* Structure containing shadow of important registers in EMIF
* The calculation function fills in this structure to be later used for
@@ -603,5 +603,5 @@ void ti_emif_enter_sr(void);
void ti_emif_exit_sr(void);
void ti_emif_abort_sr(void);
-#endif /* __ASSEMBLY__ */
+#endif /* __ASSEMBLER__ */
#endif /* __EMIF_H */
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index aaeba8ab211e..8c4606cbd73d 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -401,6 +401,30 @@ static const u8 mtk_smi_larb_mt8188_ostd[][SMI_LARB_PORT_NR_MAX] = {
[25] = {0x01},
};
+static const u8 mtk_smi_larb_mt8189_ostd[][SMI_LARB_PORT_NR_MAX] = {
+ [0] = {0x8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10,},
+ [1] = {0x8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10,},
+ [2] = {0x7, 0x7, 0x4, 0x4, 0x1, 0x1, 0x2, 0x2, 0x7, 0x7,},
+ [4] = {0x2f, 0x1e, 0x9, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x5, 0x1, 0x17,},
+ [7] = {0x20, 0x2, 0x1, 0x1, 0x1, 0x4, 0x2, 0x1, 0x1, 0x2, 0x3, 0x2,
+ 0xa, 0xf, 0x4, 0x6, 0x5, 0x1,},
+ [9] = {0x6, 0x3, 0xc, 0x6, 0x1, 0x4, 0x3, 0x1, 0x2, 0x4, 0x5, 0x2,
+ 0x4, 0x2, 0x3, 0xb, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+ 0x1, 0x1,},
+ [11] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+ 0x1, 0x1, 0x1, 0xb, 0x1, 0x4, 0x6, 0x5, 0x6, 0x1, 0x5, 0x2,
+ 0x9, 0x5,},
+ [13] = {0x2, 0x8, 0x8, 0x8, 0x4, 0x4, 0x4, 0x4, 0x4, 0xe, 0x4, 0x1,
+ 0x6, 0x6, 0x2,},
+ [14] = {0x1, 0x1, 0x1, 0x20, 0xe, 0x4, 0x8, 0x8, 0x6, 0x4,},
+ [16] = {0x1e, 0xc, 0x2, 0x8, 0xe, 0x2, 0x1e, 0x10, 0x4, 0x2, 0x2, 0x2,
+ 0x2, 0x2, 0x4, 0x2, 0x4,},
+ [17] = {0x1e, 0xc, 0x2, 0x8, 0xe, 0x2, 0x1e, 0x10, 0x4, 0x2, 0x2, 0x2,
+ 0x2, 0x2, 0x4, 0x2, 0x4,},
+ [19] = {0x2, 0x1, 0x3, 0x1,},
+ [20] = {0x7, 0x7, 0x3, 0x3, 0x1, 0x1,},
+};
+
static const u8 mtk_smi_larb_mt8192_ostd[][SMI_LARB_PORT_NR_MAX] = {
[0] = {0x2, 0x2, 0x28, 0xa, 0xc, 0x28,},
[1] = {0x2, 0x2, 0x18, 0x18, 0x18, 0xa, 0xc, 0x28,},
@@ -533,6 +557,13 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8188 = {
.ostd = mtk_smi_larb_mt8188_ostd,
};
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8189 = {
+ .config_port = mtk_smi_larb_config_port_gen2_general,
+ .flags_general = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG |
+ MTK_SMI_FLAG_SLEEP_CTL | MTK_SMI_FLAG_CFG_PORT_SEC_CTL,
+ .ostd = mtk_smi_larb_mt8189_ostd,
+};
+
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
.config_port = mtk_smi_larb_config_port_gen2_general,
.ostd = mtk_smi_larb_mt8192_ostd,
@@ -556,6 +587,7 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
{.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},
{.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186},
{.compatible = "mediatek,mt8188-smi-larb", .data = &mtk_smi_larb_mt8188},
+ {.compatible = "mediatek,mt8189-smi-larb", .data = &mtk_smi_larb_mt8189},
{.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192},
{.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},
{}
@@ -808,6 +840,17 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8188_vpp = {
.init = mtk_smi_common_mt8195_init,
};
+static const struct mtk_smi_common_plat mtk_smi_common_mt8189 = {
+ .type = MTK_SMI_GEN2,
+ .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(3) | F_MMU1_LARB(5) |
+ F_MMU1_LARB(7),
+};
+
+static const struct mtk_smi_common_plat mtk_smi_sub_common_mt8189 = {
+ .type = MTK_SMI_GEN2_SUB_COMM,
+ .has_gals = true,
+};
+
static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
.type = MTK_SMI_GEN2,
.has_gals = true,
@@ -852,6 +895,8 @@ static const struct of_device_id mtk_smi_common_of_ids[] = {
{.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186},
{.compatible = "mediatek,mt8188-smi-common-vdo", .data = &mtk_smi_common_mt8188_vdo},
{.compatible = "mediatek,mt8188-smi-common-vpp", .data = &mtk_smi_common_mt8188_vpp},
+ {.compatible = "mediatek,mt8189-smi-common", .data = &mtk_smi_common_mt8189},
+ {.compatible = "mediatek,mt8189-smi-sub-common", .data = &mtk_smi_sub_common_mt8189},
{.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192},
{.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo},
{.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp},
diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c
index 3755956ae906..ec901a5a99aa 100644
--- a/drivers/memory/renesas-rpc-if.c
+++ b/drivers/memory/renesas-rpc-if.c
@@ -34,6 +34,7 @@ static const struct regmap_access_table rpcif_volatile_table = {
static const struct regmap_range xspi_volatile_ranges[] = {
regmap_reg_range(XSPI_CDD0BUF0, XSPI_CDD0BUF0),
+ regmap_reg_range(XSPI_CDD1BUF0, XSPI_CDD1BUF0),
};
static const struct regmap_access_table xspi_volatile_table = {
@@ -311,6 +312,14 @@ static int xspi_hw_init_impl(struct rpcif_priv *xspi, bool hyperflash)
regmap_update_bits(xspi->regmap, XSPI_INTE, XSPI_INTE_CMDCMPE,
XSPI_INTE_CMDCMPE);
+ regmap_update_bits(xspi->regmap, XSPI_BMCTL0,
+ XSPI_BMCTL0_CS0ACC(0xff), XSPI_BMCTL0_CS0ACC(0x03));
+
+ regmap_update_bits(xspi->regmap, XSPI_BMCFG,
+ XSPI_BMCFG_WRMD | XSPI_BMCFG_MWRCOMB |
+ XSPI_BMCFG_MWRSIZE(0xff) | XSPI_BMCFG_PREEN,
+ 0 | XSPI_BMCFG_MWRCOMB | XSPI_BMCFG_MWRSIZE(0x0f) |
+ XSPI_BMCFG_PREEN);
return 0;
}
@@ -627,18 +636,14 @@ static int xspi_manual_xfer_impl(struct rpcif_priv *xspi)
u32 pos = 0, max = 8;
int ret = 0;
- regmap_update_bits(xspi->regmap, XSPI_CDCTL0, XSPI_CDCTL0_TRNUM(0x3),
+ /* Clear transaction number and request */
+ regmap_update_bits(xspi->regmap, XSPI_CDCTL0,
+ XSPI_CDCTL0_TRNUM(0x3) | XSPI_CDCTL0_TRREQ,
XSPI_CDCTL0_TRNUM(0));
- regmap_update_bits(xspi->regmap, XSPI_CDCTL0, XSPI_CDCTL0_TRREQ, 0);
-
regmap_write(xspi->regmap, XSPI_CDTBUF0,
- XSPI_CDTBUF_CMDSIZE(0x1) | XSPI_CDTBUF_CMD_FIELD(xspi->command));
-
- regmap_write(xspi->regmap, XSPI_CDABUF0, 0);
-
- regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, XSPI_CDTBUF_ADDSIZE(0x7),
- XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes));
+ XSPI_CDTBUF_CMDSIZE(0x1) | XSPI_CDTBUF_CMD_FIELD(xspi->command) |
+ XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes));
regmap_write(xspi->regmap, XSPI_CDABUF0, xspi->smadr);
@@ -651,17 +656,12 @@ static int xspi_manual_xfer_impl(struct rpcif_priv *xspi)
u32 bytes_left = xspi->xferlen - pos;
u32 nbytes, data[2], *p = data;
- regmap_update_bits(xspi->regmap, XSPI_CDTBUF0,
- XSPI_CDTBUF_TRTYPE, XSPI_CDTBUF_TRTYPE);
-
nbytes = bytes_left >= max ? max : bytes_left;
regmap_update_bits(xspi->regmap, XSPI_CDTBUF0,
- XSPI_CDTBUF_DATASIZE(0xf),
- XSPI_CDTBUF_DATASIZE(nbytes));
-
- regmap_update_bits(xspi->regmap, XSPI_CDTBUF0,
+ XSPI_CDTBUF_TRTYPE | XSPI_CDTBUF_DATASIZE(0xf) |
XSPI_CDTBUF_ADDSIZE(0x7),
+ XSPI_CDTBUF_TRTYPE | XSPI_CDTBUF_DATASIZE(nbytes) |
XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes));
memcpy(data, xspi->buffer + pos, nbytes);
@@ -693,30 +693,33 @@ static int xspi_manual_xfer_impl(struct rpcif_priv *xspi)
while (pos < xspi->xferlen) {
u32 bytes_left = xspi->xferlen - pos;
u32 nbytes, data[2], *p = data;
-
- regmap_update_bits(xspi->regmap, XSPI_CDTBUF0,
- XSPI_CDTBUF_TRTYPE,
- ~(u32)XSPI_CDTBUF_TRTYPE);
+ u32 cdtbuf0_mask, cdtbuf0_val;
/* nbytes can be up to 8 bytes */
nbytes = bytes_left >= max ? max : bytes_left;
- regmap_update_bits(xspi->regmap, XSPI_CDTBUF0,
- XSPI_CDTBUF_DATASIZE(0xf),
- XSPI_CDTBUF_DATASIZE(nbytes));
+ /* clear TRTYPE */
+ cdtbuf0_mask = XSPI_CDTBUF_TRTYPE;
+ cdtbuf0_val = 0;
- regmap_update_bits(xspi->regmap, XSPI_CDTBUF0,
- XSPI_CDTBUF_ADDSIZE(0x7),
- XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes));
+ /* program DATASIZE */
+ cdtbuf0_mask |= XSPI_CDTBUF_DATASIZE(0xf);
+ cdtbuf0_val |= XSPI_CDTBUF_DATASIZE(nbytes);
+
+ /* program ADDSIZE */
+ cdtbuf0_mask |= XSPI_CDTBUF_ADDSIZE(0x7);
+ cdtbuf0_val |= XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes);
+
+ /* program LATE */
+ cdtbuf0_mask |= XSPI_CDTBUF_LATE(0x1f);
+ cdtbuf0_val |= XSPI_CDTBUF_LATE(xspi->dummy);
+
+ regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, cdtbuf0_mask, cdtbuf0_val);
if (xspi->addr_nbytes)
regmap_write(xspi->regmap, XSPI_CDABUF0,
xspi->smadr + pos);
- regmap_update_bits(xspi->regmap, XSPI_CDTBUF0,
- XSPI_CDTBUF_LATE(0x1f),
- XSPI_CDTBUF_LATE(xspi->dummy));
-
regmap_update_bits(xspi->regmap, XSPI_CDCTL0,
XSPI_CDCTL0_TRREQ, XSPI_CDCTL0_TRREQ);
@@ -773,7 +776,7 @@ int rpcif_manual_xfer(struct device *dev)
ret = rpc->info->impl->manual_xfer(rpc);
- pm_runtime_put(dev);
+ pm_runtime_put_autosuspend(dev);
return ret;
}
@@ -868,15 +871,6 @@ static size_t xspi_dirmap_read_impl(struct rpcif_priv *xspi, u64 offs,
XSPI_CMCFG1_RDCMD_UPPER_BYTE(xspi->command) |
XSPI_CMCFG1_RDLATE(xspi->dummy));
- regmap_update_bits(xspi->regmap, XSPI_BMCTL0, XSPI_BMCTL0_CS0ACC(0xff),
- XSPI_BMCTL0_CS0ACC(0x01));
-
- regmap_update_bits(xspi->regmap, XSPI_BMCFG,
- XSPI_BMCFG_WRMD | XSPI_BMCFG_MWRCOMB |
- XSPI_BMCFG_MWRSIZE(0xff) | XSPI_BMCFG_PREEN,
- 0 | XSPI_BMCFG_MWRCOMB | XSPI_BMCFG_MWRSIZE(0x0f) |
- XSPI_BMCFG_PREEN);
-
regmap_update_bits(xspi->regmap, XSPI_LIOCFGCS0, XSPI_LIOCFG_PRTMD(0x3ff),
XSPI_LIOCFG_PRTMD(xspi->proto));
@@ -897,7 +891,7 @@ ssize_t rpcif_dirmap_read(struct device *dev, u64 offs, size_t len, void *buf)
read = rpc->info->impl->dirmap_read(rpc, offs, len, buf);
- pm_runtime_put(dev);
+ pm_runtime_put_autosuspend(dev);
return read;
}
@@ -944,15 +938,6 @@ ssize_t xspi_dirmap_write(struct device *dev, u64 offs, size_t len, const void *
XSPI_CMCFG2_WRCMD_UPPER(xspi->command) |
XSPI_CMCFG2_WRLATE(xspi->dummy));
- regmap_update_bits(xspi->regmap, XSPI_BMCTL0,
- XSPI_BMCTL0_CS0ACC(0xff), XSPI_BMCTL0_CS0ACC(0x03));
-
- regmap_update_bits(xspi->regmap, XSPI_BMCFG,
- XSPI_BMCFG_WRMD | XSPI_BMCFG_MWRCOMB |
- XSPI_BMCFG_MWRSIZE(0xff) | XSPI_BMCFG_PREEN,
- 0 | XSPI_BMCFG_MWRCOMB | XSPI_BMCFG_MWRSIZE(0x0f) |
- XSPI_BMCFG_PREEN);
-
regmap_update_bits(xspi->regmap, XSPI_LIOCFGCS0, XSPI_LIOCFG_PRTMD(0x3ff),
XSPI_LIOCFG_PRTMD(xspi->proto));
@@ -963,7 +948,7 @@ ssize_t xspi_dirmap_write(struct device *dev, u64 offs, size_t len, const void *
regmap_update_bits(xspi->regmap, XSPI_BMCTL1,
XSPI_BMCTL1_MWRPUSH, XSPI_BMCTL1_MWRPUSH);
- pm_runtime_put(dev);
+ pm_runtime_put_autosuspend(dev);
return writebytes;
}
diff --git a/drivers/memory/samsung/exynos5422-dmc.c b/drivers/memory/samsung/exynos5422-dmc.c
index 788d49c688b1..98c319552583 100644
--- a/drivers/memory/samsung/exynos5422-dmc.c
+++ b/drivers/memory/samsung/exynos5422-dmc.c
@@ -1297,8 +1297,15 @@ static int exynos5_dmc_init_clks(struct exynos5_dmc *dmc)
if (ret)
return ret;
- clk_prepare_enable(dmc->fout_bpll);
- clk_prepare_enable(dmc->mout_bpll);
+ ret = clk_prepare_enable(dmc->fout_bpll);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(dmc->mout_bpll);
+ if (ret) {
+ clk_disable_unprepare(dmc->fout_bpll);
+ return ret;
+ }
/*
* Some bootloaders do not set clock routes correctly.
diff --git a/drivers/memory/stm32_omm.c b/drivers/memory/stm32_omm.c
index 84eb23c824f5..3599683ab04a 100644
--- a/drivers/memory/stm32_omm.c
+++ b/drivers/memory/stm32_omm.c
@@ -274,6 +274,8 @@ static int stm32_omm_configure(struct device *dev)
writel_relaxed(omm->cr, omm->io_base + OMM_CR);
ret = stm32_omm_set_amcr(dev, true);
+ if (ret && (mux & CR_MUXEN))
+ stm32_omm_toggle_child_clock(dev, false);
error:
pm_runtime_put_sync_suspend(dev);
diff --git a/drivers/memory/tegra/tegra264.c b/drivers/memory/tegra/tegra264.c
index 790349295dcc..57e6395861ba 100644
--- a/drivers/memory/tegra/tegra264.c
+++ b/drivers/memory/tegra/tegra264.c
@@ -16,6 +16,47 @@
#include "tegra264-bwmgr.h"
/*
+ * Description of a single MCF error type: where to read the status and the
+ * faulting address, how to extract the high address bits, which bits encode
+ * the access direction and security state and the optional error-type sub-code.
+ */
+struct tegra264_mc_fault {
+ const char *const *type_names;
+ u32 addr_hi_mask;
+ u32 addr_hi_reg;
+ u32 addr_hi_shift;
+ u32 addr_reg;
+ u32 rw_bit;
+ u32 sec_bit;
+ u32 status1_reg;
+ u32 status_reg;
+ u32 type_mask;
+ u32 type_shift;
+};
+
+/*
+ * Maps an MCF interrupt to a callback that fills in the register offsets and
+ * decoding parameters for that error type. The register offsets live in the
+ * per-SoC tegra_mc_regs, so they are collected at runtime rather than being
+ * stored in a static table.
+ */
+struct tegra264_mc_error_handler {
+ u32 mask;
+ void (*get_offsets)(struct tegra_mc *mc, struct tegra264_mc_fault *fault);
+};
+
+/*
+ * Description of a single HUB error type. addr_reg is zero for error types
+ * that don't latch a fault address.
+ */
+struct tegra264_hub_error_handler {
+ u32 addr_hi_reg;
+ u32 addr_reg;
+ u32 mask;
+ u32 status_reg;
+};
+
+/*
* MC Client entries are sorted in the increasing order of the
* override and security register offsets.
*/
@@ -717,11 +758,18 @@ static const char *const tegra264_rt_error_names[16] = {
};
/*
- * MC instance aperture mapping for hubc registers
+ * On Tegra264 the memory controller error interrupts are distributed across
+ * several HUB/HUBC apertures. Each aperture is accessed like a broadcast
+ * channel through mc_ch_readl()/mc_ch_writel() using its fixed index.
*/
-static const int mc_hubc_aperture_number[5] = {
- 7, 8, 9, 10, 11
-};
+#define TEGRA264_MC_APERTURE_DISP 7
+#define TEGRA264_MC_APERTURE_SYSTEM 8
+#define TEGRA264_MC_APERTURE_VISION 9
+#define TEGRA264_MC_APERTURE_UPHY 10
+#define TEGRA264_MC_APERTURE_TOP 11
+
+/* Tegra264 splits the MCF common interrupt status across five slices. */
+#define TEGRA264_MC_NUM_SLICES 5
/*
* tegra264_mc_icc_set() - Pass MC client info to the BPMP-FW
@@ -807,115 +855,149 @@ static int tegra264_mc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *pea
return 0;
}
-static void mcf_log_fault(struct tegra_mc *mc, u32 channel, unsigned long mcf_ch_intstatus)
+static void tegra264_mc_fault_emem(struct tegra_mc *mc, struct tegra264_mc_fault *fault)
{
- unsigned int bit;
+ fault->status_reg = mc->soc->regs->err_status;
+ fault->addr_reg = mc->soc->regs->err_add;
+ fault->addr_hi_reg = mc->soc->regs->err_add_hi;
+ fault->type_mask = mc->soc->mc_err_status_type_mask;
+ fault->type_shift = MC_ERR_STATUS_TYPE_SHIFT;
+ fault->type_names = tegra264_mc_error_names;
+}
- for_each_set_bit(bit, &mcf_ch_intstatus, 32) {
- const char *client = "unknown", *desc = "NA";
- u32 status_reg, status1_reg = 0, addr_reg, addr_hi_reg = 0, err_type_mask = 0;
- u32 value, client_id, i, addr_hi_shift = 0, addr_hi_mask = 0, status1;
- u32 mc_rw_bit = MC_ERR_STATUS_RW, mc_sec_bit = MC_ERR_STATUS_SECURITY;
- phys_addr_t addr = 0;
- u8 type;
-
- switch (BIT(bit)) {
- case MC_INT_DECERR_EMEM:
- case MC_INT_SECURITY_VIOLATION:
- status_reg = mc->soc->regs->err_status;
- addr_reg = mc->soc->regs->err_add;
- addr_hi_reg = mc->soc->regs->err_add_hi;
- err_type_mask = mc->soc->mc_err_status_type_mask;
- break;
+static void tegra264_mc_fault_vpr(struct tegra_mc *mc, struct tegra264_mc_fault *fault)
+{
+ fault->status_reg = mc->soc->regs->err_vpr_status;
+ fault->addr_reg = mc->soc->regs->err_vpr_add;
+ fault->addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT;
+ fault->addr_hi_mask = mc->soc->mc_addr_hi_mask;
+}
- case MC_INT_DECERR_VPR:
- status_reg = mc->soc->regs->err_vpr_status;
- addr_reg = mc->soc->regs->err_vpr_add;
- addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT;
- addr_hi_mask = mc->soc->mc_addr_hi_mask;
- break;
+static void tegra264_mc_fault_sec(struct tegra_mc *mc, struct tegra264_mc_fault *fault)
+{
+ fault->status_reg = mc->soc->regs->err_sec_status;
+ fault->addr_reg = mc->soc->regs->err_sec_add;
+ fault->addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT;
+ fault->addr_hi_mask = mc->soc->mc_addr_hi_mask;
+}
- case MC_INT_SECERR_SEC:
- status_reg = mc->soc->regs->err_sec_status;
- addr_reg = mc->soc->regs->err_sec_add;
- addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT;
- addr_hi_mask = mc->soc->mc_addr_hi_mask;
- break;
+static void tegra264_mc_fault_mts(struct tegra_mc *mc, struct tegra264_mc_fault *fault)
+{
+ fault->status_reg = mc->soc->regs->err_mts_status;
+ fault->addr_reg = mc->soc->regs->err_mts_add;
+ fault->addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT;
+ fault->addr_hi_mask = mc->soc->mc_addr_hi_mask;
+}
- case MC_INT_DECERR_MTS:
- status_reg = mc->soc->regs->err_mts_status;
- addr_reg = mc->soc->regs->err_mts_add;
- addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT;
- addr_hi_mask = mc->soc->mc_addr_hi_mask;
- break;
+static void tegra264_mc_fault_gsc(struct tegra_mc *mc, struct tegra264_mc_fault *fault)
+{
+ fault->status_reg = mc->soc->regs->err_gen_co_status;
+ fault->status1_reg = MC_ERR_GENERALIZED_CARVEOUT_STATUS_1_0;
+ fault->addr_reg = mc->soc->regs->err_gen_co_add;
+ fault->addr_hi_shift = MC_ERR_STATUS_GSC_ADR_HI_SHIFT;
+ fault->addr_hi_mask = MC_ERR_STATUS_GSC_ADR_HI_MASK;
+}
- case MC_INT_DECERR_GENERALIZED_CARVEOUT:
- status_reg = mc->soc->regs->err_gen_co_status;
- status1_reg = MC_ERR_GENERALIZED_CARVEOUT_STATUS_1_0;
- addr_reg = mc->soc->regs->err_gen_co_add;
- addr_hi_shift = MC_ERR_STATUS_GSC_ADR_HI_SHIFT;
- addr_hi_mask = MC_ERR_STATUS_GSC_ADR_HI_MASK;
- break;
+static void tegra264_mc_fault_route(struct tegra_mc *mc, struct tegra264_mc_fault *fault)
+{
+ fault->status_reg = mc->soc->regs->err_route_status;
+ fault->addr_reg = mc->soc->regs->err_route_add;
+ fault->addr_hi_shift = MC_ERR_STATUS_RT_ADR_HI_SHIFT;
+ fault->addr_hi_mask = mc->soc->mc_addr_hi_mask;
+ fault->rw_bit = MC_ERR_ROUTE_SANITY_RW;
+ fault->sec_bit = MC_ERR_ROUTE_SANITY_SEC;
+ fault->type_mask = MC_ERR_STATUS_RT_TYPE_MASK;
+ fault->type_shift = MC_ERR_STATUS_RT_TYPE_SHIFT;
+ fault->type_names = tegra264_rt_error_names;
+}
- case MC_INT_DECERR_ROUTE_SANITY:
- case MC_INT_DECERR_ROUTE_SANITY_GIC_MSI:
- status_reg = mc->soc->regs->err_route_status;
- addr_reg = mc->soc->regs->err_route_add;
- addr_hi_shift = MC_ERR_STATUS_RT_ADR_HI_SHIFT;
- addr_hi_mask = mc->soc->mc_addr_hi_mask;
- mc_sec_bit = MC_ERR_ROUTE_SANITY_SEC;
- mc_rw_bit = MC_ERR_ROUTE_SANITY_RW;
- err_type_mask = MC_ERR_STATUS_RT_TYPE_MASK;
- break;
+static const struct tegra264_mc_error_handler tegra264_mc_error_handlers[] = {
+ { MC_INT_DECERR_EMEM, tegra264_mc_fault_emem },
+ { MC_INT_SECURITY_VIOLATION, tegra264_mc_fault_emem },
+ { MC_INT_DECERR_VPR, tegra264_mc_fault_vpr },
+ { MC_INT_SECERR_SEC, tegra264_mc_fault_sec },
+ { MC_INT_DECERR_MTS, tegra264_mc_fault_mts },
+ { MC_INT_DECERR_GENERALIZED_CARVEOUT, tegra264_mc_fault_gsc },
+ { MC_INT_DECERR_ROUTE_SANITY, tegra264_mc_fault_route },
+ { MC_INT_DECERR_ROUTE_SANITY_GIC_MSI, tegra264_mc_fault_route },
+};
- default:
- dev_err_ratelimited(mc->dev, "Incorrect MC interrupt mask\n");
- return;
- }
+static void tegra264_mc_report_fault(struct tegra_mc *mc, u32 channel,
+ unsigned int interrupt,
+ const struct tegra264_mc_fault *fault)
+{
+ const char *client = "unknown", *desc = "NA";
+ u32 value, client_id, status1 = 0;
+ phys_addr_t addr = 0;
+ unsigned int i;
+ u8 type;
+
+ value = mc_ch_readl(mc, channel, fault->status_reg);
+
+ if (fault->addr_hi_reg) {
+ addr = mc_ch_readl(mc, channel, fault->addr_hi_reg);
+ } else if (fault->status1_reg) {
+ status1 = mc_ch_readl(mc, channel, fault->status1_reg);
+ addr = (status1 >> fault->addr_hi_shift) & fault->addr_hi_mask;
+ } else {
+ addr = (value >> fault->addr_hi_shift) & fault->addr_hi_mask;
+ }
- value = mc_ch_readl(mc, channel, status_reg);
- if (addr_hi_reg) {
- addr = mc_ch_readl(mc, channel, addr_hi_reg);
- } else {
- if (!status1_reg) {
- addr = ((value >> addr_hi_shift) & addr_hi_mask);
- } else {
- status1 = mc_ch_readl(mc, channel, status1_reg);
- addr = ((status1 >> addr_hi_shift) & addr_hi_mask);
- }
+ addr <<= 32;
+ addr |= mc_ch_readl(mc, channel, fault->addr_reg);
+
+ client_id = value & mc->soc->client_id_mask;
+ for (i = 0; i < mc->soc->num_clients; i++) {
+ if (mc->soc->clients[i].id == client_id) {
+ client = mc->soc->clients[i].name;
+ break;
}
+ }
- addr <<= 32;
- addr |= mc_ch_readl(mc, channel, addr_reg);
+ if (fault->type_names) {
+ type = (value & fault->type_mask) >> fault->type_shift;
+ desc = fault->type_names[type];
+ }
- client_id = value & mc->soc->client_id_mask;
- for (i = 0; i < mc->soc->num_clients; i++) {
- if (mc->soc->clients[i].id == client_id) {
- client = mc->soc->clients[i].name;
+ dev_err_ratelimited(mc->dev, "%s: %s %s @%pa: %s (%s)\n",
+ client, value & fault->sec_bit ? "secure" : "non-secure",
+ value & fault->rw_bit ? "write" : "read", &addr,
+ tegra_mc_status_names[interrupt] ?: "unknown", desc);
+
+ if (fault->status1_reg)
+ dev_err_ratelimited(mc->dev, "gsc_apr_id=%u gsc_co_apr_id=%u\n",
+ (status1 >> ERR_GENERALIZED_APERTURE_ID_SHIFT) &
+ ERR_GENERALIZED_APERTURE_ID_MASK,
+ (status1 >> ERR_GENERALIZED_CARVEOUT_APERTURE_ID_SHIFT) &
+ ERR_GENERALIZED_CARVEOUT_APERTURE_ID_MASK);
+}
+
+static void mcf_log_fault(struct tegra_mc *mc, u32 channel, unsigned long mcf_ch_intstatus)
+{
+ unsigned int interrupt;
+
+ for_each_set_bit(interrupt, &mcf_ch_intstatus, 32) {
+ const struct tegra264_mc_error_handler *handler = NULL;
+ struct tegra264_mc_fault fault = {
+ .rw_bit = MC_ERR_STATUS_RW,
+ .sec_bit = MC_ERR_STATUS_SECURITY,
+ };
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(tegra264_mc_error_handlers); i++) {
+ if (tegra264_mc_error_handlers[i].mask == BIT(interrupt)) {
+ handler = &tegra264_mc_error_handlers[i];
break;
}
}
- if (err_type_mask == MC_ERR_STATUS_RT_TYPE_MASK) {
- type = (value & err_type_mask) >>
- MC_ERR_STATUS_RT_TYPE_SHIFT;
- desc = tegra264_rt_error_names[type];
- } else if (err_type_mask) {
- type = (value & err_type_mask) >>
- MC_ERR_STATUS_TYPE_SHIFT;
- desc = tegra264_mc_error_names[type];
+ if (!handler) {
+ dev_err_ratelimited(mc->dev, "Incorrect MC interrupt mask\n");
+ return;
}
- dev_err_ratelimited(mc->dev, "%s: %s %s @%pa: %s (%s)\n",
- client, value & mc_sec_bit ? "secure" : "non-secure",
- value & mc_rw_bit ? "write" : "read", &addr,
- tegra_mc_status_names[bit] ?: "unknown", desc);
- if (status1_reg)
- dev_err_ratelimited(mc->dev, "gsc_apr_id=%u gsc_co_apr_id=%u\n",
- ((status1 >> ERR_GENERALIZED_APERTURE_ID_SHIFT)
- & ERR_GENERALIZED_APERTURE_ID_MASK),
- ((status1 >> ERR_GENERALIZED_CARVEOUT_APERTURE_ID_SHIFT)
- & ERR_GENERALIZED_CARVEOUT_APERTURE_ID_MASK));
+ handler->get_offsets(mc, &fault);
+ tegra264_mc_report_fault(mc, channel, interrupt, &fault);
}
/* clear interrupts */
@@ -937,7 +1019,7 @@ static irqreturn_t handle_mcf_irq(int irq, void *data)
for_each_set_bit(slice, &common_intstat, 32) {
/* Find out the slice number on which interrupt occurred */
- if (slice > 4) {
+ if (slice >= TEGRA264_MC_NUM_SLICES) {
dev_err(mc->dev, "Slice index out of bounds: %u\n", slice);
return IRQ_NONE;
}
@@ -950,53 +1032,69 @@ static irqreturn_t handle_mcf_irq(int irq, void *data)
return IRQ_HANDLED;
}
+static const struct tegra264_hub_error_handler tegra264_hub_error_handlers[] = {
+ {
+ .mask = MSS_HUB_COALESCER_ERR_INTMASK,
+ .status_reg = MSS_HUB_COALESCE_ERR_STATUS_0,
+ .addr_reg = MSS_HUB_COALESCE_ERR_ADR_0,
+ .addr_hi_reg = MSS_HUB_COALESCE_ERR_ADR_HI_0,
+ },
+ {
+ .mask = MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK,
+ .status_reg = MSS_HUB_SMMU_BYPASS_ALLOW_ERR_STATUS_0,
+ },
+ {
+ .mask = MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK,
+ .status_reg = MSS_HUB_ILLEGAL_TBUGRP_ID_ERR_STATUS_0,
+ },
+ {
+ .mask = MSS_HUB_MSI_ERR_INTMASK,
+ .status_reg = MSS_HUB_MSI_ERR_STATUS_0,
+ },
+ {
+ .mask = MSS_HUB_POISON_RSP_INTMASK,
+ .status_reg = MSS_HUB_POISON_RSP_STATUS_0,
+ },
+ {
+ .mask = MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK,
+ .status_reg = MSS_HUB_RESTRICTED_ACCESS_ERR_STATUS_0,
+ },
+ {
+ .mask = MSS_HUB_RESERVED_PA_ERR_INTMASK,
+ .status_reg = MSS_HUB_RESERVED_PA_ERR_STATUS_0,
+ },
+};
+
static void hub_log_fault(struct tegra_mc *mc, u32 hub, unsigned long hub_intstat)
{
- unsigned int bit;
+ unsigned int interrupt;
- for_each_set_bit(bit, &hub_intstat, 32) {
+ for_each_set_bit(interrupt, &hub_intstat, 32) {
+ const struct tegra264_hub_error_handler *handler = NULL;
const char *client = "unknown";
- u32 client_id, status_reg, value, i;
+ u32 client_id, value;
phys_addr_t addr = 0;
+ unsigned int i;
- switch (BIT(bit)) {
- case MSS_HUB_COALESCER_ERR_INTMASK:
- status_reg = MSS_HUB_COALESCE_ERR_STATUS_0;
- addr = mc_ch_readl(mc, hub, MSS_HUB_COALESCE_ERR_ADR_HI_0);
- addr <<= 32;
- addr |= mc_ch_readl(mc, hub, MSS_HUB_COALESCE_ERR_ADR_0);
- break;
-
- case MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK:
- status_reg = MSS_HUB_SMMU_BYPASS_ALLOW_ERR_STATUS_0;
- break;
-
- case MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK:
- status_reg = MSS_HUB_ILLEGAL_TBUGRP_ID_ERR_STATUS_0;
- break;
-
- case MSS_HUB_MSI_ERR_INTMASK:
- status_reg = MSS_HUB_MSI_ERR_STATUS_0;
- break;
-
- case MSS_HUB_POISON_RSP_INTMASK:
- status_reg = MSS_HUB_POISON_RSP_STATUS_0;
- break;
-
- case MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK:
- status_reg = MSS_HUB_RESTRICTED_ACCESS_ERR_STATUS_0;
- break;
-
- case MSS_HUB_RESERVED_PA_ERR_INTMASK:
- status_reg = MSS_HUB_RESERVED_PA_ERR_STATUS_0;
- break;
+ for (i = 0; i < ARRAY_SIZE(tegra264_hub_error_handlers); i++) {
+ if (tegra264_hub_error_handlers[i].mask == BIT(interrupt)) {
+ handler = &tegra264_hub_error_handlers[i];
+ break;
+ }
+ }
- default:
+ if (!handler) {
dev_err_ratelimited(mc->dev, "Incorrect HUB interrupt mask\n");
return;
}
- value = mc_ch_readl(mc, hub, status_reg);
+ if (handler->addr_reg) {
+ addr = mc_ch_readl(mc, hub, handler->addr_hi_reg);
+ addr <<= 32;
+ addr |= mc_ch_readl(mc, hub, handler->addr_reg);
+ }
+
+ value = mc_ch_readl(mc, hub, handler->status_reg);
client_id = value & mc->soc->client_id_mask;
for (i = 0; i < mc->soc->num_clients; i++) {
@@ -1007,8 +1105,8 @@ static void hub_log_fault(struct tegra_mc *mc, u32 hub, unsigned long hub_intsta
}
dev_err_ratelimited(mc->dev, "%s: @%pa: %s status: 0x%x\n",
- client, &addr, tegra264_hub_error_names[bit] ?: "unknown",
- value);
+ client, &addr,
+ tegra264_hub_error_names[interrupt] ?: "unknown", value);
}
/* clear interrupts */
@@ -1057,27 +1155,27 @@ static irqreturn_t handle_hub_irq(int irq, void *data, int mc_hubc_aperture_numb
static irqreturn_t handle_disp_hub_irq(int irq, void *data)
{
- return handle_hub_irq(irq, data, mc_hubc_aperture_number[0]);
+ return handle_hub_irq(irq, data, TEGRA264_MC_APERTURE_DISP);
}
static irqreturn_t handle_system_hub_irq(int irq, void *data)
{
- return handle_hub_irq(irq, data, mc_hubc_aperture_number[1]);
+ return handle_hub_irq(irq, data, TEGRA264_MC_APERTURE_SYSTEM);
}
static irqreturn_t handle_vision_hub_irq(int irq, void *data)
{
- return handle_hub_irq(irq, data, mc_hubc_aperture_number[2]);
+ return handle_hub_irq(irq, data, TEGRA264_MC_APERTURE_VISION);
}
static irqreturn_t handle_uphy_hub_irq(int irq, void *data)
{
- return handle_hub_irq(irq, data, mc_hubc_aperture_number[3]);
+ return handle_hub_irq(irq, data, TEGRA264_MC_APERTURE_UPHY);
}
static irqreturn_t handle_top_hub_irq(int irq, void *data)
{
- return handle_hub_irq(irq, data, mc_hubc_aperture_number[4]);
+ return handle_hub_irq(irq, data, TEGRA264_MC_APERTURE_TOP);
}
static irqreturn_t handle_generic_irq(struct tegra_mc *mc, unsigned long intstat_reg)
diff --git a/drivers/platform/cznic/turris-omnia-mcu-base.c b/drivers/platform/cznic/turris-omnia-mcu-base.c
index e8fc0d7b3343..f0416302a1f3 100644
--- a/drivers/platform/cznic/turris-omnia-mcu-base.c
+++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
@@ -403,6 +403,7 @@ static const struct of_device_id of_omnia_mcu_match[] = {
{ .compatible = "cznic,turris-omnia-mcu" },
{}
};
+MODULE_DEVICE_TABLE(of, of_omnia_mcu_match);
static struct i2c_driver omnia_mcu_driver = {
.probe = omnia_mcu_probe,
diff --git a/drivers/platform/cznic/turris-omnia-mcu-gpio.c b/drivers/platform/cznic/turris-omnia-mcu-gpio.c
index 4e430d6c3fc4..8f43bfa92373 100644
--- a/drivers/platform/cznic/turris-omnia-mcu-gpio.c
+++ b/drivers/platform/cznic/turris-omnia-mcu-gpio.c
@@ -11,7 +11,6 @@
#include <linux/bug.h>
#include <linux/cleanup.h>
#include <linux/device.h>
-#include <linux/devm-helpers.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
@@ -841,6 +840,18 @@ static void button_release_emul_fn(struct work_struct *work)
generic_handle_irq_safe(mcu->client->irq);
}
+static void omnia_disable_button_release_work(void *data)
+{
+ struct delayed_work *work = data;
+
+ /*
+ * The IRQ thread may requeue this work while the IRQ remains active.
+ * Disable and drain it before releasing the IRQ action and the MCU
+ * state used by the worker.
+ */
+ disable_delayed_work_sync(work);
+}
+
static void
fill_int_from_sts(unsigned long *rising, unsigned long *falling,
unsigned long rising_sts, unsigned long falling_sts,
@@ -1082,21 +1093,9 @@ int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu)
return dev_err_probe(dev, err, "Cannot request IRQ\n");
if (!new_api) {
- /*
- * The button_release_emul_work has to be initialized before the
- * thread is requested, and on driver remove it needs to be
- * canceled before the thread is freed. Therefore we can't use
- * devm_delayed_work_autocancel() directly, because the order
- * devm_delayed_work_autocancel();
- * devm_request_threaded_irq();
- * would cause improper release order:
- * free_irq();
- * cancel_delayed_work_sync();
- * Instead we first initialize the work above, and only now
- * after IRQ is requested we add the work devm action.
- */
- err = devm_add_action(dev, devm_delayed_work_drop,
- &mcu->button_release_emul_work);
+ err = devm_add_action_or_reset(dev,
+ omnia_disable_button_release_work,
+ &mcu->button_release_emul_work);
if (err)
return err;
}
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index dfe5cec59262..483cbdcae153 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -25,6 +25,7 @@ source "drivers/soc/rockchip/Kconfig"
source "drivers/soc/samsung/Kconfig"
source "drivers/soc/sophgo/Kconfig"
source "drivers/soc/st/Kconfig"
+source "drivers/soc/starfive/Kconfig"
source "drivers/soc/sunxi/Kconfig"
source "drivers/soc/tegra/Kconfig"
source "drivers/soc/ti/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 894bd6ebaaa4..5a3efd68355c 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -31,6 +31,7 @@ obj-y += rockchip/
obj-$(CONFIG_SOC_SAMSUNG) += samsung/
obj-y += sophgo/
obj-y += st/
+obj-y += starfive/
obj-y += sunxi/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-y += ti/
diff --git a/drivers/soc/amlogic/meson-clk-measure.c b/drivers/soc/amlogic/meson-clk-measure.c
index 8a1a9fed0e74..33767f0bc67c 100644
--- a/drivers/soc/amlogic/meson-clk-measure.c
+++ b/drivers/soc/amlogic/meson-clk-measure.c
@@ -20,7 +20,7 @@ static DEFINE_MUTEX(measure_lock);
#define MSR_CONT BIT(17) /* continuous measurement */
#define MSR_INTR BIT(18) /* interrupts */
#define MSR_RUN BIT(19)
-#define MSR_CLK_SRC GENMASK(26, 20)
+#define MSR_CLK_SRC GENMASK(27, 20)
#define MSR_BUSY BIT(31)
#define MSR_VAL_MASK GENMASK(15, 0)
@@ -55,7 +55,7 @@ struct meson_msr {
};
#define CLK_MSR_ID(__id, __name) \
- [__id] = {.id = __id, .name = __name,}
+ {.id = __id, .name = __name,}
static const struct meson_msr_id clk_msr_m8[] = {
CLK_MSR_ID(0, "ring_osc_out_ee0"),
@@ -1041,6 +1041,843 @@ static const struct meson_msr_id clk_msr_t7[] = {
CLK_MSR_ID(222, "enc0")
};
+static const struct meson_msr_id clk_msr_a4[] = {
+ CLK_MSR_ID(0, "sys_clk"),
+ CLK_MSR_ID(1, "axi_clk"),
+ CLK_MSR_ID(2, "rtc_clk"),
+ CLK_MSR_ID(3, "p22_usb2_ckout"),
+ CLK_MSR_ID(4, "p21_usb2_ckout"),
+ CLK_MSR_ID(5, "p20_usb2_ckout"),
+ CLK_MSR_ID(6, "cpu_clk_div16"),
+ CLK_MSR_ID(8, "eth_mpll_test"),
+ CLK_MSR_ID(10, "fclk_div5"),
+ CLK_MSR_ID(15, "fclk_50m"),
+ CLK_MSR_ID(16, "sys_oscin32k_i"),
+ CLK_MSR_ID(17, "rtc_pll"),
+ CLK_MSR_ID(19, "hifi_pll"),
+ CLK_MSR_ID(20, "gp0_pll"),
+ CLK_MSR_ID(21, "gp1_pll"),
+ CLK_MSR_ID(22, "eth_mppll_50m_ckout"),
+ CLK_MSR_ID(23, "sys_pll_div16"),
+ CLK_MSR_ID(24, "ddr_dpll_pt_clk"),
+ CLK_MSR_ID(27, "rtc_sec_pulse_out"),
+ CLK_MSR_ID(28, "rtc_osc_clk_out"),
+ CLK_MSR_ID(30, "mod_eth_phy_ref_clk"),
+ CLK_MSR_ID(31, "mod_eth_tx_clk"),
+ CLK_MSR_ID(32, "eth_125m"),
+ CLK_MSR_ID(33, "eth_rmii"),
+ CLK_MSR_ID(34, "co_clkin_to_mac"),
+ CLK_MSR_ID(35, "mod_eth_rx_clk_rmii"),
+ CLK_MSR_ID(36, "co_rx_clk"),
+ CLK_MSR_ID(37, "co_tx_clk"),
+ CLK_MSR_ID(38, "eth_phy_rxclk"),
+ CLK_MSR_ID(39, "eth_phy_plltxclk"),
+ CLK_MSR_ID(40, "ephy_test_clk"),
+ CLK_MSR_ID(41, "audio_core"),
+ CLK_MSR_ID(51, "cts_vout_venc_clk_ph"),
+ CLK_MSR_ID(52, "cts_vout_venc_clk"),
+ CLK_MSR_ID(106, "deskew_pll_test_clk"),
+ CLK_MSR_ID(111, "sar_adc"),
+ CLK_MSR_ID(112, "ts"),
+ CLK_MSR_ID(113, "sd_emmc_c"),
+ CLK_MSR_ID(115, "sd_emmc_a"),
+ CLK_MSR_ID(116, "gpio_msr_clk"),
+ CLK_MSR_ID(117, "spicc1"),
+ CLK_MSR_ID(118, "spicc0"),
+ CLK_MSR_ID(119, "o_mst_sclk_vad"),
+ CLK_MSR_ID(120, "o_mst_mclk_vad"),
+ CLK_MSR_ID(121, "o_pdm_sysclk"),
+ CLK_MSR_ID(122, "mod_audio_pdm_dclk_o"),
+ CLK_MSR_ID(123, "o_vad_clk"),
+ CLK_MSR_ID(124, "earcrx_dmac_clk"),
+ CLK_MSR_ID(125, "earcrx_cmdc_clk"),
+ CLK_MSR_ID(126, "earctx_dmac_clk"),
+ CLK_MSR_ID(127, "earctx_cmdc_clk"),
+ CLK_MSR_ID(128, "tohdmitx_bclk"),
+ CLK_MSR_ID(129, "tohdmitx_mclk"),
+ CLK_MSR_ID(130, "tohdmitx_spdif_clk"),
+ CLK_MSR_ID(131, "toacodec_bclk"),
+ CLK_MSR_ID(132, "toacodec_mclk"),
+ CLK_MSR_ID(133, "spdifout_b_mst_clk"),
+ CLK_MSR_ID(134, "spdifout_mst_clk"),
+ CLK_MSR_ID(135, "spdifin_mst_clk"),
+ CLK_MSR_ID(136, "audio_mclk"),
+ CLK_MSR_ID(137, "vad_clk"),
+ CLK_MSR_ID(138, "tdmout_d_sclk"),
+ CLK_MSR_ID(139, "tdmout_c_sclk"),
+ CLK_MSR_ID(140, "tdmout_b_sclk"),
+ CLK_MSR_ID(141, "tdmout_a_sclk"),
+ CLK_MSR_ID(142, "tdminb_lb_sclk"),
+ CLK_MSR_ID(143, "tdmin_lb_sclk"),
+ CLK_MSR_ID(144, "tdmin_d_sclk"),
+ CLK_MSR_ID(145, "tdmin_c_sclk"),
+ CLK_MSR_ID(146, "tdmin_b_sclk"),
+ CLK_MSR_ID(147, "tdmin_a_sclk"),
+ CLK_MSR_ID(148, "resampleb_clk"),
+ CLK_MSR_ID(149, "resamplea_clk"),
+ CLK_MSR_ID(150, "pdmb_sysclk"),
+ CLK_MSR_ID(151, "pdmb_dclk"),
+ CLK_MSR_ID(152, "pdm_sysclk"),
+ CLK_MSR_ID(153, "pdm_dclk"),
+ CLK_MSR_ID(154, "alockerb_out_clk"),
+ CLK_MSR_ID(155, "alockerb_in_clk"),
+ CLK_MSR_ID(156, "alocker_out_clk"),
+ CLK_MSR_ID(157, "alocker_in_clk"),
+ CLK_MSR_ID(158, "audio_mst_clk[34]"),
+ CLK_MSR_ID(159, "audio_mst_clk[35]"),
+ CLK_MSR_ID(162, "pwm_h"),
+ CLK_MSR_ID(163, "pwm_g"),
+ CLK_MSR_ID(164, "pwm_f"),
+ CLK_MSR_ID(165, "pwm_e"),
+ CLK_MSR_ID(166, "pwm_d"),
+ CLK_MSR_ID(167, "pwm_c"),
+ CLK_MSR_ID(168, "pwm_b"),
+ CLK_MSR_ID(169, "pwm_a"),
+ CLK_MSR_ID(170, "AU_ADC_CLK_G128X"),
+ CLK_MSR_ID(171, "AU_ADC_CLK_TO_GPIO"),
+ CLK_MSR_ID(172, "AU_DAC1_CLK_G128X"),
+ CLK_MSR_ID(173, "AU_DAC1_CLK_TO_GPIO"),
+ CLK_MSR_ID(176, "rng_ring_osc_clk[0]"),
+ CLK_MSR_ID(177, "rng_ring_osc_clk[1]"),
+ CLK_MSR_ID(178, "rng_ring_osc_clk[2]"),
+ CLK_MSR_ID(179, "rng_ring_osc_clk[3]"),
+ CLK_MSR_ID(180, "sys_cpu_osc_ring[0](ULVT16)"),
+ CLK_MSR_ID(181, "sys_cpu_osc_ring[1](ULVT20)"),
+ CLK_MSR_ID(182, "sys_cpu_osc_ring[2](ULVT16)"),
+ CLK_MSR_ID(183, "sys_cpu_osc_ring[3](ULVT16)"),
+ CLK_MSR_ID(184, "sys_cpu_osc_ring[4](ULVT16)"),
+ CLK_MSR_ID(185, "am_ring_osc_clk_out_top[0](SVT16)"),
+ CLK_MSR_ID(186, "am_ring_osc_clk_out_top[1](LVT20)"),
+};
+
+static const struct meson_msr_id clk_msr_a5[] = {
+ CLK_MSR_ID(0, "sys_clk"),
+ CLK_MSR_ID(1, "axi_clk"),
+ CLK_MSR_ID(2, "rtc_clk"),
+ CLK_MSR_ID(3, "dspa"),
+ CLK_MSR_ID(6, "cpu_clk_div16"),
+ CLK_MSR_ID(10, "fclk_div5"),
+ CLK_MSR_ID(11, "mpll0"),
+ CLK_MSR_ID(12, "mpll1"),
+ CLK_MSR_ID(13, "mpll2"),
+ CLK_MSR_ID(14, "mpll3"),
+ CLK_MSR_ID(15, "fclk_50m"),
+ CLK_MSR_ID(16, "sys_oscin32k_i"),
+ CLK_MSR_ID(17, "rtc_pll"),
+ CLK_MSR_ID(18, "mpll_clk_test_out"),
+ CLK_MSR_ID(19, "hifi_pll"),
+ CLK_MSR_ID(20, "gp0_pll"),
+ CLK_MSR_ID(21, "gp1_pll"),
+ CLK_MSR_ID(23, "sys_pll_div16"),
+ CLK_MSR_ID(24, "ddr_dpll_pt_clk"),
+ CLK_MSR_ID(25, "nna_axi"),
+ CLK_MSR_ID(26, "nna_core"),
+ CLK_MSR_ID(27, "rtc_sec_pulse_out"),
+ CLK_MSR_ID(28, "rtc_osc_clk_out"),
+ CLK_MSR_ID(30, "mod_eth_phy_ref_clk"),
+ CLK_MSR_ID(31, "mod_eth_tx_clk"),
+ CLK_MSR_ID(35, "mod_eth_rx_clk_rmii"),
+ CLK_MSR_ID(79, "rama_clk"),
+ CLK_MSR_ID(106, "deskew_pll_clk_div32_out"),
+ CLK_MSR_ID(111, "sar_adc"),
+ CLK_MSR_ID(112, "ts"),
+ CLK_MSR_ID(113, "sd_emmc_c"),
+ CLK_MSR_ID(115, "sd_emmc_a"),
+ CLK_MSR_ID(116, "gpio_msr_clk"),
+ CLK_MSR_ID(117, "spicc1"),
+ CLK_MSR_ID(118, "spicc0"),
+ CLK_MSR_ID(119, "o_mst_sclk_vad"),
+ CLK_MSR_ID(120, "o_mst_mclk_vad"),
+ CLK_MSR_ID(121, "o_pdm_sysclk"),
+ CLK_MSR_ID(122, "mod_audio_pdm_dclk_o"),
+ CLK_MSR_ID(123, "o_vad_clk"),
+ CLK_MSR_ID(124, "earcrx_dmac_clk"),
+ CLK_MSR_ID(125, "earcrx_cmdc_clk"),
+ CLK_MSR_ID(126, "earctx_dmac_clk"),
+ CLK_MSR_ID(127, "earctx_cmdc_clk"),
+ CLK_MSR_ID(128, "tohdmitx_bclk"),
+ CLK_MSR_ID(129, "tohdmitx_mclk"),
+ CLK_MSR_ID(130, "tohdmitx_spdif_clk"),
+ CLK_MSR_ID(131, "toacodec_bclk"),
+ CLK_MSR_ID(132, "toacodec_mclk"),
+ CLK_MSR_ID(133, "spdifout_b_mst_clk"),
+ CLK_MSR_ID(134, "spdifout_mst_clk"),
+ CLK_MSR_ID(135, "spdifin_mst_clk"),
+ CLK_MSR_ID(136, "audio_mclk"),
+ CLK_MSR_ID(137, "vad_clk"),
+ CLK_MSR_ID(138, "tdmout_d_sclk"),
+ CLK_MSR_ID(139, "tdmout_c_sclk"),
+ CLK_MSR_ID(140, "tdmout_b_sclk"),
+ CLK_MSR_ID(141, "tdmout_a_sclk"),
+ CLK_MSR_ID(142, "tdminb_lb_sclk"),
+ CLK_MSR_ID(143, "tdmin_lb_sclk"),
+ CLK_MSR_ID(144, "tdmin_d_sclk"),
+ CLK_MSR_ID(145, "tdmin_c_sclk"),
+ CLK_MSR_ID(146, "tdmin_b_sclk"),
+ CLK_MSR_ID(147, "tdmin_a_sclk"),
+ CLK_MSR_ID(148, "resampleb_clk"),
+ CLK_MSR_ID(149, "resamplea_clk"),
+ CLK_MSR_ID(150, "pdmb_sysclk"),
+ CLK_MSR_ID(151, "pdmb_dclk"),
+ CLK_MSR_ID(152, "pdm_sysclk"),
+ CLK_MSR_ID(153, "pdm_dclk"),
+ CLK_MSR_ID(154, "alockerb_out_clk"),
+ CLK_MSR_ID(155, "alockerb_in_clk"),
+ CLK_MSR_ID(156, "alocker_out_clk"),
+ CLK_MSR_ID(157, "alocker_in_clk"),
+ CLK_MSR_ID(158, "audio_mst_clk[34]"),
+ CLK_MSR_ID(159, "audio_mst_clk[35]"),
+ CLK_MSR_ID(162, "pwm_h"),
+ CLK_MSR_ID(163, "pwm_g"),
+ CLK_MSR_ID(164, "pwm_f"),
+ CLK_MSR_ID(165, "pwm_e"),
+ CLK_MSR_ID(166, "pwm_d"),
+ CLK_MSR_ID(167, "pwm_c"),
+ CLK_MSR_ID(168, "pwm_b"),
+ CLK_MSR_ID(169, "pwm_a"),
+ CLK_MSR_ID(176, "rng_ring_osc_clk[0]"),
+ CLK_MSR_ID(177, "rng_ring_osc_clk[1]"),
+ CLK_MSR_ID(178, "rng_ring_osc_clk[2]"),
+ CLK_MSR_ID(179, "rng_ring_osc_clk[3]"),
+ CLK_MSR_ID(180, "dmc_osc_ring(LVT16)"),
+ CLK_MSR_ID(181, "dsp_osc_ring(SVT16)"),
+ CLK_MSR_ID(182, "axi_srama_osc_ring(SVT16)"),
+ CLK_MSR_ID(183, "nna_osc_ring[0](ULVT20)"),
+ CLK_MSR_ID(184, "nna_osc_ring[1](LVT16)"),
+ CLK_MSR_ID(185, "sys_cpu_osc_ring[0](ULVT16)"),
+ CLK_MSR_ID(186, "sys_cpu_osc_ring[1](ULVT20)"),
+ CLK_MSR_ID(187, "sys_cpu_osc_ring[2](ULVT16)"),
+ CLK_MSR_ID(188, "sys_cpu_osc_ring[3](LVT16)"),
+ CLK_MSR_ID(189, "axi_sramb_osc_ring(SVT16)"),
+};
+
+static const struct meson_msr_id clk_msr_a9[] = {
+ CLK_MSR_ID(0, "sys_clk"),
+ CLK_MSR_ID(1, "axi_clk"),
+ CLK_MSR_ID(2, "rtc_clk"),
+ CLK_MSR_ID(3, "dspa"),
+ CLK_MSR_ID(4, "mali_stack"),
+ CLK_MSR_ID(5, "mali"),
+ CLK_MSR_ID(6, "cpu_clk_div16"),
+ CLK_MSR_ID(7, "a78_clk_div16"),
+ CLK_MSR_ID(8, "dsu_clk_div16"),
+ CLK_MSR_ID(9, "isp"),
+ CLK_MSR_ID(10, "gp2_pll"),
+ CLK_MSR_ID(11, "fclk_div5"),
+ CLK_MSR_ID(12, "u2drd_usb2_ckout"),
+ CLK_MSR_ID(13, "pre0_hdmirx_aud_pll_clk"),
+ CLK_MSR_ID(14, "hrx20_pll_clk_test"),
+ CLK_MSR_ID(15, "u2h_usb2_ckout"),
+ CLK_MSR_ID(16, "fclk_50m"),
+ CLK_MSR_ID(17, "u3drd_b_usb2_ckout"),
+ CLK_MSR_ID(18, "gp1_pll"),
+ CLK_MSR_ID(19, "hifi_pll"),
+ CLK_MSR_ID(20, "gp0_pll"),
+ CLK_MSR_ID(21, "hifi1_pll"),
+ CLK_MSR_ID(22, "csi_phy"),
+ CLK_MSR_ID(23, "sys_pll_div16"),
+ CLK_MSR_ID(24, "ddr_dpll_pt_clk"),
+ CLK_MSR_ID(25, "mod_Tsin_A_CLK_IN"),
+ CLK_MSR_ID(26, "ext_Tsin_B_CLK_IN"),
+ CLK_MSR_ID(27, "u3p2pll1_0_clk_div16"),
+ CLK_MSR_ID(28, "u3p2pll1_1_clk_div16"),
+ CLK_MSR_ID(29, "upcrx0_cdrclk"),
+ CLK_MSR_ID(30, "upcrx1_cdrclk"),
+ CLK_MSR_ID(31, "hdmirx_aud_sck"),
+ CLK_MSR_ID(32, "uptx0_clk_sync_b20"),
+ CLK_MSR_ID(33, "uptx1_clk_sync_b20"),
+ CLK_MSR_ID(34, "lp_pll_clk0"),
+ CLK_MSR_ID(35, "lp_pll_clk1"),
+ CLK_MSR_ID(36, "u3hsg_PCIE_PIPE_PCLK"),
+ CLK_MSR_ID(37, "u3hsg_upcrx_cdrclk"),
+ CLK_MSR_ID(38, "u3hsg_upctx_clk_sync_b20"),
+ CLK_MSR_ID(39, "u3hsg_upcrxpll_clk_test"),
+ CLK_MSR_ID(40, "hdmirx_acr_lclk"),
+ CLK_MSR_ID(41, "i3c"),
+ CLK_MSR_ID(42, "hdmirx_aud_pll"),
+ CLK_MSR_ID(43, "hdmirx_acr_ref"),
+ CLK_MSR_ID(44, "hdmirx_meter"),
+ CLK_MSR_ID(45, "hdmirx_hdcp2x"),
+ CLK_MSR_ID(46, "hdmirx_5m"),
+ CLK_MSR_ID(47, "hdmirx_2m"),
+ CLK_MSR_ID(48, "hdmirx_cfg"),
+ CLK_MSR_ID(49, "hdmi_vx1_pix_clk"),
+ CLK_MSR_ID(50, "vid_pll"),
+ CLK_MSR_ID(51, "encoder0_if_clk"),
+ CLK_MSR_ID(52, "encoder1"),
+ CLK_MSR_ID(53, "encoder0"),
+ CLK_MSR_ID(54, "vdac"),
+ CLK_MSR_ID(55, "mali_aclkm"),
+ CLK_MSR_ID(56, "vid1_pll"),
+ CLK_MSR_ID(57, "lcd_an_ph2"),
+ CLK_MSR_ID(58, "lcd_an_ph3"),
+ CLK_MSR_ID(59, "hdmitx_pixel"),
+ CLK_MSR_ID(60, "vdin_meas"),
+ CLK_MSR_ID(61, "vpu"),
+ CLK_MSR_ID(62, "vpu_clkb"),
+ CLK_MSR_ID(63, "vpu_clkb_tmp"),
+ CLK_MSR_ID(64, "u3p2_upcrxpll_fst_pll_clk"),
+ CLK_MSR_ID(65, "vid_lock"),
+ CLK_MSR_ID(66, "vapb"),
+ CLK_MSR_ID(67, "ge2d"),
+ CLK_MSR_ID(68, "cve"),
+ CLK_MSR_ID(69, "vge"),
+ CLK_MSR_ID(70, "dsi0_meas"),
+ CLK_MSR_ID(71, "dsi1_meas"),
+ CLK_MSR_ID(72, "mipi_csi_phy_clk_out[0]"),
+ CLK_MSR_ID(73, "mipi_csi_phy_clk_out[1]"),
+ CLK_MSR_ID(74, "mipi_csi_phy_clk_out[2]"),
+ CLK_MSR_ID(75, "mipi_csi_phy_clk_out[3]"),
+ CLK_MSR_ID(76, "hdmitx_tmds"),
+ CLK_MSR_ID(77, "hdmitx_sys"),
+ CLK_MSR_ID(78, "hdmitx_fe"),
+ CLK_MSR_ID(80, "hdmitx_prif"),
+ CLK_MSR_ID(81, "hdmitx_200m"),
+ CLK_MSR_ID(82, "hdmitx_aud"),
+ CLK_MSR_ID(83, "hdmitx1_pixel"),
+ CLK_MSR_ID(84, "hdmitx1_fe"),
+ CLK_MSR_ID(85, "gic"),
+ CLK_MSR_ID(86, "lvds0_fifo_clk"),
+ CLK_MSR_ID(87, "lvds1_fifo_clk"),
+ CLK_MSR_ID(88, "htx_aes_clk"),
+ CLK_MSR_ID(89, "amfc"),
+ CLK_MSR_ID(90, "a_clk_sync_dig"),
+ CLK_MSR_ID(91, "b_clk_sync_dig"),
+ CLK_MSR_ID(92, "u3dp_upcrx_cdrclk"),
+ CLK_MSR_ID(93, "u3dp_upctx_clk_sync_b20"),
+ CLK_MSR_ID(94, "u3dp_upcrxpll_clk_test"),
+ CLK_MSR_ID(95, "u3dp_upcrpll_fst_pll_clk"),
+ CLK_MSR_ID(96, "u3dp_usb2_ckout"),
+ CLK_MSR_ID(97, "hcodec"),
+ CLK_MSR_ID(99, "hevcf"),
+ CLK_MSR_ID(104, "spisg2"),
+ CLK_MSR_ID(105, "spisg1"),
+ CLK_MSR_ID(106, "deskew_pll_clk_div32_out"),
+ CLK_MSR_ID(108, "cmpr"),
+ CLK_MSR_ID(109, "dewarpa"),
+ CLK_MSR_ID(110, "sc"),
+ CLK_MSR_ID(111, "sar_adc"),
+ CLK_MSR_ID(112, "glb"),
+ CLK_MSR_ID(113, "sd_emmc_c"),
+ CLK_MSR_ID(114, "sd_emmc_b"),
+ CLK_MSR_ID(115, "sd_emmc_a"),
+ CLK_MSR_ID(116, "gpio_msr_clk"),
+ CLK_MSR_ID(117, "aux_clk_o"),
+ CLK_MSR_ID(118, "spisg0"),
+ CLK_MSR_ID(121, "ts"),
+ CLK_MSR_ID(122, "usb_48m"),
+ CLK_MSR_ID(123, "usb_250m"),
+ CLK_MSR_ID(124, "eth_125m"),
+ CLK_MSR_ID(125, "eth_rmii"),
+ CLK_MSR_ID(126, "hrx20_tmds20_clk"),
+ CLK_MSR_ID(127, "hrx20_cable_clk"),
+ CLK_MSR_ID(128, "hdmirx_vid_clk"),
+ CLK_MSR_ID(129, "hdmirx_aud_clk"),
+ CLK_MSR_ID(130, "dptx_apb2"),
+ CLK_MSR_ID(131, "dptx_aud"),
+ CLK_MSR_ID(132, "audio_todptx_bclk"),
+ CLK_MSR_ID(133, "audio_txhdmitx_bclk"),
+ CLK_MSR_ID(134, "audio_txhdmitx_mclk"),
+ CLK_MSR_ID(135, "audio_txhdmitx_spdif_clk"),
+ CLK_MSR_ID(136, "mclk_0_pre"),
+ CLK_MSR_ID(137, "mclk1_0_pre"),
+ CLK_MSR_ID(138, "pixel0_pll_clkout"),
+ CLK_MSR_ID(139, "pixel1_pll_clkout"),
+ CLK_MSR_ID(140, "tcon_clk_out0"),
+ CLK_MSR_ID(141, "tcon_clk_out1"),
+ CLK_MSR_ID(142, "audio_todptx_spdif_clk"),
+ CLK_MSR_ID(143, "audio_todptx_mclk"),
+ CLK_MSR_ID(144, "dptx_lnk_clk"),
+ CLK_MSR_ID(145, "edptx_lnk_clk_tx"),
+ CLK_MSR_ID(146, "mod_audio_pdm_dclk_o_ao"),
+ CLK_MSR_ID(147, "vid2_pll"),
+ CLK_MSR_ID(151, "can1_filter"),
+ CLK_MSR_ID(152, "can0_filter"),
+ CLK_MSR_ID(153, "can1_pe"),
+ CLK_MSR_ID(154, "can0_pe"),
+ CLK_MSR_ID(155, "o_sed_clk"),
+ CLK_MSR_ID(156, "pwm_n"),
+ CLK_MSR_ID(157, "pwm_m"),
+ CLK_MSR_ID(158, "pwm_l"),
+ CLK_MSR_ID(159, "pwm_k"),
+ CLK_MSR_ID(160, "pwm_j"),
+ CLK_MSR_ID(161, "pwm_i"),
+ CLK_MSR_ID(162, "pwm_h"),
+ CLK_MSR_ID(170, "rng_ring_osc_clk[0]"),
+ CLK_MSR_ID(171, "rng_ring_osc_clk[1]"),
+ CLK_MSR_ID(172, "rng_ring_osc_clk[2]"),
+ CLK_MSR_ID(173, "rng_ring_osc_clk[3]"),
+ CLK_MSR_ID(174, "rng_ring_osc_clk[4]"),
+ CLK_MSR_ID(175, "sys_cpu_osc_ring_clk[0]"),
+ CLK_MSR_ID(176, "sys_cpu_osc_ring_clk[1]"),
+ CLK_MSR_ID(177, "sys_cpu_osc_ring_clk[2]"),
+ CLK_MSR_ID(178, "sys_cpu_osc_ring_clk[3]"),
+ CLK_MSR_ID(179, "sys_cpu_osc_ring_clk[4]"),
+ CLK_MSR_ID(180, "sys_cpu_osc_ring_clk[5]"),
+ CLK_MSR_ID(181, "sys_cpu_osc_ring_clk[6]"),
+ CLK_MSR_ID(182, "sys_cpu_osc_ring_clk[7]"),
+ CLK_MSR_ID(183, "sys_cpu_osc_ring_clk[8]"),
+ CLK_MSR_ID(184, "sys_cpu_osc_ring_clk[9]"),
+ CLK_MSR_ID(185, "osc_ring_clk_gpu[0]"),
+ CLK_MSR_ID(186, "osc_ring_clk_gpu[1]"),
+ CLK_MSR_ID(187, "osc_ring_clk_vpu"),
+ CLK_MSR_ID(188, "osc_ring_clk_dos[0]"),
+ CLK_MSR_ID(189, "osc_ring_clk_dos[1]"),
+ CLK_MSR_ID(190, "osc_ring_clk_vge"),
+ CLK_MSR_ID(191, "osc_ring_clk_nna[0]"),
+ CLK_MSR_ID(192, "osc_ring_clk_nna[1]"),
+ CLK_MSR_ID(193, "osc_ring_clk_top[0]"),
+ CLK_MSR_ID(194, "osc_ring_clk_top[1]"),
+ CLK_MSR_ID(195, "nna"),
+ CLK_MSR_ID(200, "pcie1_tl"),
+ CLK_MSR_ID(201, "pcie0_tl"),
+ CLK_MSR_ID(202, "pp"),
+ CLK_MSR_ID(203, "pwm_a(ao)"),
+ CLK_MSR_ID(204, "pwm_b(ao)"),
+ CLK_MSR_ID(205, "pwm_c(ao)"),
+ CLK_MSR_ID(206, "pwm_d(ao)"),
+ CLK_MSR_ID(207, "pwm_e(ao)"),
+ CLK_MSR_ID(208, "pwm_f(ao)"),
+ CLK_MSR_ID(209, "pwm_g(ao)"),
+ CLK_MSR_ID(210, "ao_cec"),
+ CLK_MSR_ID(211, "sec_pulse_out"),
+ CLK_MSR_ID(212, "osc_clk_out"),
+ CLK_MSR_ID(213, "earcrx_pll_clk_out"),
+ CLK_MSR_ID(215, "o_pd_sysclk"),
+ CLK_MSR_ID(216, "o_earcrx_dmac_clk"),
+ CLK_MSR_ID(217, "o_earcrx_cmdc_clk"),
+ CLK_MSR_ID(218, "o_earctx_dmac_clk"),
+ CLK_MSR_ID(219, "o_earctx_cmdc_clk"),
+ CLK_MSR_ID(220, "o_earctx_ana_dmac_clk_a2d"),
+ CLK_MSR_ID(221, "o_tohdmi_dp_tx_a_bclk"),
+ CLK_MSR_ID(222, "o_tohdmi_dp_tx_a_mclk"),
+ CLK_MSR_ID(223, "o_tohdmi_dp_tx_a_spdif_clk"),
+ CLK_MSR_ID(224, "o_tohdmi_dp_tx_b_bclk"),
+ CLK_MSR_ID(225, "o_tohdmi_dp_tx_b_mclk"),
+ CLK_MSR_ID(226, "o_tohdmi_dp_tx_b_spdif_clk"),
+ CLK_MSR_ID(227, "o_toacodec_dac_bclk"),
+ CLK_MSR_ID(228, "o_toacodec_dac_mclk"),
+ CLK_MSR_ID(229, "o_spdifout_b_mst_clk"),
+ CLK_MSR_ID(230, "o_spdifout_mst_clk"),
+ CLK_MSR_ID(231, "o_spdifin_mst_clk"),
+ CLK_MSR_ID(232, "o_audio_mclk"),
+ CLK_MSR_ID(233, "o_vad_clk"),
+ CLK_MSR_ID(234, "o_tdmout_d_sclk"),
+ CLK_MSR_ID(235, "o_tdmout_c_sclk"),
+ CLK_MSR_ID(236, "o_tdmout_b_sclk"),
+ CLK_MSR_ID(237, "o_tdmout_a_sclk"),
+ CLK_MSR_ID(238, "o_tdminb_lb_sclk"),
+ CLK_MSR_ID(239, "o_tdmin_lb_sclk"),
+ CLK_MSR_ID(240, "o_tdmin_d_sclk"),
+ CLK_MSR_ID(241, "o_tdmin_c_sclk"),
+ CLK_MSR_ID(242, "o_tdmin_b_sclk"),
+ CLK_MSR_ID(243, "o_tdmin_a_sclk"),
+ CLK_MSR_ID(244, "o_resampleb_clk"),
+ CLK_MSR_ID(245, "o_resamplea_clk"),
+ CLK_MSR_ID(246, "o_pdmb_sysclk"),
+ CLK_MSR_ID(247, "o_pdmb_dclk"),
+ CLK_MSR_ID(248, "o_pdm_sysclk"),
+ CLK_MSR_ID(249, "o_pdm_dclk"),
+ CLK_MSR_ID(250, "c_alockerb_out_clk"),
+ CLK_MSR_ID(251, "c_alockerb_in_clk"),
+ CLK_MSR_ID(252, "c_alocker_out_clk"),
+ CLK_MSR_ID(253, "c_alocker_in_clk"),
+ CLK_MSR_ID(254, "o_resample_c_clk")
+};
+
+static const struct meson_msr_id clk_msr_s6[] = {
+ CLK_MSR_ID(0, "sys_clk"),
+ CLK_MSR_ID(1, "axi_clk"),
+ CLK_MSR_ID(2, "rtc_clk"),
+ CLK_MSR_ID(3, "dspa"),
+ CLK_MSR_ID(4, "mali_stack"),
+ CLK_MSR_ID(5, "mali"),
+ CLK_MSR_ID(6, "cpu_clk_div16"),
+ CLK_MSR_ID(7, "mali_aclkm"),
+ CLK_MSR_ID(8, "cecb"),
+ CLK_MSR_ID(9, "gp2_pll"),
+ CLK_MSR_ID(10, "fclk_div5"),
+ CLK_MSR_ID(11, "p21_usb2_ckout"),
+ CLK_MSR_ID(12, "p20_usb2_ckout"),
+ CLK_MSR_ID(13, "eth_mpll_test"),
+ CLK_MSR_ID(15, "fclk_50m"),
+ CLK_MSR_ID(18, "gp1_pll"),
+ CLK_MSR_ID(19, "hifi_pll"),
+ CLK_MSR_ID(20, "gp0_pll"),
+ CLK_MSR_ID(21, "hifi1_pll"),
+ CLK_MSR_ID(22, "eth_mppll_50m_ckout"),
+ CLK_MSR_ID(23, "sys_pll_div16"),
+ CLK_MSR_ID(24, "ddr_dpll_pt_clk"),
+ CLK_MSR_ID(25, "mod_Tsin_A_CLK_IN"),
+ CLK_MSR_ID(26, "ext_Tsin_B_CLK_IN"),
+ CLK_MSR_ID(27, "mod_Tsin_C_CLK_IN"),
+ CLK_MSR_ID(28, "mod_Tsin_D_CLK_IN"),
+ CLK_MSR_ID(29, "dsi_pll_div_clk_out"),
+ CLK_MSR_ID(30, "dsi_pll_clk"),
+ CLK_MSR_ID(32, "eth_125m"),
+ CLK_MSR_ID(33, "eth_rmii"),
+ CLK_MSR_ID(34, "co_clkin_to_mac"),
+ CLK_MSR_ID(36, "co_rx_clk"),
+ CLK_MSR_ID(37, "co_tx_clk"),
+ CLK_MSR_ID(38, "eth_phy_rxclk"),
+ CLK_MSR_ID(39, "eth_phy_plltxclk"),
+ CLK_MSR_ID(40, "ephy_test_clk"),
+ CLK_MSR_ID(49, "hdmi_vx1_pix_clk"),
+ CLK_MSR_ID(50, "vid_pll"),
+ CLK_MSR_ID(51, "enci"),
+ CLK_MSR_ID(52, "encp"),
+ CLK_MSR_ID(53, "encl"),
+ CLK_MSR_ID(54, "vdac"),
+ CLK_MSR_ID(55, "cdac"),
+ CLK_MSR_ID(57, "lcd_an_clk_ph2"),
+ CLK_MSR_ID(58, "lcd_an_clk_ph3"),
+ CLK_MSR_ID(59, "hdmitx_pixel"),
+ CLK_MSR_ID(60, "vdin_meas"),
+ CLK_MSR_ID(61, "vpu"),
+ CLK_MSR_ID(62, "vpu_clkb"),
+ CLK_MSR_ID(63, "vpu_clkb_tmp"),
+ CLK_MSR_ID(64, "vpu_clkc"),
+ CLK_MSR_ID(65, "vid_lock"),
+ CLK_MSR_ID(66, "vapb"),
+ CLK_MSR_ID(67, "ge2d"),
+ CLK_MSR_ID(70, "mipi_dsi_meas"),
+ CLK_MSR_ID(71, "mipi_dsi_phy"),
+ CLK_MSR_ID(72, "mipi_csi_phy"),
+ CLK_MSR_ID(73, "csi2_adapt"),
+ CLK_MSR_ID(74, "cts_csi2_data"),
+ CLK_MSR_ID(75, "mipi_csi_phy_out"),
+ CLK_MSR_ID(76, "hdmitx_tmds"),
+ CLK_MSR_ID(77, "hdmitx_sys"),
+ CLK_MSR_ID(78, "hdmitx_fe"),
+ CLK_MSR_ID(79, "rama_clk"),
+ CLK_MSR_ID(80, "hdmitx_prif"),
+ CLK_MSR_ID(81, "hdmitx_200m"),
+ CLK_MSR_ID(82, "hdmitx_aud"),
+ CLK_MSR_ID(84, "audio_tohdmitx_mclk"),
+ CLK_MSR_ID(85, "audio_tohdmitx_bclk"),
+ CLK_MSR_ID(86, "audio_tohdmitx_lrclk"),
+ CLK_MSR_ID(87, "audio_tohdmitx_spdif_clk"),
+ CLK_MSR_ID(88, "htx_aes_clk"),
+ CLK_MSR_ID(89, "amfc"),
+ CLK_MSR_ID(93, "vdec"),
+ CLK_MSR_ID(99, "hevcf"),
+ CLK_MSR_ID(106, "deskew_pll_clk_div32_out"),
+ CLK_MSR_ID(108, "cmpr"),
+ CLK_MSR_ID(109, "dewarpa"),
+ CLK_MSR_ID(110, "sc"),
+ CLK_MSR_ID(111, "sar_adc"),
+ CLK_MSR_ID(113, "sd_emmc_c"),
+ CLK_MSR_ID(114, "sd_emmc_b"),
+ CLK_MSR_ID(115, "sd_emmc_a"),
+ CLK_MSR_ID(116, "gpio_msr_clk"),
+ CLK_MSR_ID(117, "aux_clk_o"),
+ CLK_MSR_ID(118, "spicc"),
+ CLK_MSR_ID(121, "ts"),
+ CLK_MSR_ID(130, "o_vad_clk"),
+ CLK_MSR_ID(132, "audio_locker_in_clk"),
+ CLK_MSR_ID(133, "audio_locker_out_clk"),
+ CLK_MSR_ID(134, "audio_tdmout_c_sclk"),
+ CLK_MSR_ID(135, "audio_tdmout_b_sclk"),
+ CLK_MSR_ID(136, "audio_tdmout_a_sclk"),
+ CLK_MSR_ID(137, "audio_tdmin_lb_sclk"),
+ CLK_MSR_ID(138, "audio_tdmin_c_sclk"),
+ CLK_MSR_ID(139, "audio_tdmin_b_sclk"),
+ CLK_MSR_ID(140, "audio_tdmin_a_sclk"),
+ CLK_MSR_ID(141, "audio_resamplea_clk"),
+ CLK_MSR_ID(142, "audio_pdm_sysclk"),
+ CLK_MSR_ID(143, "audio_spdifout_b_mst_clk"),
+ CLK_MSR_ID(144, "audio_spdifout_mst_clk"),
+ CLK_MSR_ID(145, "audio_spdifin_mst_clk"),
+ CLK_MSR_ID(147, "audio_resampleb_clk"),
+ CLK_MSR_ID(148, "pcie_pipe_clk"),
+ CLK_MSR_ID(149, "pcie_ref_clk"),
+ CLK_MSR_ID(150, "pcie_upcrx_cdrclk"),
+ CLK_MSR_ID(151, "pcie_upcrx_clk_sync_b20"),
+ CLK_MSR_ID(152, "pcie_u3p2pll1_clk_div16"),
+ CLK_MSR_ID(153, "pcie_u3p2pll0_clkout"),
+ CLK_MSR_ID(154, "pcie_ref_clk_p"),
+ CLK_MSR_ID(160, "pwm_j"),
+ CLK_MSR_ID(161, "pwm_i"),
+ CLK_MSR_ID(162, "pwm_h"),
+ CLK_MSR_ID(163, "pwm_g"),
+ CLK_MSR_ID(164, "pwm_f"),
+ CLK_MSR_ID(165, "pwm_e"),
+ CLK_MSR_ID(166, "pwm_d"),
+ CLK_MSR_ID(167, "pwm_c"),
+ CLK_MSR_ID(168, "pwm_b"),
+ CLK_MSR_ID(169, "pwm_a"),
+ CLK_MSR_ID(175, "rng_ring_clk[0]"),
+ CLK_MSR_ID(176, "rng_ring_clk[1]"),
+ CLK_MSR_ID(177, "rng_ring_clk[2]"),
+ CLK_MSR_ID(178, "rng_ring_clk[3]"),
+ CLK_MSR_ID(179, "rng_ring_clk[4]"),
+ CLK_MSR_ID(180, "am_ring_osc_clk_out[0]"),
+ CLK_MSR_ID(181, "am_ring_osc_clk_out[1]"),
+ CLK_MSR_ID(182, "am_ring_osc_clk_out[2]"),
+ CLK_MSR_ID(183, "am_ring_osc_clk_out[3]"),
+ CLK_MSR_ID(184, "am_ring_osc_clk_out[4]"),
+ CLK_MSR_ID(185, "am_ring_osc_clk_out[5]"),
+ CLK_MSR_ID(186, "am_ring_osc_clk_out[6]"),
+ CLK_MSR_ID(187, "am_ring_osc_clk_out[7]"),
+ CLK_MSR_ID(188, "am_ring_osc_clk_out[8]"),
+ CLK_MSR_ID(189, "am_ring_osc_clk_out[9]"),
+ CLK_MSR_ID(190, "am_ring_osc_clk_out[10]"),
+ CLK_MSR_ID(191, "am_ring_osc_clk_out[11]"),
+ CLK_MSR_ID(192, "am_ring_osc_clk_out[12]"),
+ CLK_MSR_ID(193, "am_ring_osc_clk_out[13]"),
+ CLK_MSR_ID(194, "am_ring_osc_clk_out[14]"),
+ CLK_MSR_ID(195, "am_ring_osc_clk_out[15]"),
+ CLK_MSR_ID(196, "am_ring_osc_clk_out[16]"),
+ CLK_MSR_ID(197, "nna"),
+ CLK_MSR_ID(198, "vc9000e_axi"),
+ CLK_MSR_ID(199, "vc9000e_core"),
+ CLK_MSR_ID(201, "pcie_tl"),
+ CLK_MSR_ID(204, "u3p2pll1_clk_div16"),
+ CLK_MSR_ID(205, "u3p2pll0_clkout"),
+ CLK_MSR_ID(206, "upctx_clk_sync_b20"),
+ CLK_MSR_ID(207, "upcrx_carclk"),
+ CLK_MSR_ID(208, "usb_pipe_clk"),
+ CLK_MSR_ID(209, "earcrx_pll_out"),
+ CLK_MSR_ID(210, "mclk_pll_clk")
+};
+
+static const struct meson_msr_id clk_msr_s7[] = {
+ CLK_MSR_ID(0, "sys_clk"),
+ CLK_MSR_ID(1, "axi_clk"),
+ CLK_MSR_ID(2, "rtc_clk"),
+ CLK_MSR_ID(5, "mali"),
+ CLK_MSR_ID(6, "cpu_clk_div16"),
+ CLK_MSR_ID(8, "cecb"),
+ CLK_MSR_ID(10, "fclk_div5"),
+ CLK_MSR_ID(11, "p21_usb2_ckout"),
+ CLK_MSR_ID(12, "p20_usb2_ckout"),
+ CLK_MSR_ID(13, "eth_mpll_test"),
+ CLK_MSR_ID(15, "fclk_50m"),
+ CLK_MSR_ID(18, "gp1_pll"),
+ CLK_MSR_ID(19, "hifi_pll"),
+ CLK_MSR_ID(20, "gp0_pll"),
+ CLK_MSR_ID(21, "hifi1_pll"),
+ CLK_MSR_ID(22, "eth_mppll_50m_ckout"),
+ CLK_MSR_ID(23, "sys_pll_div16"),
+ CLK_MSR_ID(24, "ddr_dpll_pt_clk"),
+ CLK_MSR_ID(25, "mod_Tsin_A_CLK_IN"),
+ CLK_MSR_ID(32, "eth_125m"),
+ CLK_MSR_ID(33, "eth_rmii"),
+ CLK_MSR_ID(34, "co_clkin_to_mac"),
+ CLK_MSR_ID(36, "co_rx_clk"),
+ CLK_MSR_ID(37, "co_tx_clk"),
+ CLK_MSR_ID(38, "eth_phy_rxclk"),
+ CLK_MSR_ID(39, "eth_phy_plltxclk"),
+ CLK_MSR_ID(40, "ephy_test_clk"),
+ CLK_MSR_ID(49, "hdmi_vx1_pix_clk"),
+ CLK_MSR_ID(50, "vid_pll"),
+ CLK_MSR_ID(51, "enci"),
+ CLK_MSR_ID(52, "encp"),
+ CLK_MSR_ID(53, "encl"),
+ CLK_MSR_ID(54, "vdac"),
+ CLK_MSR_ID(55, "cdac"),
+ CLK_MSR_ID(57, "lcd_an_clk_ph2"),
+ CLK_MSR_ID(58, "lcd_an_clk_ph3"),
+ CLK_MSR_ID(59, "hdmitx_pixel"),
+ CLK_MSR_ID(60, "vdin_meas"),
+ CLK_MSR_ID(61, "vpu"),
+ CLK_MSR_ID(62, "vpu_clkb"),
+ CLK_MSR_ID(63, "vpu_clkb_tmp"),
+ CLK_MSR_ID(64, "vpu_clkc"),
+ CLK_MSR_ID(65, "vid_lock"),
+ CLK_MSR_ID(66, "vapb"),
+ CLK_MSR_ID(67, "ge2d"),
+ CLK_MSR_ID(76, "hdmitx_tmds"),
+ CLK_MSR_ID(77, "hdmitx_sys"),
+ CLK_MSR_ID(78, "hdmitx_fe"),
+ CLK_MSR_ID(80, "hdmitx_prif"),
+ CLK_MSR_ID(81, "hdmitx_200m"),
+ CLK_MSR_ID(82, "hdmitx_aud"),
+ CLK_MSR_ID(84, "audio_tohdmitx_mclk"),
+ CLK_MSR_ID(85, "audio_tohdmitx_bclk"),
+ CLK_MSR_ID(86, "audio_tohdmitx_lrclk"),
+ CLK_MSR_ID(87, "audio_tohdmitx_spdif_clk"),
+ CLK_MSR_ID(88, "htx_aes_clk"),
+ CLK_MSR_ID(93, "vdec"),
+ CLK_MSR_ID(99, "hevcf"),
+ CLK_MSR_ID(106, "deskew_pll_clk_div32_out"),
+ CLK_MSR_ID(110, "sc"),
+ CLK_MSR_ID(111, "sar_adc"),
+ CLK_MSR_ID(113, "sd_emmc_c"),
+ CLK_MSR_ID(114, "sd_emmc_b"),
+ CLK_MSR_ID(115, "sd_emmc_a"),
+ CLK_MSR_ID(116, "gpio_msr_clk"),
+ CLK_MSR_ID(118, "spicc"),
+ CLK_MSR_ID(121, "ts"),
+ CLK_MSR_ID(130, "o_vad_clk"),
+ CLK_MSR_ID(131, "au_dac_clk_x128"),
+ CLK_MSR_ID(132, "audio_locker_in_clk"),
+ CLK_MSR_ID(133, "audio_locker_out_clk"),
+ CLK_MSR_ID(134, "audio_tdmout_c_sclk"),
+ CLK_MSR_ID(135, "audio_tdmout_b_sclk"),
+ CLK_MSR_ID(136, "audio_tdmout_a_sclk"),
+ CLK_MSR_ID(137, "audio_tdmin_lb_sclk"),
+ CLK_MSR_ID(138, "audio_tdmin_c_sclk"),
+ CLK_MSR_ID(139, "audio_tdmin_b_sclk"),
+ CLK_MSR_ID(140, "audio_tdmin_a_sclk"),
+ CLK_MSR_ID(141, "audio_resamplea_clk"),
+ CLK_MSR_ID(142, "audio_pdm_sysclk"),
+ CLK_MSR_ID(143, "audio_spdifout_b_mst_clk"),
+ CLK_MSR_ID(144, "audio_spdifout_mst_clk"),
+ CLK_MSR_ID(145, "audio_spdifin_mst_clk"),
+ CLK_MSR_ID(147, "audio_resampleb_clk"),
+ CLK_MSR_ID(160, "pwm_j"),
+ CLK_MSR_ID(161, "pwm_i"),
+ CLK_MSR_ID(162, "pwm_h"),
+ CLK_MSR_ID(163, "pwm_g"),
+ CLK_MSR_ID(164, "pwm_f"),
+ CLK_MSR_ID(165, "pwm_e"),
+ CLK_MSR_ID(166, "pwm_d"),
+ CLK_MSR_ID(167, "pwm_c"),
+ CLK_MSR_ID(168, "pwm_b"),
+ CLK_MSR_ID(169, "pwm_a"),
+ CLK_MSR_ID(176, "rng_ring_clk[0]"),
+ CLK_MSR_ID(177, "rng_ring_clk[1]"),
+ CLK_MSR_ID(178, "rng_ring_clk[2]"),
+ CLK_MSR_ID(179, "rng_ring_clk[3]"),
+ CLK_MSR_ID(180, "osc_ring_clk[0](a55 core0 14_slvt)"),
+ CLK_MSR_ID(181, "osc_ring_clk[1](a55 core1 14_slvt)"),
+ CLK_MSR_ID(182, "osc_ring_clk[2](a55 core2 14_slvt)"),
+ CLK_MSR_ID(183, "osc_ring_clk[3](a55 core3 14_slvt)"),
+ CLK_MSR_ID(184, "osc_ring_clk[4](a55_pwr[0] 16_slvt)"),
+ CLK_MSR_ID(185, "osc_ring_clk[5](a55_pwr[1] 14_lvt)"),
+ CLK_MSR_ID(186, "osc_ring_clk[6](a55_pwr[2] 14_rvt)"),
+ CLK_MSR_ID(187, "osc_ring_clk[7](mali[1] 14_lvt)"),
+ CLK_MSR_ID(188, "osc_ring_clk[8](mali[1] 14_rvt)"),
+ CLK_MSR_ID(189, "osc_ring_clk[9](dos[0] 16_lvt)"),
+ CLK_MSR_ID(190, "osc_ring_clk[10](dos[1] 14_rvt)"),
+ CLK_MSR_ID(191, "osc_ring_clk[11](ddr[0] 9t_14_lvt)"),
+ CLK_MSR_ID(192, "osc_ring_clk[12](top[0] 16_rvt)"),
+};
+
+static const struct meson_msr_id clk_msr_s7d[] = {
+ CLK_MSR_ID(0, "sys_clk"),
+ CLK_MSR_ID(1, "axi_clk"),
+ CLK_MSR_ID(2, "rtc_clk"),
+ CLK_MSR_ID(4, "mali_stack"),
+ CLK_MSR_ID(5, "mali"),
+ CLK_MSR_ID(6, "cpu_clk_div16"),
+ CLK_MSR_ID(8, "cecb"),
+ CLK_MSR_ID(9, "mali_aclkm"),
+ CLK_MSR_ID(10, "fclk_div5"),
+ CLK_MSR_ID(11, "p21_usb2_ckout"),
+ CLK_MSR_ID(12, "p20_usb2_ckout"),
+ CLK_MSR_ID(13, "eth_mpll_test"),
+ CLK_MSR_ID(15, "fclk_50m"),
+ CLK_MSR_ID(18, "gp1_pll"),
+ CLK_MSR_ID(19, "hifi_pll"),
+ CLK_MSR_ID(20, "gp0_pll"),
+ CLK_MSR_ID(21, "hifi1_pll"),
+ CLK_MSR_ID(22, "eth_mppll_50m_ckout"),
+ CLK_MSR_ID(23, "sys_pll_div16"),
+ CLK_MSR_ID(24, "ddr_dpll_pt_clk"),
+ CLK_MSR_ID(25, "mod_Tsin_A_CLK_IN"),
+ CLK_MSR_ID(26, "mod_Tsin_B_CLK_IN"),
+ CLK_MSR_ID(31, "earcrx_pll_clk_out"),
+ CLK_MSR_ID(32, "eth_125m"),
+ CLK_MSR_ID(33, "eth_rmii"),
+ CLK_MSR_ID(34, "co_clkin_to_mac"),
+ CLK_MSR_ID(36, "co_rx_clk"),
+ CLK_MSR_ID(37, "co_tx_clk"),
+ CLK_MSR_ID(38, "eth_phy_rxclk"),
+ CLK_MSR_ID(39, "eth_phy_plltxclk"),
+ CLK_MSR_ID(40, "ephy_test_clk"),
+ CLK_MSR_ID(49, "hdmi_vx1_pix_clk"),
+ CLK_MSR_ID(50, "vid_pll"),
+ CLK_MSR_ID(51, "enci"),
+ CLK_MSR_ID(52, "encp"),
+ CLK_MSR_ID(53, "encl"),
+ CLK_MSR_ID(54, "vdac"),
+ CLK_MSR_ID(55, "cdac"),
+ CLK_MSR_ID(57, "lcd_an_clk_ph2"),
+ CLK_MSR_ID(58, "lcd_an_clk_ph3"),
+ CLK_MSR_ID(59, "hdmitx_pixel"),
+ CLK_MSR_ID(60, "vdin_meas"),
+ CLK_MSR_ID(61, "vpu"),
+ CLK_MSR_ID(62, "vpu_clkb"),
+ CLK_MSR_ID(63, "vpu_clkb_tmp"),
+ CLK_MSR_ID(64, "vpu_clkc"),
+ CLK_MSR_ID(65, "vid_lock"),
+ CLK_MSR_ID(66, "vapb"),
+ CLK_MSR_ID(67, "ge2d"),
+ CLK_MSR_ID(76, "hdmitx_tmds"),
+ CLK_MSR_ID(77, "hdmitx_sys"),
+ CLK_MSR_ID(78, "hdmitx_fe"),
+ CLK_MSR_ID(80, "hdmitx_prif"),
+ CLK_MSR_ID(81, "hdmitx_200m"),
+ CLK_MSR_ID(82, "hdmitx_aud"),
+ CLK_MSR_ID(84, "audio_tohdmitx_mclk"),
+ CLK_MSR_ID(85, "audio_tohdmitx_bclk"),
+ CLK_MSR_ID(86, "audio_tohdmitx_lrclk"),
+ CLK_MSR_ID(87, "audio_tohdmitx_spdif_clk"),
+ CLK_MSR_ID(88, "htx_aes_clk"),
+ CLK_MSR_ID(89, "amfc"),
+ CLK_MSR_ID(93, "vdec"),
+ CLK_MSR_ID(97, "hcodec"),
+ CLK_MSR_ID(99, "hevcf"),
+ CLK_MSR_ID(106, "deskew_pll_clk_div32_out"),
+ CLK_MSR_ID(110, "sc"),
+ CLK_MSR_ID(111, "sar_adc"),
+ CLK_MSR_ID(112, "aux_adc_clk_to_gpio"),
+ CLK_MSR_ID(113, "sd_emmc_c"),
+ CLK_MSR_ID(114, "sd_emmc_b"),
+ CLK_MSR_ID(115, "sd_emmc_a"),
+ CLK_MSR_ID(116, "gpio_msr_clk"),
+ CLK_MSR_ID(117, "aux_clk_o"),
+ CLK_MSR_ID(118, "spicc"),
+ CLK_MSR_ID(121, "ts"),
+ CLK_MSR_ID(130, "o_vad_clk"),
+ CLK_MSR_ID(131, "au_dac_clk_x128"),
+ CLK_MSR_ID(132, "audio_locker_in_clk"),
+ CLK_MSR_ID(133, "audio_locker_out_clk"),
+ CLK_MSR_ID(134, "audio_tdmout_c_sclk"),
+ CLK_MSR_ID(135, "audio_tdmout_b_sclk"),
+ CLK_MSR_ID(136, "audio_tdmout_a_sclk"),
+ CLK_MSR_ID(137, "audio_tdmin_lb_sclk"),
+ CLK_MSR_ID(138, "audio_tdmin_c_sclk"),
+ CLK_MSR_ID(139, "audio_tdmin_b_sclk"),
+ CLK_MSR_ID(140, "audio_tdmin_a_sclk"),
+ CLK_MSR_ID(141, "audio_resamplea_clk"),
+ CLK_MSR_ID(142, "audio_pdm_sysclk"),
+ CLK_MSR_ID(143, "audio_spdifout_b_mst_clk"),
+ CLK_MSR_ID(144, "audio_spdifout_mst_clk"),
+ CLK_MSR_ID(145, "audio_spdifin_mst_clk"),
+ CLK_MSR_ID(146, "mod_audio_pdm_dclk_o"),
+ CLK_MSR_ID(147, "audio_resampleb_clk"),
+ CLK_MSR_ID(160, "pwm_j"),
+ CLK_MSR_ID(161, "pwm_i"),
+ CLK_MSR_ID(162, "pwm_h"),
+ CLK_MSR_ID(163, "pwm_g"),
+ CLK_MSR_ID(164, "pwm_f"),
+ CLK_MSR_ID(165, "pwm_e"),
+ CLK_MSR_ID(166, "pwm_d"),
+ CLK_MSR_ID(167, "pwm_c"),
+ CLK_MSR_ID(168, "pwm_b"),
+ CLK_MSR_ID(169, "pwm_a"),
+ CLK_MSR_ID(176, "rng_ring_clk[0]"),
+ CLK_MSR_ID(177, "rng_ring_clk[1]"),
+ CLK_MSR_ID(178, "rng_ring_clk[2]"),
+ CLK_MSR_ID(179, "rng_ring_clk[3]"),
+ CLK_MSR_ID(180, "osc_ring_clk[0](a55 core0 14_slvt)"),
+ CLK_MSR_ID(181, "osc_ring_clk[1](a55 core1 14_slvt)"),
+ CLK_MSR_ID(182, "osc_ring_clk[2](a55 core2 14_slvt)"),
+ CLK_MSR_ID(183, "osc_ring_clk[3](a55 core3 14_slvt)"),
+ CLK_MSR_ID(184, "osc_ring_clk[4](a55_pwr[0] 16_slvt)"),
+ CLK_MSR_ID(185, "osc_ring_clk[5](a55_pwr[1] 14_lvt)"),
+ CLK_MSR_ID(186, "osc_ring_clk[6](a55_pwr[2] 14_rvt)"),
+ CLK_MSR_ID(187, "osc_ring_clk[7](mali[1] 14_lvt)"),
+ CLK_MSR_ID(188, "osc_ring_clk[8](mali[1] 14_rvt)"),
+ CLK_MSR_ID(189, "osc_ring_clk[9](dos[0] 16_lvt)"),
+ CLK_MSR_ID(190, "osc_ring_clk[10](dos[1] 14_rvt)"),
+ CLK_MSR_ID(191, "osc_ring_clk[11](ddr[0] 9t_14_lvt)"),
+ CLK_MSR_ID(192, "osc_ring_clk[12](top[0] 16_rvt)"),
+};
+
static int meson_measure_id(struct meson_msr_id *clk_msr_id,
unsigned int duration)
{
@@ -1279,6 +2116,30 @@ static const struct msr_reg_offset msr_reg_offset_v2 = {
.duty_val = 0x18,
};
+static const struct meson_msr_data clk_msr_a1_data = {
+ .msr_table = (void *)clk_msr_a1,
+ .msr_count = ARRAY_SIZE(clk_msr_a1),
+ .reg = &msr_reg_offset_v2,
+};
+
+static const struct meson_msr_data clk_msr_a4_data = {
+ .msr_table = (void *)clk_msr_a4,
+ .msr_count = ARRAY_SIZE(clk_msr_a4),
+ .reg = &msr_reg_offset_v2,
+};
+
+static const struct meson_msr_data clk_msr_a5_data = {
+ .msr_table = (void *)clk_msr_a5,
+ .msr_count = ARRAY_SIZE(clk_msr_a5),
+ .reg = &msr_reg_offset_v2,
+};
+
+static const struct meson_msr_data clk_msr_a9_data = {
+ .msr_table = (void *)clk_msr_a9,
+ .msr_count = ARRAY_SIZE(clk_msr_a9),
+ .reg = &msr_reg_offset_v2,
+};
+
static const struct meson_msr_data clk_msr_c3_data = {
.msr_table = (void *)clk_msr_c3,
.msr_count = ARRAY_SIZE(clk_msr_c3),
@@ -1291,9 +2152,21 @@ static const struct meson_msr_data clk_msr_s4_data = {
.reg = &msr_reg_offset_v2,
};
-static const struct meson_msr_data clk_msr_a1_data = {
- .msr_table = (void *)clk_msr_a1,
- .msr_count = ARRAY_SIZE(clk_msr_a1),
+static const struct meson_msr_data clk_msr_s6_data = {
+ .msr_table = (void *)clk_msr_s6,
+ .msr_count = ARRAY_SIZE(clk_msr_s6),
+ .reg = &msr_reg_offset_v2,
+};
+
+static const struct meson_msr_data clk_msr_s7_data = {
+ .msr_table = (void *)clk_msr_s7,
+ .msr_count = ARRAY_SIZE(clk_msr_s7),
+ .reg = &msr_reg_offset_v2,
+};
+
+static const struct meson_msr_data clk_msr_s7d_data = {
+ .msr_table = (void *)clk_msr_s7d,
+ .msr_count = ARRAY_SIZE(clk_msr_s7d),
.reg = &msr_reg_offset_v2,
};
@@ -1305,16 +2178,24 @@ static const struct meson_msr_data clk_msr_t7_data = {
static const struct of_device_id meson_msr_match_table[] = {
{
- .compatible = "amlogic,meson-gx-clk-measure",
- .data = &clk_msr_gx_data,
+ .compatible = "amlogic,a1-clk-measure",
+ .data = &clk_msr_a1_data,
},
{
- .compatible = "amlogic,meson8-clk-measure",
- .data = &clk_msr_m8_data,
+ .compatible = "amlogic,a4-clk-measure",
+ .data = &clk_msr_a4_data,
},
{
- .compatible = "amlogic,meson8b-clk-measure",
- .data = &clk_msr_m8_data,
+ .compatible = "amlogic,a5-clk-measure",
+ .data = &clk_msr_a5_data,
+ },
+ {
+ .compatible = "amlogic,a9-clk-measure",
+ .data = &clk_msr_a9_data,
+ },
+ {
+ .compatible = "amlogic,c3-clk-measure",
+ .data = &clk_msr_c3_data,
},
{
.compatible = "amlogic,meson-axg-clk-measure",
@@ -1325,20 +2206,36 @@ static const struct of_device_id meson_msr_match_table[] = {
.data = &clk_msr_g12a_data,
},
{
+ .compatible = "amlogic,meson-gx-clk-measure",
+ .data = &clk_msr_gx_data,
+ },
+ {
.compatible = "amlogic,meson-sm1-clk-measure",
.data = &clk_msr_sm1_data,
},
{
- .compatible = "amlogic,c3-clk-measure",
- .data = &clk_msr_c3_data,
+ .compatible = "amlogic,meson8-clk-measure",
+ .data = &clk_msr_m8_data,
+ },
+ {
+ .compatible = "amlogic,meson8b-clk-measure",
+ .data = &clk_msr_m8_data,
},
{
.compatible = "amlogic,s4-clk-measure",
.data = &clk_msr_s4_data,
},
{
- .compatible = "amlogic,a1-clk-measure",
- .data = &clk_msr_a1_data,
+ .compatible = "amlogic,s6-clk-measure",
+ .data = &clk_msr_s6_data,
+ },
+ {
+ .compatible = "amlogic,s7-clk-measure",
+ .data = &clk_msr_s7_data,
+ },
+ {
+ .compatible = "amlogic,s7d-clk-measure",
+ .data = &clk_msr_s7d_data,
},
{
.compatible = "amlogic,t7-clk-measure",
diff --git a/drivers/soc/apple/rtkit-crashlog.c b/drivers/soc/apple/rtkit-crashlog.c
index 8319e365110b..195b7869ce58 100644
--- a/drivers/soc/apple/rtkit-crashlog.c
+++ b/drivers/soc/apple/rtkit-crashlog.c
@@ -13,7 +13,8 @@
#define APPLE_RTKIT_CRASHLOG_VERSION FOURCC('C', 'v', 'e', 'r')
#define APPLE_RTKIT_CRASHLOG_MBOX FOURCC('C', 'm', 'b', 'x')
#define APPLE_RTKIT_CRASHLOG_TIME FOURCC('C', 't', 'i', 'm')
-#define APPLE_RTKIT_CRASHLOG_REGS FOURCC('C', 'r', 'g', '8')
+#define APPLE_RTKIT_CRASHLOG_AARCH32 FOURCC('C', 'r', 'g', 'A')
+#define APPLE_RTKIT_CRASHLOG_AARCH64 FOURCC('C', 'r', 'g', '8')
/* For COMPILE_TEST on non-ARM64 architectures */
#ifndef PSR_MODE_EL0t
@@ -25,6 +26,21 @@
#define PSR_MODE_MASK 0x0000000f
#endif
+/*
+ * AArch32 mode definitions: APPLE_RTKIT depends on APPLE_MAILBOX, which
+ * depends on 64BIT, so there is no need to care about COMPILE_TEST on ARM.
+ */
+#define USR_MODE 0x00000010
+#define FIQ_MODE 0x00000011
+#define IRQ_MODE 0x00000012
+#define SVC_MODE 0x00000013
+#define MON_MODE 0x00000016
+#define ABT_MODE 0x00000017
+#define HYP_MODE 0x0000001a
+#define UND_MODE 0x0000001b
+#define SYSTEM_MODE 0x0000001f
+#define MODE_MASK_32 0x0000001f
+
struct apple_rtkit_crashlog_header {
u32 fourcc;
u32 version;
@@ -42,7 +58,7 @@ struct apple_rtkit_crashlog_mbox_entry {
};
static_assert(sizeof(struct apple_rtkit_crashlog_mbox_entry) == 0x18);
-struct apple_rtkit_crashlog_regs {
+struct apple_rtkit_crashlog_aarch64 {
u32 unk_0;
u32 unk_4;
u64 regs[31];
@@ -58,7 +74,21 @@ struct apple_rtkit_crashlog_regs {
u64 esr;
u64 unk_Z;
} __packed;
-static_assert(sizeof(struct apple_rtkit_crashlog_regs) == 0x350);
+static_assert(sizeof(struct apple_rtkit_crashlog_aarch64) == 0x350);
+
+struct apple_rtkit_crashlog_aarch32 {
+ u32 unk_0;
+ u32 unk_4;
+ u32 regs[16];
+ u32 psr;
+ u32 unk_x1;
+ u8 stack[0x100];
+ u32 unk_x2;
+ u32 unk_x3;
+ u32 unk_x4;
+ u32 unk_x5;
+} __packed;
+static_assert(sizeof(struct apple_rtkit_crashlog_aarch32) == 0x160);
static void apple_rtkit_crashlog_dump_str(struct apple_rtkit *rtk, u8 *bfr,
size_t size)
@@ -123,21 +153,84 @@ static void apple_rtkit_crashlog_dump_mailbox(struct apple_rtkit *rtk, u8 *bfr,
}
}
-static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr,
- size_t size)
+static void apple_rtkit_crashlog_dump_aarch32(struct apple_rtkit *rtk, u8 *bfr,
+ size_t size)
{
- struct apple_rtkit_crashlog_regs *regs;
+ struct apple_rtkit_crashlog_aarch32 *state;
+ const char *mode;
+ int i;
+
+ if (size < sizeof(*state)) {
+ dev_warn(rtk->dev, "RTKit: AArch32 section too small: 0x%zx", size);
+ return;
+ }
+
+ state = (struct apple_rtkit_crashlog_aarch32 *)bfr;
+
+ switch (state->psr & MODE_MASK_32) {
+ case USR_MODE:
+ mode = "User";
+ break;
+ case FIQ_MODE:
+ mode = "FIQ";
+ break;
+ case IRQ_MODE:
+ mode = "IRQ";
+ break;
+ case SVC_MODE:
+ mode = "Supervisor";
+ break;
+ case MON_MODE:
+ mode = "Monitor";
+ break;
+ case ABT_MODE:
+ mode = "Abort";
+ break;
+ case HYP_MODE:
+ mode = "Hypervisor";
+ break;
+ case UND_MODE:
+ mode = "Undefined";
+ break;
+ case SYSTEM_MODE:
+ mode = "System";
+ break;
+ default:
+ mode = "Unknown";
+ break;
+ }
+
+ dev_warn(rtk->dev, "RTKit: Exception dump:");
+ dev_warn(rtk->dev, " == Exception taken from %s mode ==", mode);
+ dev_warn(rtk->dev, " PSR = 0x%x", state->psr);
+ dev_warn(rtk->dev, "\n");
+
+ for (i = 0; i < 16; i += 4)
+ dev_warn(rtk->dev,
+ " r%02d-r%02d = %08x %08x %08x %08x\n",
+ i, i + 3,
+ state->regs[i], state->regs[i + 1],
+ state->regs[i + 2], state->regs[i + 3]);
+
+ dev_warn(rtk->dev, "\n");
+}
+
+static void apple_rtkit_crashlog_dump_aarch64(struct apple_rtkit *rtk, u8 *bfr,
+ size_t size)
+{
+ struct apple_rtkit_crashlog_aarch64 *state;
const char *el;
int i;
- if (size < sizeof(*regs)) {
- dev_warn(rtk->dev, "RTKit: Regs section too small: 0x%zx", size);
+ if (size < sizeof(*state)) {
+ dev_warn(rtk->dev, "RTKit: AArch64 section too small: 0x%zx",
+ size);
return;
}
- regs = (struct apple_rtkit_crashlog_regs *)bfr;
+ state = (struct apple_rtkit_crashlog_aarch64 *)bfr;
- switch (regs->psr & PSR_MODE_MASK) {
+ switch (state->psr & PSR_MODE_MASK) {
case PSR_MODE_EL0t:
el = "EL0t";
break;
@@ -160,11 +253,11 @@ static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr,
dev_warn(rtk->dev, "RTKit: Exception dump:");
dev_warn(rtk->dev, " == Exception taken from %s ==", el);
- dev_warn(rtk->dev, " PSR = 0x%llx", regs->psr);
- dev_warn(rtk->dev, " PC = 0x%llx\n", regs->pc);
- dev_warn(rtk->dev, " ESR = 0x%llx\n", regs->esr);
- dev_warn(rtk->dev, " FAR = 0x%llx\n", regs->far);
- dev_warn(rtk->dev, " SP = 0x%llx\n", regs->sp);
+ dev_warn(rtk->dev, " PSR = 0x%llx", state->psr);
+ dev_warn(rtk->dev, " PC = 0x%llx\n", state->pc);
+ dev_warn(rtk->dev, " ESR = 0x%llx\n", state->esr);
+ dev_warn(rtk->dev, " FAR = 0x%llx\n", state->far);
+ dev_warn(rtk->dev, " SP = 0x%llx\n", state->sp);
dev_warn(rtk->dev, "\n");
for (i = 0; i < 31; i += 4) {
@@ -172,12 +265,12 @@ static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr,
dev_warn(rtk->dev,
" x%02d-x%02d = %016llx %016llx %016llx %016llx\n",
i, i + 3,
- regs->regs[i], regs->regs[i + 1],
- regs->regs[i + 2], regs->regs[i + 3]);
+ state->regs[i], state->regs[i + 1],
+ state->regs[i + 2], state->regs[i + 3]);
else
dev_warn(rtk->dev,
" x%02d-x%02d = %016llx %016llx %016llx\n", i, i + 3,
- regs->regs[i], regs->regs[i + 1], regs->regs[i + 2]);
+ state->regs[i], state->regs[i + 1], state->regs[i + 2]);
}
dev_warn(rtk->dev, "\n");
@@ -229,9 +322,13 @@ void apple_rtkit_crashlog_dump(struct apple_rtkit *rtk, u8 *bfr, size_t size)
apple_rtkit_crashlog_dump_time(rtk, bfr + offset + 16,
section_size);
break;
- case APPLE_RTKIT_CRASHLOG_REGS:
- apple_rtkit_crashlog_dump_regs(rtk, bfr + offset + 16,
- section_size);
+ case APPLE_RTKIT_CRASHLOG_AARCH32:
+ apple_rtkit_crashlog_dump_aarch32(rtk, bfr + offset + 16,
+ section_size);
+ break;
+ case APPLE_RTKIT_CRASHLOG_AARCH64:
+ apple_rtkit_crashlog_dump_aarch64(rtk, bfr + offset + 16,
+ section_size);
break;
default:
dev_warn(rtk->dev,
diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c
index d89f9dcade7d..7e60c5681ad0 100644
--- a/drivers/soc/atmel/soc.c
+++ b/drivers/soc/atmel/soc.c
@@ -404,9 +404,7 @@ static const struct of_device_id at91_soc_allowed_list[] __initconst = {
static int __init atmel_soc_device_init(void)
{
- struct device_node *np __free(device_node) = of_find_node_by_path("/");
-
- if (!of_match_node(at91_soc_allowed_list, np))
+ if (!of_machine_device_match(at91_soc_allowed_list))
return 0;
at91_soc_init(socs);
diff --git a/drivers/soc/fsl/dpio/dpio-driver.c b/drivers/soc/fsl/dpio/dpio-driver.c
index d5198ffc4455..d8f28fb7c37a 100644
--- a/drivers/soc/fsl/dpio/dpio-driver.c
+++ b/drivers/soc/fsl/dpio/dpio-driver.c
@@ -88,6 +88,7 @@ static void unregister_dpio_irq_handlers(struct fsl_mc_device *dpio_dev)
/* clear the affinity hint */
irq_set_affinity_hint(irq->virq, NULL);
+ devm_free_irq(&dpio_dev->dev, irq->virq, &dpio_dev->dev);
}
static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu)
@@ -244,9 +245,9 @@ static int dpaa2_dpio_probe(struct fsl_mc_device *dpio_dev)
return 0;
-err_dpaa2_io_create:
- unregister_dpio_irq_handlers(dpio_dev);
err_register_dpio_irq:
+ dpaa2_io_down(priv->io);
+err_dpaa2_io_create:
fsl_mc_free_irqs(dpio_dev);
err_allocate_irqs:
dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
@@ -276,10 +277,10 @@ static void dpaa2_dpio_remove(struct fsl_mc_device *dpio_dev)
priv = dev_get_drvdata(dev);
cpu = dpaa2_io_get_cpu(priv->io);
- dpaa2_io_down(priv->io);
-
dpio_teardown_irqs(dpio_dev);
+ dpaa2_io_down(priv->io);
+
cpumask_set_cpu(cpu, cpus_unused_mask);
err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id,
diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c
index 5cd59cfbf22f..1b5a1b134596 100644
--- a/drivers/soc/fsl/qe/gpio.c
+++ b/drivers/soc/fsl/qe/gpio.c
@@ -32,8 +32,13 @@ struct qe_gpio_chip {
/* shadowed data register to clear/set bits safely */
u32 cpdata;
- /* saved_regs used to restore dedicated functions */
- struct qe_pio_regs saved_regs;
+ /* saved regs used to restore dedicated functions */
+ u32 saved_cpodr;
+ u32 saved_cpdata;
+ u32 saved_cpdir1;
+ u32 saved_cpdir2;
+ u32 saved_cppar1;
+ u32 saved_cppar2;
};
static void qe_gpio_save_regs(struct qe_gpio_chip *qe_gc)
@@ -41,12 +46,12 @@ static void qe_gpio_save_regs(struct qe_gpio_chip *qe_gc)
struct qe_pio_regs __iomem *regs = qe_gc->regs;
qe_gc->cpdata = ioread32be(&regs->cpdata);
- qe_gc->saved_regs.cpdata = qe_gc->cpdata;
- qe_gc->saved_regs.cpdir1 = ioread32be(&regs->cpdir1);
- qe_gc->saved_regs.cpdir2 = ioread32be(&regs->cpdir2);
- qe_gc->saved_regs.cppar1 = ioread32be(&regs->cppar1);
- qe_gc->saved_regs.cppar2 = ioread32be(&regs->cppar2);
- qe_gc->saved_regs.cpodr = ioread32be(&regs->cpodr);
+ qe_gc->saved_cpdata = qe_gc->cpdata;
+ qe_gc->saved_cpdir1 = ioread32be(&regs->cpdir1);
+ qe_gc->saved_cpdir2 = ioread32be(&regs->cpdir2);
+ qe_gc->saved_cppar1 = ioread32be(&regs->cppar1);
+ qe_gc->saved_cppar2 = ioread32be(&regs->cppar2);
+ qe_gc->saved_cpodr = ioread32be(&regs->cpodr);
}
static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
@@ -196,18 +201,17 @@ struct qe_pin {
/**
* qe_pin_request - Request a QE pin
* @dev: device to get the pin from
- * @index: index of the pin in the device tree
+ * @gpiod: GPIO descriptor associated with this pin
* Context: non-atomic
*
* This function return qe_pin so that you could use it with the rest of
* the QE Pin Multiplexing API.
*/
-struct qe_pin *qe_pin_request(struct device *dev, int index)
+struct qe_pin *qe_pin_request(struct device *dev, struct gpio_desc *gpiod)
{
+ struct gpio_device *gdev;
struct qe_pin *qe_pin;
struct gpio_chip *gc;
- struct gpio_desc *gpiod;
- int gpio_num;
int err;
qe_pin = kzalloc_obj(*qe_pin);
@@ -216,34 +220,20 @@ struct qe_pin *qe_pin_request(struct device *dev, int index)
return ERR_PTR(-ENOMEM);
}
- /*
- * Request gpio as nonexclusive as it was likely reserved by the
- * caller, and we are not planning on controlling it, we only need
- * the descriptor to the to the gpio chip structure.
- */
- gpiod = gpiod_get_index(dev, NULL, index,
- GPIOD_ASIS | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
- err = PTR_ERR_OR_ZERO(gpiod);
- if (err)
- goto err0;
-
- gc = gpiod_to_chip(gpiod);
- gpio_num = desc_to_gpio(gpiod);
- /* We no longer need this descriptor */
- gpiod_put(gpiod);
-
- if (WARN_ON(!gc)) {
+ gdev = gpiod_to_gpio_device(gpiod);
+ if (WARN_ON(!gdev)) {
err = -ENODEV;
goto err0;
}
+ gc = gpio_device_get_chip(gdev);
qe_pin->controller = gpiochip_get_data(gc);
/*
* FIXME: this gets the local offset on the gpio_chip so that the driver
* can manipulate pin control settings through its custom API. The real
* solution is to create a real pin control driver for this.
*/
- qe_pin->num = gpio_num - gc->base;
+ qe_pin->num = desc_to_gpio(gpiod) - gc->base;
if (!fwnode_device_is_compatible(gc->fwnode, "fsl,mpc8323-qe-pario-bank")) {
dev_dbg(dev, "%s: tried to get a non-qe pin\n", __func__);
@@ -284,7 +274,6 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin)
{
struct qe_gpio_chip *qe_gc = qe_pin->controller;
struct qe_pio_regs __iomem *regs = qe_gc->regs;
- struct qe_pio_regs *sregs = &qe_gc->saved_regs;
int pin = qe_pin->num;
u32 mask1 = 1 << (QE_PIO_PINS - (pin + 1));
u32 mask2 = 0x3 << (QE_PIO_PINS - (pin % (QE_PIO_PINS / 2) + 1) * 2);
@@ -294,24 +283,20 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin)
spin_lock_irqsave(&qe_gc->lock, flags);
if (second_reg) {
- qe_clrsetbits_be32(&regs->cpdir2, mask2,
- sregs->cpdir2 & mask2);
- qe_clrsetbits_be32(&regs->cppar2, mask2,
- sregs->cppar2 & mask2);
+ qe_clrsetbits_be32(&regs->cpdir2, mask2, qe_gc->saved_cpdir2 & mask2);
+ qe_clrsetbits_be32(&regs->cppar2, mask2, qe_gc->saved_cppar2 & mask2);
} else {
- qe_clrsetbits_be32(&regs->cpdir1, mask2,
- sregs->cpdir1 & mask2);
- qe_clrsetbits_be32(&regs->cppar1, mask2,
- sregs->cppar1 & mask2);
+ qe_clrsetbits_be32(&regs->cpdir1, mask2, qe_gc->saved_cpdir1 & mask2);
+ qe_clrsetbits_be32(&regs->cppar1, mask2, qe_gc->saved_cppar1 & mask2);
}
- if (sregs->cpdata & mask1)
+ if (qe_gc->saved_cpdata & mask1)
qe_gc->cpdata |= mask1;
else
qe_gc->cpdata &= ~mask1;
iowrite32be(qe_gc->cpdata, &regs->cpdata);
- qe_clrsetbits_be32(&regs->cpodr, mask1, sregs->cpodr & mask1);
+ qe_clrsetbits_be32(&regs->cpodr, mask1, qe_gc->saved_cpodr & mask1);
spin_unlock_irqrestore(&qe_gc->lock, flags);
}
EXPORT_SYMBOL(qe_pin_set_dedicated);
diff --git a/drivers/soc/fsl/qe/tsa.c b/drivers/soc/fsl/qe/tsa.c
index 4a88e54d25b9..502e2ffe8689 100644
--- a/drivers/soc/fsl/qe/tsa.c
+++ b/drivers/soc/fsl/qe/tsa.c
@@ -865,12 +865,12 @@ err:
clk_put(tsa->tdm[i].l1rclk_clk);
}
if (tsa->tdm[i].l1tsync_clk) {
- clk_disable_unprepare(tsa->tdm[i].l1rsync_clk);
- clk_put(tsa->tdm[i].l1rsync_clk);
+ clk_disable_unprepare(tsa->tdm[i].l1tsync_clk);
+ clk_put(tsa->tdm[i].l1tsync_clk);
}
if (tsa->tdm[i].l1tclk_clk) {
- clk_disable_unprepare(tsa->tdm[i].l1rclk_clk);
- clk_put(tsa->tdm[i].l1rclk_clk);
+ clk_disable_unprepare(tsa->tdm[i].l1tclk_clk);
+ clk_put(tsa->tdm[i].l1tclk_clk);
}
}
return ret;
@@ -1039,12 +1039,12 @@ static void tsa_remove(struct platform_device *pdev)
clk_put(tsa->tdm[i].l1rclk_clk);
}
if (tsa->tdm[i].l1tsync_clk) {
- clk_disable_unprepare(tsa->tdm[i].l1rsync_clk);
- clk_put(tsa->tdm[i].l1rsync_clk);
+ clk_disable_unprepare(tsa->tdm[i].l1tsync_clk);
+ clk_put(tsa->tdm[i].l1tsync_clk);
}
if (tsa->tdm[i].l1tclk_clk) {
- clk_disable_unprepare(tsa->tdm[i].l1rclk_clk);
- clk_put(tsa->tdm[i].l1rclk_clk);
+ clk_disable_unprepare(tsa->tdm[i].l1tclk_clk);
+ clk_put(tsa->tdm[i].l1tclk_clk);
}
}
}
diff --git a/drivers/soc/mediatek/mt8167-mmsys.h b/drivers/soc/mediatek/mt8167-mmsys.h
index 001379373507..858779ace895 100644
--- a/drivers/soc/mediatek/mt8167-mmsys.h
+++ b/drivers/soc/mediatek/mt8167-mmsys.h
@@ -5,35 +5,200 @@
#define MT8167_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN 0x030
#define MT8167_DISP_REG_CONFIG_DISP_DITHER_MOUT_EN 0x038
+#define MT8167_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN 0x03c
#define MT8167_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN 0x058
+#define MT8167_DISP_REG_CONFIG_DISP_WDMA0_SEL_IN 0x05c
+#define MT8167_DISP_REG_CONFIG_DISP_UFOE_SEL_IN 0x060
#define MT8167_DISP_REG_CONFIG_DISP_DSI0_SEL_IN 0x064
+#define MT8167_DISP_REG_CONFIG_DISP_DPI0_SEL_IN 0x068
#define MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN 0x06c
+#define MT8167_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL_IN 0x070
+#define MT8167_DISP_REG_CONFIG_DISP_DPI1_SEL_IN 0x074
+
+#define MT8167_OVL0_MOUT_EN_COLOR0 0x1
+#define MT8167_OVL0_MOUT_EN_WDMA0 0x2
+#define MT8167_OVL0_MOUT_EN_MASK 0x3
#define MT8167_DITHER_MOUT_EN_RDMA0 0x1
+#define MT8167_DITHER_MOUT_EN_UFOE 0x2
+#define MT8167_DITHER_MOUT_EN_WDMA0 0x4
#define MT8167_DITHER_MOUT_EN_MASK 0x7
-#define MT8167_RDMA0_SOUT_DSI0 0x2
-#define MT8167_RDMA0_SOUT_MASK 0x3
+#define MT8167_UFOE_MOUT_EN_DSI0 0x1
+#define MT8167_UFOE_MOUT_EN_DPI0 0x2
+/*
+ * For some reason Android sources and the data sheet don't agree here,
+ * the data sheet has UFOE_MOUT_EN_WDMA0 as 0x4 and does not mention DPI1.
+ */
+#define MT8167_UFOE_MOUT_EN_DPI1 0x4
+#define MT8167_UFOE_MOUT_EN_WDMA0 0x8
+#define MT8167_UFOE_MOUT_EN_MASK 0xF
+
+#define MT8167_COLOR0_SEL_IN_RDMA0 0x0
+#define MT8167_COLOR0_SEL_IN_OVL0 0x1
+#define MT8167_COLOR0_SEL_IN_MASK 0x1
+
+#define MT8167_WDMA0_SEL_IN_OVL0 0x0
+#define MT8167_WDMA0_SEL_IN_DITHER 0x1
+#define MT8167_WDMA0_SEL_IN_UFOE 0x2
+#define MT8167_WDMA0_SEL_IN_MASK 0x3
+
+#define MT8167_UFOE_SEL_IN_RDMA0 0x0
+#define MT8167_UFOE_SEL_IN_DITHER 0x1
+#define MT8167_UFOE_SEL_IN_MASK 0x1
+#define MT8167_DSI0_SEL_IN_UFOE 0x0
#define MT8167_DSI0_SEL_IN_RDMA0 0x1
+#define MT8167_DSI0_SEL_IN_RDMA1 0x2
#define MT8167_DSI0_SEL_IN_MASK 0x3
+#define MT8167_DPI0_SEL_IN_UFOE 0x0
+#define MT8167_DPI0_SEL_IN_RDMA0 0x1
+#define MT8167_DPI0_SEL_IN_RDMA1 0x2
+#define MT8167_DPI0_SEL_IN_MASK 0x3
+
+#define MT8167_DPI1_SEL_IN_UFOE 0x0
+#define MT8167_DPI1_SEL_IN_RDMA0 0x1
+#define MT8167_DPI1_SEL_IN_RDMA1 0x2
+#define MT8167_DPI1_SEL_IN_MASK 0x3
+
+#define MT8167_RDMA0_SOUT_UFOE 0x0
+#define MT8167_RDMA0_SOUT_COLOR0 0x1
+#define MT8167_RDMA0_SOUT_DSI0 0x2
+#define MT8167_RDMA0_SOUT_DPI0 0x3
+/* DPI1 is only defined in Android sources, not in the data sheet */
+#define MT8167_RDMA0_SOUT_DPI1 0x4
+#define MT8167_RDMA0_SOUT_MASK 0x7
+
+#define MT8167_RDMA1_SOUT_DSI0 0x0
+#define MT8167_RDMA1_SOUT_DPI0 0x1
+/* DPI1 is only defined in Android sources, not in the data sheet */
+#define MT8167_RDMA1_SOUT_DPI1 0x2
+#define MT8167_RDMA1_SOUT_MASK 0x3
+
static const struct mtk_mmsys_routes mt8167_mmsys_routing_table[] = {
+ /* OVL0<->COLOR0 */
MMSYS_ROUTE(OVL, 0, COLOR, 0,
- MT8167_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, OVL0_MOUT_EN_COLOR0,
- OVL0_MOUT_EN_COLOR0),
+ MT8167_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, MT8167_OVL0_MOUT_EN_MASK,
+ MT8167_OVL0_MOUT_EN_COLOR0),
+ MMSYS_ROUTE(OVL, 0, COLOR, 0,
+ MT8167_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, MT8167_COLOR0_SEL_IN_MASK,
+ MT8167_COLOR0_SEL_IN_OVL0),
+
+ /* OVL0<->WDMA0 */
+ MMSYS_ROUTE(OVL, 0, WDMA, 0,
+ MT8167_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, MT8167_OVL0_MOUT_EN_MASK,
+ MT8167_OVL0_MOUT_EN_WDMA0),
+ MMSYS_ROUTE(OVL, 0, WDMA, 0,
+ MT8167_DISP_REG_CONFIG_DISP_WDMA0_SEL_IN, MT8167_COLOR0_SEL_IN_MASK,
+ MT8167_WDMA0_SEL_IN_OVL0),
+
+ /* DITHER0 outputs */
MMSYS_ROUTE(DITHER, 0, RDMA, 0,
MT8167_DISP_REG_CONFIG_DISP_DITHER_MOUT_EN, MT8167_DITHER_MOUT_EN_MASK,
MT8167_DITHER_MOUT_EN_RDMA0),
- MMSYS_ROUTE(OVL, 0, COLOR, 0,
- MT8167_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, COLOR0_SEL_IN_OVL0,
- COLOR0_SEL_IN_OVL0),
- MMSYS_ROUTE(RDMA, 0, DSI, 0,
+ MMSYS_ROUTE(DITHER, 0, UFOE, 0,
+ MT8167_DISP_REG_CONFIG_DISP_DITHER_MOUT_EN, MT8167_DITHER_MOUT_EN_MASK,
+ MT8167_DITHER_MOUT_EN_UFOE),
+ MMSYS_ROUTE(DITHER, 0, WDMA, 0,
+ MT8167_DISP_REG_CONFIG_DISP_DITHER_MOUT_EN, MT8167_DITHER_MOUT_EN_MASK,
+ MT8167_DITHER_MOUT_EN_WDMA0),
+
+ /* UFOE<->DSI0 */
+ MMSYS_ROUTE(UFOE, 0, DSI, 0,
+ MT8167_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN, MT8167_UFOE_MOUT_EN_MASK,
+ MT8167_UFOE_MOUT_EN_DSI0),
+ MMSYS_ROUTE(UFOE, 0, DSI, 0,
MT8167_DISP_REG_CONFIG_DISP_DSI0_SEL_IN, MT8167_DSI0_SEL_IN_MASK,
- MT8167_DSI0_SEL_IN_RDMA0),
+ MT8167_DSI0_SEL_IN_UFOE),
+
+ /* UFOE<->DPI0 */
+ MMSYS_ROUTE(UFOE, 0, DPI, 0,
+ MT8167_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN, MT8167_UFOE_MOUT_EN_MASK,
+ MT8167_UFOE_MOUT_EN_DPI0),
+ MMSYS_ROUTE(UFOE, 0, DPI, 0,
+ MT8167_DISP_REG_CONFIG_DISP_DPI0_SEL_IN, MT8167_DPI0_SEL_IN_MASK,
+ MT8167_DPI0_SEL_IN_UFOE),
+
+ /* UFOE<->DPI1 */
+ MMSYS_ROUTE(UFOE, 0, DPI, 1,
+ MT8167_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN, MT8167_UFOE_MOUT_EN_MASK,
+ MT8167_UFOE_MOUT_EN_DPI1),
+ MMSYS_ROUTE(UFOE, 0, DPI, 1,
+ MT8167_DISP_REG_CONFIG_DISP_DPI1_SEL_IN, MT8167_DPI1_SEL_IN_MASK,
+ MT8167_DPI1_SEL_IN_UFOE),
+
+ /* UFOE<->WDMA0 */
+ MMSYS_ROUTE(UFOE, 0, WDMA, 0,
+ MT8167_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN, MT8167_UFOE_MOUT_EN_MASK,
+ MT8167_UFOE_MOUT_EN_WDMA0),
+ MMSYS_ROUTE(UFOE, 0, WDMA, 0,
+ MT8167_DISP_REG_CONFIG_DISP_WDMA0_SEL_IN, MT8167_WDMA0_SEL_IN_MASK,
+ MT8167_WDMA0_SEL_IN_UFOE),
+
+ /* RDMA0<->UFOE */
+ MMSYS_ROUTE(RDMA, 0, UFOE, 0,
+ MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_MASK,
+ MT8167_RDMA0_SOUT_UFOE),
+ MMSYS_ROUTE(RDMA, 0, UFOE, 0,
+ MT8167_DISP_REG_CONFIG_DISP_UFOE_SEL_IN, MT8167_UFOE_SEL_IN_MASK,
+ MT8167_UFOE_SEL_IN_RDMA0),
+
+ /* RDMA0->COLOR0 */
+ MMSYS_ROUTE(RDMA, 0, COLOR, 0,
+ MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_MASK,
+ MT8167_RDMA0_SOUT_COLOR0),
+ MMSYS_ROUTE(RDMA, 0, COLOR, 0,
+ MT8167_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, MT8167_COLOR0_SEL_IN_MASK,
+ MT8167_COLOR0_SEL_IN_RDMA0),
+
+ /* RDMA0<->DSI0 */
MMSYS_ROUTE(RDMA, 0, DSI, 0,
MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_MASK,
MT8167_RDMA0_SOUT_DSI0),
+ MMSYS_ROUTE(RDMA, 0, DSI, 0,
+ MT8167_DISP_REG_CONFIG_DISP_DSI0_SEL_IN, MT8167_DSI0_SEL_IN_MASK,
+ MT8167_DSI0_SEL_IN_RDMA0),
+
+ /* RDMA0<->DPI0 */
+ MMSYS_ROUTE(RDMA, 0, DPI, 0,
+ MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_MASK,
+ MT8167_RDMA0_SOUT_DPI0),
+ MMSYS_ROUTE(RDMA, 0, DPI, 0,
+ MT8167_DISP_REG_CONFIG_DISP_DPI0_SEL_IN, MT8167_DPI0_SEL_IN_MASK,
+ MT8167_DPI0_SEL_IN_RDMA0),
+
+ /* RDMA0<->DPI1 */
+ MMSYS_ROUTE(RDMA, 0, DPI, 1,
+ MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_MASK,
+ MT8167_RDMA0_SOUT_DPI1),
+ MMSYS_ROUTE(RDMA, 0, DPI, 1,
+ MT8167_DISP_REG_CONFIG_DISP_DPI1_SEL_IN, MT8167_DPI1_SEL_IN_MASK,
+ MT8167_DPI1_SEL_IN_RDMA0),
+
+ /* RDMA1<->DSI0 */
+ MMSYS_ROUTE(RDMA, 1, DSI, 0,
+ MT8167_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL_IN, MT8167_RDMA1_SOUT_MASK,
+ MT8167_RDMA1_SOUT_DSI0),
+ MMSYS_ROUTE(RDMA, 1, DSI, 0,
+ MT8167_DISP_REG_CONFIG_DISP_DSI0_SEL_IN, MT8167_DSI0_SEL_IN_MASK,
+ MT8167_DSI0_SEL_IN_RDMA1),
+
+ /* RDMA1<->DPI0 */
+ MMSYS_ROUTE(RDMA, 1, DPI, 0,
+ MT8167_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL_IN, MT8167_RDMA1_SOUT_MASK,
+ MT8167_RDMA1_SOUT_DPI0),
+ MMSYS_ROUTE(RDMA, 1, DPI, 0,
+ MT8167_DISP_REG_CONFIG_DISP_DPI0_SEL_IN, MT8167_DPI0_SEL_IN_MASK,
+ MT8167_DPI0_SEL_IN_RDMA1),
+
+ /* RDMA1<->DPI1 */
+ MMSYS_ROUTE(RDMA, 1, DPI, 1,
+ MT8167_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL_IN, MT8167_RDMA1_SOUT_MASK,
+ MT8167_RDMA1_SOUT_DPI1),
+ MMSYS_ROUTE(RDMA, 1, DPI, 1,
+ MT8167_DISP_REG_CONFIG_DISP_DPI1_SEL_IN, MT8167_DPI1_SEL_IN_MASK,
+ MT8167_DPI1_SEL_IN_RDMA1),
};
#endif /* __SOC_MEDIATEK_MT8167_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-regulator-coupler.c b/drivers/soc/mediatek/mtk-regulator-coupler.c
index 0b6a2884145e..1109e3d9a319 100644
--- a/drivers/soc/mediatek/mtk-regulator-coupler.c
+++ b/drivers/soc/mediatek/mtk-regulator-coupler.c
@@ -148,6 +148,7 @@ static int mediatek_regulator_coupler_init(void)
if (!of_machine_is_compatible("mediatek,mt8183") &&
!of_machine_is_compatible("mediatek,mt8186") &&
!of_machine_is_compatible("mediatek,mt8188") &&
+ !of_machine_is_compatible("mediatek,mt8189") &&
!of_machine_is_compatible("mediatek,mt8192"))
return 0;
diff --git a/drivers/soc/microchip/mpfs-sys-controller.c b/drivers/soc/microchip/mpfs-sys-controller.c
index 0400a01b2338..ef27e1083f0f 100644
--- a/drivers/soc/microchip/mpfs-sys-controller.c
+++ b/drivers/soc/microchip/mpfs-sys-controller.c
@@ -159,7 +159,7 @@ no_flash:
of_data = (struct mpfs_syscon_config *) device_get_match_data(dev);
if (!of_data) {
ret = dev_err_probe(dev, -EINVAL, "Error getting match data\n");
- goto out_free_channel;
+ goto out_put;
}
for (i = 0; i < of_data->nb_subdevs; i++) {
@@ -173,8 +173,9 @@ no_flash:
return 0;
-out_free_channel:
- mbox_free_channel(sys_controller->chan);
+out_put:
+ mpfs_sys_controller_put(sys_controller);
+ return ret;
out_free:
kfree(sys_controller);
return ret;
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 2b524154d9fb..9f703261d7ac 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -39,7 +39,6 @@ config QCOM_COMMAND_DB
config QCOM_GENI_SE
tristate "Qualcomm GENI Serial Engine Driver"
- depends on ARM64 || COMPILE_TEST
default ARCH_QCOM
help
This driver is used to manage Generic Interface (GENI) firmware based
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
index ea7f83916d8d..2d5645ff9919 100644
--- a/drivers/soc/qcom/apr.c
+++ b/drivers/soc/qcom/apr.c
@@ -338,29 +338,6 @@ static void apr_rxwq(struct work_struct *work)
}
}
-static int apr_device_match(struct device *dev, const struct device_driver *drv)
-{
- struct apr_device *adev = to_apr_device(dev);
- const struct apr_driver *adrv = to_apr_driver(drv);
- const struct apr_device_id *id = adrv->id_table;
-
- /* Attempt an OF style match first */
- if (of_driver_match_device(dev, drv))
- return 1;
-
- if (!id)
- return 0;
-
- while (id->domain_id != 0 || id->svc_id != 0) {
- if (id->domain_id == adev->domain_id &&
- id->svc_id == adev->svc.id)
- return 1;
- id++;
- }
-
- return 0;
-}
-
static int apr_device_probe(struct device *dev)
{
struct apr_device *adev = to_apr_device(dev);
@@ -401,7 +378,7 @@ static int apr_uevent(const struct device *dev, struct kobj_uevent_env *env)
const struct bus_type aprbus = {
.name = "aprbus",
- .match = apr_device_match,
+ .match = of_driver_match_device,
.probe = apr_device_probe,
.uevent = apr_uevent,
.remove = apr_device_remove,
@@ -434,31 +411,35 @@ static int apr_add_device(struct device *dev, struct device_node *np,
if (np)
snprintf(adev->name, APR_NAME_SIZE, "%pOFn", np);
+ adev->dev.bus = &aprbus;
+ adev->dev.parent = dev;
+ adev->dev.of_node = np;
+ adev->dev.release = apr_dev_release;
+ adev->dev.driver = NULL;
+ device_initialize(&adev->dev);
+
switch (apr->type) {
case PR_TYPE_APR:
- dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
- domain_id, svc_id);
+ ret = dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
+ domain_id, svc_id);
break;
case PR_TYPE_GPR:
- dev_set_name(&adev->dev, "gprsvc:%s:%x:%x", adev->name,
- domain_id, svc_id);
+ ret = dev_set_name(&adev->dev, "gprsvc:%s:%x:%x", adev->name,
+ domain_id, svc_id);
break;
default:
+ ret = -EINVAL;
break;
}
-
- adev->dev.bus = &aprbus;
- adev->dev.parent = dev;
- adev->dev.of_node = np;
- adev->dev.release = apr_dev_release;
- adev->dev.driver = NULL;
+ if (ret)
+ goto out_put_device;
spin_lock(&apr->svcs_lock);
ret = idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
spin_unlock(&apr->svcs_lock);
if (ret < 0) {
dev_err(dev, "idr_alloc failed: %d\n", ret);
- goto out;
+ goto out_put_device;
}
/* Protection domain is optional, it does not exist on older platforms */
@@ -466,18 +447,26 @@ static int apr_add_device(struct device *dev, struct device_node *np,
1, &adev->service_path);
if (ret < 0 && ret != -EINVAL) {
dev_err(dev, "Failed to read second value of qcom,protection-domain\n");
- goto out;
+ goto out_remove_idr;
}
dev_info(dev, "Adding APR/GPR dev: %s\n", dev_name(&adev->dev));
- ret = device_register(&adev->dev);
+ ret = device_add(&adev->dev);
if (ret) {
- dev_err(dev, "device_register failed: %d\n", ret);
- put_device(&adev->dev);
+ dev_err(dev, "device_add failed: %d\n", ret);
+ goto out_remove_idr;
}
-out:
+ return 0;
+
+out_remove_idr:
+ spin_lock(&apr->svcs_lock);
+ idr_remove(&apr->svcs_idr, svc_id);
+ spin_unlock(&apr->svcs_lock);
+ flush_workqueue(apr->rxwq);
+out_put_device:
+ put_device(&adev->dev);
return ret;
}
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index 733999867bbf..d7a42a8040a1 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -626,11 +626,11 @@ static const struct llcc_slice_config glymur_data[] = {
static const struct llcc_slice_config ipq5424_data[] = {
{
- .usecase_id = LLCC_CPUSS,
+ .usecase_id = LLCC_PPE_RXDESC,
.slice_id = 1,
- .max_cap = 768,
- .priority = 1,
- .bonus_ways = 0xFFFF,
+ .max_cap = 128,
+ .priority = 3,
+ .bonus_ways = 0x0FFF,
.retain_on_pc = true,
.activate_on_init = true,
.write_scid_cacheable_en = true,
@@ -642,12 +642,52 @@ static const struct llcc_slice_config ipq5424_data[] = {
.vict_prio = true,
},
{
- .usecase_id = LLCC_VIDSC0,
+ .usecase_id = LLCC_CPUSS,
.slice_id = 2,
- .max_cap = 256,
- .priority = 2,
+ .max_cap = 768,
+ .priority = 1,
.fixed_size = true,
- .bonus_ways = 0xF000,
+ .bonus_ways = 0x0FFF,
+ .retain_on_pc = true,
+ .activate_on_init = true,
+ .write_scid_cacheable_en = true,
+ .stale_en = true,
+ .stale_cap_en = true,
+ },
+ {
+ .usecase_id = LLCC_PPE_RXFILL,
+ .slice_id = 5,
+ .max_cap = 128,
+ .priority = 3,
+ .bonus_ways = 0x0FFF,
+ .retain_on_pc = true,
+ .activate_on_init = true,
+ .write_scid_cacheable_en = true,
+ .stale_en = true,
+ .stale_cap_en = true,
+ .alloc_oneway_en = true,
+ .ovcap_en = true,
+ .ovcap_prio = true,
+ .vict_prio = true,
+ },
+ {
+ .usecase_id = LLCC_WLAN_5G,
+ .slice_id = 6,
+ .max_cap = 128,
+ .priority = 3,
+ .bonus_ways = 0xC000,
+ .retain_on_pc = true,
+ .activate_on_init = true,
+ .write_scid_cacheable_en = true,
+ .stale_en = true,
+ .stale_cap_en = true,
+ },
+ {
+ .usecase_id = LLCC_WLAN_6G,
+ .slice_id = 7,
+ .max_cap = 128,
+ .priority = 3,
+ .bonus_ways = 0x3000,
.retain_on_pc = true,
.activate_on_init = true,
.write_scid_cacheable_en = true,
@@ -1014,6 +1054,128 @@ static const struct llcc_slice_config kaanapali_data[] = {
},
};
+static const struct llcc_slice_config nord_data[] = {
+ {
+ .usecase_id = LLCC_CPUSS,
+ .slice_id = 1,
+ .max_cap = 3072,
+ .priority = 0,
+ .bonus_ways = 0xff,
+ .activate_on_init = true,
+ .write_scid_en = true,
+ .write_scid_cacheable_en = true,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_CMPT,
+ .slice_id = 34,
+ .max_cap = 0,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_GPUHTW,
+ .slice_id = 11,
+ .max_cap = 512,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_GPU,
+ .slice_id = 12,
+ .max_cap = 2048,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .write_scid_en = true,
+ .write_scid_cacheable_en = true,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_MMUHWT,
+ .slice_id = 13,
+ .max_cap = 1024,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .activate_on_init = true,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_CAMFW,
+ .slice_id = 20,
+ .max_cap = 512,
+ .priority = 2,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_ECC,
+ .slice_id = 26,
+ .max_cap = 1536,
+ .priority = 3,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .activate_on_init = true,
+ .write_scid_en = true,
+ .write_scid_cacheable_en = true,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_WRCACHE,
+ .slice_id = 31,
+ .max_cap = 2048,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .activate_on_init = true,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_LCPDARE,
+ .slice_id = 30,
+ .max_cap = 512,
+ .priority = 3,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .activate_on_init = true,
+ .alloc_oneway_en = true,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_COMPUTE1,
+ .slice_id = 22,
+ .max_cap = 0,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_PCIE_TCU,
+ .slice_id = 15,
+ .max_cap = 0,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .activate_on_init = true,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_GPU_LITTLE,
+ .slice_id = 9,
+ .max_cap = 2048,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .write_scid_en = true,
+ .write_scid_cacheable_en = true,
+ .vict_prio = true,
+ }, {
+ .usecase_id = LLCC_GPUHTW_LITTLE,
+ .slice_id = 14,
+ .max_cap = 512,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0xff,
+ .vict_prio = true,
+ },
+};
+
static const struct llcc_slice_config sa8775p_data[] = {
{
.usecase_id = LLCC_CPUSS,
@@ -4444,6 +4606,17 @@ static const struct qcom_llcc_config glymur_cfg[] = {
},
};
+static const struct qcom_llcc_config nord_cfg[] = {
+ {
+ .sct_data = nord_data,
+ .size = ARRAY_SIZE(nord_data),
+ .reg_offset = llcc_v6_reg_offset,
+ .edac_reg_offset = &llcc_v6_edac_reg_offset,
+ .num_banks = 16,
+ .no_edac = true,
+ },
+};
+
static const struct qcom_llcc_config qcs615_cfg[] = {
{
.sct_data = qcs615_data,
@@ -4711,6 +4884,11 @@ static const struct qcom_sct_config glymur_cfgs = {
.num_config = ARRAY_SIZE(glymur_cfg),
};
+static const struct qcom_sct_config nord_cfgs = {
+ .llcc_config = nord_cfg,
+ .num_config = ARRAY_SIZE(nord_cfg),
+};
+
static const struct qcom_sct_config qcs615_cfgs = {
.llcc_config = qcs615_cfg,
.num_config = ARRAY_SIZE(qcs615_cfg),
@@ -5617,6 +5795,10 @@ static int qcom_llcc_probe(struct platform_device *pdev)
}
drv_data->ecc_irq = platform_get_irq_optional(pdev, 0);
+ if (drv_data->ecc_irq < 0 && drv_data->ecc_irq != -ENXIO)
+ return dev_err_probe(&pdev->dev, drv_data->ecc_irq,
+ "failed to get IRQ resource\n");
+
drv_data->edac_reg_offset = cfg->edac_reg_offset;
drv_data->ecc_irq_configured = cfg->irq_configured;
drv_data->dev = dev;
@@ -5649,6 +5831,7 @@ static const struct of_device_id qcom_llcc_of_match[] = {
{ .compatible = "qcom,hawi-llcc", .data = &hawi_sct_cfgs },
{ .compatible = "qcom,ipq5424-llcc", .data = &ipq5424_cfgs},
{ .compatible = "qcom,kaanapali-llcc", .data = &kaanapali_cfgs},
+ { .compatible = "qcom,nord-llcc", .data = &nord_cfgs},
{ .compatible = "qcom,qcs615-llcc", .data = &qcs615_cfgs},
{ .compatible = "qcom,qcs8300-llcc", .data = &qcs8300_cfgs},
{ .compatible = "qcom,qdu1000-llcc", .data = &qdu1000_cfgs},
diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c
index 3042261578aa..84fd0c82c0c4 100644
--- a/drivers/soc/qcom/pmic_glink.c
+++ b/drivers/soc/qcom/pmic_glink.c
@@ -250,7 +250,8 @@ static int pmic_glink_rpmsg_probe(struct rpmsg_device *rpdev)
guard(mutex)(&__pmic_glink_lock);
pg = __pmic_glink;
if (!pg)
- return dev_err_probe(&rpdev->dev, -ENODEV, "no pmic_glink device to attach to\n");
+ return dev_err_probe(&rpdev->dev, -EPROBE_DEFER,
+ "no pmic_glink device to attach to\n");
dev_set_drvdata(&rpdev->dev, pg);
pg->pdr_available = rpdev->id.driver_data;
diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c
index 13c434f8d03a..465e5d2316a0 100644
--- a/drivers/soc/qcom/pmic_glink_altmode.c
+++ b/drivers/soc/qcom/pmic_glink_altmode.c
@@ -451,7 +451,7 @@ static void pmic_glink_altmode_sc8180xp_notify(struct pmic_glink_altmode *altmod
alt_port->mode = mode;
alt_port->hpd_state = hpd_state;
alt_port->hpd_irq = hpd_irq;
- schedule_work(&alt_port->work);
+ queue_work(system_freezable_wq, &alt_port->work);
}
#define SC8280XP_DPAM_MASK 0x3f
@@ -502,7 +502,7 @@ static void pmic_glink_altmode_sc8280xp_notify(struct pmic_glink_altmode *altmod
alt_port->tbt_data = *tbt;
}
- schedule_work(&alt_port->work);
+ queue_work(system_freezable_wq, &alt_port->work);
}
static void pmic_glink_altmode_callback(const void *data, size_t len, void *priv)
diff --git a/drivers/soc/qcom/pmic_pdcharger_ulog.c b/drivers/soc/qcom/pmic_pdcharger_ulog.c
index 39f412bbf2c1..06cd9c4411c2 100644
--- a/drivers/soc/qcom/pmic_pdcharger_ulog.c
+++ b/drivers/soc/qcom/pmic_pdcharger_ulog.c
@@ -143,7 +143,7 @@ static void pmic_pdcharger_ulog_rpmsg_remove(struct rpmsg_device *rpdev)
{
struct pmic_pdcharger_ulog *pg = dev_get_drvdata(&rpdev->dev);
- cancel_delayed_work_sync(&pg->ulog_work);
+ disable_delayed_work_sync(&pg->ulog_work);
}
static const struct rpmsg_device_id pmic_pdcharger_ulog_rpmsg_id_match[] = {
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 873bfbd6b2b7..074087c592cc 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -42,7 +42,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(geni_se_regs);
*
* GENI based QUP is a highly-flexible and programmable module for supporting
* a wide range of serial interfaces like UART, SPI, I2C, I3C, etc. A single
- * QUP module can provide upto 8 serial interfaces, using its internal
+ * QUP module can provide up to 8 serial interfaces, using its internal
* serial engines. The actual configuration is determined by the target
* platform configuration. The protocol supported by each interface is
* determined by the firmware loaded to the serial engine. Each SE consists
@@ -101,22 +101,26 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(geni_se_regs);
* @base: Base address of this instance of QUP wrapper core
* @clks: Handle to the primary & optional secondary AHB clocks
* @num_clks: Count of clocks
+ * @prog_ram_depth: Available CFG RAM depth for instance without SE_HW_PARAM_2
*/
struct geni_wrapper {
struct device *dev;
void __iomem *base;
struct clk_bulk_data clks[MAX_CLKS];
unsigned int num_clks;
+ unsigned int prog_ram_depth;
};
/**
* struct geni_se_desc - Data structure to represent the QUP Wrapper resources
* @clks: Name of the primary & optional secondary AHB clocks
* @num_clks: Count of clock names
+ * @prog_ram_depth: Available CFG RAM depth for instance without SE_HW_PARAM_2
*/
struct geni_se_desc {
unsigned int num_clks;
const char * const *clks;
+ unsigned int prog_ram_depth;
};
static const char * const icc_path_names[] = {"qup-core", "qup-config",
@@ -920,7 +924,7 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
}
EXPORT_SYMBOL_GPL(geni_se_rx_dma_unprep);
-int geni_icc_get(struct geni_se *se, const char *icc_ddr)
+int geni_icc_get(struct geni_se *se)
{
struct geni_icc_path *icc_paths = se->icc_paths;
@@ -1217,7 +1221,7 @@ int geni_se_resources_init(struct geni_se *se)
se->has_opp = (ret == 0);
- ret = geni_icc_get(se, "qup-memory");
+ ret = geni_icc_get(se);
if (ret)
return ret;
@@ -1230,25 +1234,29 @@ EXPORT_SYMBOL_GPL(geni_se_resources_init);
* @se: Pointer to the serial engine structure.
* @fw: Pointer to the firmware image.
* @protocol: Expected serial engine protocol type.
+ * @fw_size_out: Non-NULL output parameter; receives the rounded, validated
+ * firmware word count on success.
*
* Identifies the appropriate firmware image or configuration required for a
* specific communication protocol instance running on a Qualcomm GENI
* controller. Validates the firmware size against the hardware PROG_RAM_DEPTH
* read from SE_HW_PARAM_2.
*
- * Return: pointer to a valid 'struct se_fw_hdr' if found, or NULL otherwise.
+ * Return: pointer to a valid 'const struct se_fw_hdr' if found, or NULL otherwise.
*/
-static struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct firmware *fw,
- enum geni_se_protocol_type protocol)
+static const struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct firmware *fw,
+ enum geni_se_protocol_type protocol,
+ u32 *fw_size_out)
{
+ struct geni_wrapper *wrapper = se->wrapper;
struct device *dev = se->dev;
const struct elf32_hdr *ehdr;
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
- struct se_fw_hdr *sefw;
+ const struct se_fw_hdr *sefw;
u32 fw_end, cfg_idx_end, cfg_val_end;
u32 prog_ram_depth;
- u16 fw_size;
+ u32 fw_size;
int i;
if (!fw || fw->size < sizeof(struct elf32_hdr))
@@ -1287,27 +1295,29 @@ static struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct
if (phdr->p_filesz < sizeof(struct se_fw_hdr))
continue;
- sefw = (struct se_fw_hdr *)(fw->data + phdr->p_offset);
+ sefw = (const struct se_fw_hdr *)(fw->data + phdr->p_offset);
fw_size = le16_to_cpu(sefw->fw_size_in_items);
- fw_end = le16_to_cpu(sefw->fw_offset) + fw_size * sizeof(u32);
- cfg_idx_end = le16_to_cpu(sefw->cfg_idx_offset) +
- le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u8);
- cfg_val_end = le16_to_cpu(sefw->cfg_val_offset) +
- le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u32);
if (le32_to_cpu(sefw->magic) != SE_MAGIC_NUM || le32_to_cpu(sefw->version) != 1)
continue;
- if (le32_to_cpu(sefw->serial_protocol) != protocol)
+ if (le16_to_cpu(sefw->serial_protocol) != protocol)
continue;
- if (fw_size % 2 != 0) {
+ if (fw_size % 2 != 0)
fw_size++;
- sefw->fw_size_in_items = cpu_to_le16(fw_size);
- }
- prog_ram_depth = FIELD_GET(PROG_RAM_DEPTH_MSK,
- readl_relaxed(se->base + SE_HW_PARAM_2));
+ fw_end = le16_to_cpu(sefw->fw_offset) + fw_size * sizeof(u32);
+ cfg_idx_end = le16_to_cpu(sefw->cfg_idx_offset) +
+ le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u8);
+ cfg_val_end = le16_to_cpu(sefw->cfg_val_offset) +
+ le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u32);
+
+ if (wrapper->prog_ram_depth)
+ prog_ram_depth = wrapper->prog_ram_depth;
+ else
+ prog_ram_depth = FIELD_GET(PROG_RAM_DEPTH_MSK,
+ readl_relaxed(se->base + SE_HW_PARAM_2));
if (fw_size >= prog_ram_depth) {
dev_err(dev, "Firmware size (%u) exceeds RAM size (%u)\n",
fw_size, prog_ram_depth);
@@ -1320,6 +1330,7 @@ static struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct
continue;
}
+ *fw_size_out = fw_size;
return sefw;
}
@@ -1430,17 +1441,17 @@ static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw,
{
const u32 *fw_data, *cfg_val_arr;
const u8 *cfg_idx_arr;
- u32 i, reg_value;
+ u32 i, reg_value, fw_size_in_items;
int ret;
- struct se_fw_hdr *hdr;
+ const struct se_fw_hdr *hdr;
- hdr = geni_find_protocol_fw(se, fw, protocol);
+ hdr = geni_find_protocol_fw(se, fw, protocol, &fw_size_in_items);
if (!hdr)
return -EINVAL;
- fw_data = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->fw_offset));
+ fw_data = (const u32 *)((const u8 *)hdr + le16_to_cpu(hdr->fw_offset));
cfg_idx_arr = (const u8 *)hdr + le16_to_cpu(hdr->cfg_idx_offset);
- cfg_val_arr = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->cfg_val_offset));
+ cfg_val_arr = (const u32 *)((const u8 *)hdr + le16_to_cpu(hdr->cfg_val_offset));
ret = geni_icc_set_bw(se);
if (ret)
@@ -1511,7 +1522,7 @@ static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw,
/* Program RAM address space. */
memcpy_toio(se->base + SE_GENI_CFG_RAMN, fw_data,
- le16_to_cpu(hdr->fw_size_in_items) * sizeof(u32));
+ fw_size_in_items * sizeof(u32));
/* Put default values on GENI's output pads. */
writel_relaxed(0x1, se->base + GENI_FORCE_DEFAULT_REG);
@@ -1617,6 +1628,7 @@ static int geni_se_probe(struct platform_device *pdev)
return PTR_ERR(wrapper->base);
desc = device_get_match_data(&pdev->dev);
+ wrapper->prog_ram_depth = desc->prog_ram_depth;
if (!has_acpi_companion(&pdev->dev) && desc->num_clks) {
int i;
@@ -1669,6 +1681,7 @@ static const char * const i2c_master_hub_clks[] = {
static const struct geni_se_desc i2c_master_hub_desc = {
.clks = i2c_master_hub_clks,
.num_clks = ARRAY_SIZE(i2c_master_hub_clks),
+ .prog_ram_depth = 1020,
};
static const struct of_device_id geni_se_dt_match[] = {
diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
index 259c41f0c34e..a6b673cd7678 100644
--- a/drivers/soc/qcom/qcom_aoss.c
+++ b/drivers/soc/qcom/qcom_aoss.c
@@ -602,10 +602,8 @@ static int qmp_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
ret = devm_request_irq(&pdev->dev, irq, qmp_intr, 0,
"aoss-qmp", qmp);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to request interrupt\n");
+ if (ret < 0)
goto err_free_mbox;
- }
ret = qmp_open(qmp);
if (ret < 0)
diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c
index 06923408bfce..3422d6df7b51 100644
--- a/drivers/soc/qcom/qcom_stats.c
+++ b/drivers/soc/qcom/qcom_stats.c
@@ -371,6 +371,14 @@ static const struct stats_config rpm_data_dba0 = {
.subsystem_stats_in_smem = false,
};
+static const struct stats_config rpm_data_shikra = {
+ .stats_offset = 0,
+ .num_records = 2,
+ .appended_stats_avail = true,
+ .dynamic_offset = true,
+ .subsystem_stats_in_smem = true,
+};
+
static const struct stats_config rpmh_data_sdm845 = {
.stats_offset = 0x48,
.num_records = 2,
@@ -396,6 +404,7 @@ static const struct of_device_id qcom_stats_table[] = {
{ .compatible = "qcom,rpm-stats", .data = &rpm_data },
{ .compatible = "qcom,rpmh-stats", .data = &rpmh_data },
{ .compatible = "qcom,sdm845-rpmh-stats", .data = &rpmh_data_sdm845 },
+ { .compatible = "qcom,shikra-rpm-stats", .data = &rpm_data_shikra },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_stats_table);
diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h
index e3cf1beff803..39441a25af9b 100644
--- a/drivers/soc/qcom/rpmh-internal.h
+++ b/drivers/soc/qcom/rpmh-internal.h
@@ -20,7 +20,7 @@
struct rsc_drv;
/**
- * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests
+ * struct tcs_group - group of Trigger Command Sets (TCS) to send state requests
* to the controller
*
* @drv: The controller.
@@ -53,7 +53,7 @@ struct tcs_group {
};
/**
- * struct rpmh_request: the message to be sent to rpmh-rsc
+ * struct rpmh_request - the message to be sent to rpmh-rsc
*
* @msg: the request
* @cmd: the payload that will be part of the @msg
@@ -70,7 +70,7 @@ struct rpmh_request {
};
/**
- * struct rpmh_ctrlr: our representation of the controller
+ * struct rpmh_ctrlr - our representation of the controller
*
* @cache: the list of cached requests
* @cache_lock: synchronize access to the cache data
@@ -84,13 +84,19 @@ struct rpmh_ctrlr {
struct list_head batch_cache;
};
+/**
+ * struct rsc_ver - Hardware version of the RSC controller.
+ *
+ * @major: Major version number.
+ * @minor: Minor version number.
+ */
struct rsc_ver {
u32 major;
u32 minor;
};
/**
- * struct rsc_drv: the Direct Resource Voter (DRV) of the
+ * struct rsc_drv - the Direct Resource Voter (DRV) of the
* Resource State Coordinator controller (RSC)
*
* @name: Controller identifier.
@@ -116,6 +122,8 @@ struct rsc_ver {
* slot
* @client: Handle to the DRV's client.
* @dev: RSC device.
+ * @ver: HW version of the RSC controller.
+ * @regs: Pointer to the register offset table for this version.
*/
struct rsc_drv {
const char *name;
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
index f881af35ecfc..c4542318eac4 100644
--- a/drivers/soc/qcom/rpmh-rsc.c
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -842,7 +842,7 @@ exit:
}
/**
- * rpmh_rsc_cpu_pm_callback() - Check if any of the AMCs are busy.
+ * rpmh_rsc_cpu_pm_callback() - CPU PM notifier to flush sleep/wake TCS data.
* @nfb: Pointer to the notifier block in struct rsc_drv.
* @action: CPU_PM_ENTER, CPU_PM_ENTER_FAILED, or CPU_PM_EXIT.
* @v: Unused
@@ -923,7 +923,7 @@ static int rpmh_rsc_cpu_pm_callback(struct notifier_block *nfb,
}
/**
- * rpmh_rsc_pd_callback() - Check if any of the AMCs are busy.
+ * rpmh_rsc_pd_callback() - PM domain callback to flush sleep/wake TCS data.
* @nfb: Pointer to the genpd notifier block in struct rsc_drv.
* @action: GENPD_NOTIFY_PRE_OFF, GENPD_NOTIFY_OFF, GENPD_NOTIFY_PRE_ON or GENPD_NOTIFY_ON.
* @v: Unused
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
index f881c4c757ec..360242a315e3 100644
--- a/drivers/soc/qcom/rpmh.c
+++ b/drivers/soc/qcom/rpmh.c
@@ -41,7 +41,7 @@
#define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client)
/**
- * struct cache_req: the request object for caching
+ * struct cache_req - the request object for caching
*
* @addr: the address of the resource
* @sleep_val: the sleep vote
@@ -56,7 +56,7 @@ struct cache_req {
};
/**
- * struct batch_cache_req - An entry in our batch catch
+ * struct batch_cache_req - An entry in our batch cache
*
* @list: linked list obj
* @count: number of messages
@@ -76,6 +76,14 @@ static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct device *dev)
return &drv->client;
}
+/**
+ * rpmh_tx_done() - Signal the completion of a RPMH transfer.
+ * @msg: The request that was previously sent.
+ *
+ * Called by the RSC driver when an active-only transfer is complete.
+ * Signals any blocking waiter and frees the message if it was dynamically
+ * allocated.
+ */
void rpmh_tx_done(const struct tcs_request *msg)
{
struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request,
@@ -157,7 +165,7 @@ unlock:
}
/**
- * __rpmh_write: Cache and send the RPMH request
+ * __rpmh_write() - Cache and send the RPMH request.
*
* @dev: The device making the request
* @state: Active/Sleep request type
@@ -166,6 +174,8 @@ unlock:
* Cache the RPMH request and send if the state is ACTIVE_ONLY.
* SLEEP/WAKE_ONLY requests are not sent to the controller at
* this time. Use rpmh_flush() to send them to the controller.
+ *
+ * Return: 0 on success, negative error code on failure.
*/
static int __rpmh_write(const struct device *dev, enum rpmh_state state,
struct rpmh_request *rpm_msg)
@@ -248,7 +258,7 @@ int rpmh_read(const struct device *dev, struct tcs_cmd *cmd)
EXPORT_SYMBOL_GPL(rpmh_read);
/**
- * rpmh_write_async: Write a set of RPMH commands
+ * rpmh_write_async() - Write a set of RPMH commands.
*
* @dev: The device making the request
* @state: Active/sleep set
@@ -257,6 +267,8 @@ EXPORT_SYMBOL_GPL(rpmh_read);
*
* Write a set of RPMH commands, the order of commands is maintained
* and will be sent as a single shot.
+ *
+ * Return: 0 on success, negative error code on failure.
*/
int rpmh_write_async(const struct device *dev, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 n)
@@ -280,7 +292,7 @@ int rpmh_write_async(const struct device *dev, enum rpmh_state state,
EXPORT_SYMBOL_GPL(rpmh_write_async);
/**
- * rpmh_write: Write a set of RPMH commands and block until response
+ * rpmh_write() - Write a set of RPMH commands and block until response
*
* @dev: The device making the request
* @state: Active/sleep set
@@ -288,6 +300,8 @@ EXPORT_SYMBOL_GPL(rpmh_write_async);
* @n: The number of elements in @cmd
*
* May sleep. Do not call from atomic contexts.
+ *
+ * Return: 0 on success, negative error code on failure.
*/
int rpmh_write(const struct device *dev, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 n)
@@ -342,7 +356,7 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr)
}
/**
- * rpmh_write_batch: Write multiple sets of RPMH commands and wait for the
+ * rpmh_write_batch() - Write multiple sets of RPMH commands and wait for the
* batch to finish.
*
* @dev: the device making the request
@@ -350,13 +364,15 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr)
* @cmd: The payload data
* @n: The array of count of elements in each batch, 0 terminated.
*
- * Write a request to the RSC controller without caching. If the request
- * state is ACTIVE, then the requests are treated as completion request
- * and sent to the controller immediately. The function waits until all the
- * commands are complete. If the request was to SLEEP or WAKE_ONLY, then the
- * request is sent as fire-n-forget and no ack is expected.
+ * If the request state is ACTIVE_ONLY, the requests are sent to the
+ * controller immediately and the function waits until all commands are
+ * complete. If the state is SLEEP or WAKE_ONLY, the requests are cached
+ * and the function returns immediately; they are sent to the controller
+ * later by rpmh_flush().
*
* May sleep. Do not call from atomic contexts for ACTIVE_ONLY requests.
+ *
+ * Return: 0 on success, negative error code on failure.
*/
int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 *n)
@@ -519,7 +535,7 @@ exit:
}
/**
- * rpmh_invalidate: Invalidate sleep and wake sets in batch_cache
+ * rpmh_invalidate() - Invalidate sleep and wake sets in batch_cache
*
* @dev: The device making the request
*
diff --git a/drivers/soc/qcom/smem_dramc.c b/drivers/soc/qcom/smem_dramc.c
index 63ebe7f6db59..497513c95308 100644
--- a/drivers/soc/qcom/smem_dramc.c
+++ b/drivers/soc/qcom/smem_dramc.c
@@ -20,12 +20,22 @@
#define MAX_DDR_FREQ_NUM_V5 14
#define MAX_CHAN_NUM 8
+#define MAX_CHAN_NUM_V7_GLYMUR 16
#define MAX_RANK_NUM 2
#define DDR_HBB_MIN 13
#define DDR_HBB_MAX 19
#define MAX_SHUB_ENTRIES 8
+#define MAX_SHUB_ENTRIES_V7_GLYMUR 10
+#define MAX_DDR_REGIONS_V7_GLYMUR 4
+
+/*
+ * Glymur's DRAM information entry has 256 bytes of trailing zeroes
+ * after its DDR details, four region slots, 10-entry SHUB frequency
+ * plan, and v6 misc information.
+ */
+#define DDR_V7_GLYMUR_RESERVED_SIZE 256
static struct smem_dram *__dram;
@@ -39,6 +49,7 @@ enum ddr_info_version {
INFO_V6, /* INFO_V6 seems to only have shipped with 6 DDR regions, unlike V7 */
INFO_V7,
INFO_V7_WITH_6_REGIONS,
+ INFO_V7_GLYMUR,
};
struct smem_dram {
@@ -188,6 +199,37 @@ struct ddr_details_v7 {
struct ddr_regions_v5 ddr_regions;
};
+struct ddr_regions_v7_glymur {
+ __le32 ddr_region_num;
+ __le64 ddr_rank0_size;
+ __le64 ddr_rank1_size;
+ __le64 ddr_cs0_start_addr;
+ __le64 ddr_cs1_start_addr;
+ __le32 highest_bank_addr_bit;
+ struct ddr_region_v5 ddr_region[MAX_DDR_REGIONS_V7_GLYMUR];
+};
+
+struct ddr_details_v7_glymur {
+ u8 manufacturer_id;
+ u8 device_type;
+ struct ddr_part_details ddr_params[MAX_CHAN_NUM_V7_GLYMUR];
+ struct ddr_freq_plan_v5 ddr_freq_tbl;
+ u8 num_channels;
+ u8 sct_config;
+ struct ddr_regions_v7_glymur ddr_regions;
+};
+
+struct shub_freq_plan_entry_v7_glymur {
+ u8 num_shub_freqs;
+ struct shub_freq_table shub_freq[MAX_SHUB_ENTRIES_V7_GLYMUR];
+};
+
+struct ddr_v7_glymur_tail {
+ struct shub_freq_plan_entry_v7_glymur shub_freq_plan;
+ struct ddr_misc_info_v6 misc_info;
+ u8 reserved[DDR_V7_GLYMUR_RESERVED_SIZE];
+};
+
/**
* qcom_smem_dram_get_hbb(): Get the Highest bank address bit
*
@@ -219,7 +261,7 @@ static void smem_dram_parse_v3_data(struct smem_dram *dram, void *data)
if (freq_entry->freq_khz && freq_entry->enabled) {
u32 freq_khz = le32_to_cpu(freq_entry->freq_khz);
- dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz;
+ dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz;
}
}
}
@@ -231,8 +273,11 @@ static void smem_dram_parse_v3_14freqs_data(struct smem_dram *dram, void *data)
for (int i = 0; i < MAX_DDR_FREQ_NUM_V3 + 1; i++) {
struct ddr_freq_table *freq_entry = &details->ddr_freq_tbl.ddr_freq[i];
- if (freq_entry->freq_khz && freq_entry->enabled)
- dram->frequencies[dram->num_frequencies++] = 1000 * freq_entry->freq_khz;
+ if (freq_entry->freq_khz && freq_entry->enabled) {
+ u32 freq_khz = le32_to_cpu(freq_entry->freq_khz);
+
+ dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz;
+ }
}
}
@@ -248,7 +293,7 @@ static void smem_dram_parse_v4_data(struct smem_dram *dram, void *data)
if (freq_entry->freq_khz && freq_entry->enabled) {
u32 freq_khz = le32_to_cpu(freq_entry->freq_khz);
- dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz;
+ dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz;
}
}
}
@@ -265,7 +310,7 @@ static void smem_dram_parse_v5_data(struct smem_dram *dram, void *data)
if (freq_entry->freq_khz && freq_entry->enabled) {
u32 freq_khz = le32_to_cpu(freq_entry->freq_khz);
- dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz;
+ dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz;
}
}
}
@@ -282,6 +327,23 @@ static void smem_dram_parse_v7_data(struct smem_dram *dram, void *data)
if (freq_entry->freq_khz && freq_entry->enabled) {
u32 freq_khz = le32_to_cpu(freq_entry->freq_khz);
+ dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz;
+ }
+ }
+}
+
+static void smem_dram_parse_v7_glymur_data(struct smem_dram *dram, void *data)
+{
+ struct ddr_details_v7_glymur *details = data;
+
+ dram->hbb = le32_to_cpu(details->ddr_regions.highest_bank_addr_bit);
+
+ for (int i = 0; i < MAX_DDR_FREQ_NUM_V5; i++) {
+ struct ddr_freq_table *freq_entry = &details->ddr_freq_tbl.ddr_freq[i];
+
+ if (freq_entry->freq_khz && freq_entry->enabled) {
+ u32 freq_khz = le32_to_cpu(freq_entry->freq_khz);
+
dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz;
}
}
@@ -341,6 +403,10 @@ static int smem_dram_infer_struct_version(size_t size)
sizeof(struct shub_freq_plan_entry))
return INFO_V7_WITH_6_REGIONS;
+ if (size == sizeof(struct ddr_details_v7_glymur) +
+ sizeof(struct ddr_v7_glymur_tail))
+ return INFO_V7_GLYMUR;
+
return INFO_UNKNOWN;
}
@@ -382,7 +448,7 @@ struct dentry *smem_dram_parse(struct qcom_smem *smem, struct device *dev)
return ERR_PTR(-ENODATA);
ver = smem_dram_infer_struct_version(actual_size);
- if (ver < 0) {
+ if ((int)ver < 0) {
/* Some SoCs don't provide data that's useful for us */
return ERR_PTR(-ENODATA);
} else if (ver == INFO_UNKNOWN) {
@@ -415,6 +481,9 @@ struct dentry *smem_dram_parse(struct qcom_smem *smem, struct device *dev)
case INFO_V7_WITH_6_REGIONS:
smem_dram_parse_v7_data(dram, data);
break;
+ case INFO_V7_GLYMUR:
+ smem_dram_parse_v7_glymur_data(dram, data);
+ break;
default:
return ERR_PTR(-EINVAL);
}
diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c
index af0ceeaf6e07..01b8580c9f27 100644
--- a/drivers/soc/qcom/smp2p.c
+++ b/drivers/soc/qcom/smp2p.c
@@ -102,7 +102,7 @@ struct smp2p_entry {
struct qcom_smp2p *smp2p;
const char *name;
- u32 *value;
+ u32 __iomem *value;
u32 last_value;
struct irq_domain *domain;
@@ -276,7 +276,7 @@ static void qcom_smp2p_start_in(struct qcom_smp2p *smp2p)
list_for_each_entry(entry, &smp2p->inbound, node) {
memcpy(buf, in->entries[i].name, sizeof(buf));
if (!strcmp(buf, entry->name)) {
- entry->value = &in->entries[i].value;
+ entry->value = (u32 __iomem *)&in->entries[i].value;
entry->last_value = readl(entry->value);
break;
}
@@ -302,7 +302,7 @@ static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p)
list_for_each_entry(entry, &smp2p->inbound, node) {
memcpy(buf, in->entries[i].name, sizeof(buf));
if (!strcmp(buf, entry->name)) {
- entry->value = &in->entries[i].value;
+ entry->value = (u32 __iomem *)&in->entries[i].value;
break;
}
}
@@ -411,15 +411,9 @@ static int smp2p_set_irq_type(struct irq_data *irqd, unsigned int type)
if (!(type & IRQ_TYPE_EDGE_BOTH))
return -EINVAL;
- if (type & IRQ_TYPE_EDGE_RISING)
- set_bit(irq, entry->irq_rising);
- else
- clear_bit(irq, entry->irq_rising);
+ assign_bit(irq, entry->irq_rising, type & IRQ_TYPE_EDGE_RISING);
- if (type & IRQ_TYPE_EDGE_FALLING)
- set_bit(irq, entry->irq_falling);
- else
- clear_bit(irq, entry->irq_falling);
+ assign_bit(irq, entry->irq_falling, type & IRQ_TYPE_EDGE_FALLING);
return 0;
}
@@ -528,7 +522,7 @@ static int qcom_smp2p_outbound_entry(struct qcom_smp2p *smp2p,
memcpy(out->entries[out->valid_entries].name, buf, SMP2P_MAX_ENTRY_NAME);
/* Make the logical entry reference the physical value */
- entry->value = &out->entries[out->valid_entries].value;
+ entry->value = (u32 __iomem *)&out->entries[out->valid_entries].value;
out->valid_entries++;
@@ -720,10 +714,8 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
NULL, qcom_smp2p_intr,
IRQF_ONESHOT,
NULL, (void *)smp2p);
- if (ret) {
- dev_err(&pdev->dev, "failed to request interrupt\n");
+ if (ret)
goto unwind_interfaces;
- }
/*
* Treat smp2p interrupt as wakeup source, but keep it disabled
diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c
index 021e9d1f61dc..bb487bf6bf03 100644
--- a/drivers/soc/qcom/smsm.c
+++ b/drivers/soc/qcom/smsm.c
@@ -82,8 +82,8 @@ struct qcom_smsm {
u32 num_hosts;
u32 num_entries;
- u32 *local_state;
- u32 *subscription;
+ u32 __iomem *local_state;
+ u32 __iomem *subscription;
struct qcom_smem_state *state;
spinlock_t lock;
@@ -115,8 +115,8 @@ struct smsm_entry {
DECLARE_BITMAP(irq_falling, 32);
unsigned long last_value;
- u32 *remote_state;
- u32 *subscription;
+ u32 __iomem *remote_state;
+ u32 __iomem *subscription;
};
/**
@@ -277,10 +277,8 @@ static void smsm_unmask_irq(struct irq_data *irqd)
u32 val;
/* Make sure our last cached state is up-to-date */
- if (readl(entry->remote_state) & BIT(irq))
- set_bit(irq, &entry->last_value);
- else
- clear_bit(irq, &entry->last_value);
+ assign_bit(irq, &entry->last_value,
+ readl(entry->remote_state) & BIT(irq));
set_bit(irq, entry->irq_enabled);
@@ -304,15 +302,9 @@ static int smsm_set_irq_type(struct irq_data *irqd, unsigned int type)
if (!(type & IRQ_TYPE_EDGE_BOTH))
return -EINVAL;
- if (type & IRQ_TYPE_EDGE_RISING)
- set_bit(irq, entry->irq_rising);
- else
- clear_bit(irq, entry->irq_rising);
+ assign_bit(irq, entry->irq_rising, type & IRQ_TYPE_EDGE_RISING);
- if (type & IRQ_TYPE_EDGE_FALLING)
- set_bit(irq, entry->irq_falling);
- else
- clear_bit(irq, entry->irq_falling);
+ assign_bit(irq, entry->irq_falling, type & IRQ_TYPE_EDGE_FALLING);
return 0;
}
@@ -451,10 +443,8 @@ static int smsm_inbound_entry(struct qcom_smsm *smsm,
NULL, smsm_intr,
IRQF_ONESHOT,
"smsm", (void *)entry);
- if (ret) {
- dev_err(smsm->dev, "failed to request interrupt\n");
+ if (ret)
return ret;
- }
entry->domain = irq_domain_create_linear(of_fwnode_handle(node), 32, &smsm_irq_ops, entry);
if (!entry->domain) {
@@ -513,9 +503,9 @@ static int qcom_smsm_probe(struct platform_device *pdev)
struct device_node *node;
struct smsm_entry *entry;
struct qcom_smsm *smsm;
- u32 *intr_mask;
+ u32 __iomem *intr_mask;
size_t size;
- u32 *states;
+ u32 __iomem *states;
u32 id;
int ret;
@@ -579,7 +569,7 @@ static int qcom_smsm_probe(struct platform_device *pdev)
goto out_put;
}
- states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL);
+ states = (u32 __iomem *)qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL);
if (IS_ERR(states)) {
dev_err(&pdev->dev, "Unable to acquire shared state entry\n");
ret = PTR_ERR(states);
@@ -594,7 +584,7 @@ static int qcom_smsm_probe(struct platform_device *pdev)
goto out_put;
}
- intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL);
+ intr_mask = (u32 __iomem *)qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL);
if (IS_ERR(intr_mask)) {
dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n");
ret = PTR_ERR(intr_mask);
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 1836e226a294..38efc5db7fa8 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -450,6 +450,7 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(IPQ8172) },
{ qcom_board_id(IPQ8173) },
{ qcom_board_id(IPQ8174) },
+ { qcom_board_id(SM7250) },
{ qcom_board_id(IPQ6018) },
{ qcom_board_id(IPQ6028) },
{ qcom_board_id(SDM429W) },
@@ -541,8 +542,10 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(QCS9075) },
{ qcom_board_id(QCS615) },
{ qcom_board_id(SA8797P) },
+ { qcom_board_id(SM8975) },
{ qcom_board_id(CQ7790M) },
{ qcom_board_id(CQ7790S) },
+ { qcom_board_id(SM8950) },
{ qcom_board_id(CQ2390M) },
{ qcom_board_id(CQ2390S) },
{ qcom_board_id(IQ2390S) },
diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c
index 23901a4c51f7..a4d8769f8550 100644
--- a/drivers/soc/qcom/ubwc_config.c
+++ b/drivers/soc/qcom/ubwc_config.c
@@ -105,6 +105,13 @@ static const struct qcom_ubwc_cfg_data milos_data = {
.highest_bank_bit = 15,
};
+static const struct qcom_ubwc_cfg_data ubwc_7_0_hbb16 = {
+ .ubwc_enc_version = UBWC_7_0,
+ .flags = UBWC_SWIZZLE_ENABLE_LVL2 |
+ UBWC_SWIZZLE_ENABLE_LVL3,
+ .highest_bank_bit = 16,
+};
+
static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = {
{ .compatible = "qcom,apq8016", .data = &no_ubwc_data },
{ .compatible = "qcom,apq8026", .data = &no_ubwc_data },
@@ -112,8 +119,11 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = {
{ .compatible = "qcom,apq8096", .data = &ubwc_1_0_hbb15 },
{ .compatible = "qcom,eliza", .data = &ubwc_5_0_hbb15 },
{ .compatible = "qcom,glymur", .data = &glymur_data},
+ { .compatible = "qcom,hawi", .data = &ubwc_7_0_hbb16 },
{ .compatible = "qcom,kaanapali", .data = &ubwc_6_0_hbb16 },
+ { .compatible = "qcom,kalambo", .data = &glymur_data },
{ .compatible = "qcom,mahua", .data = &glymur_data },
+ { .compatible = "qcom,maili", .data = &ubwc_7_0_hbb16, },
{ .compatible = "qcom,milos", .data = &milos_data },
{ .compatible = "qcom,msm8226", .data = &no_ubwc_data },
{ .compatible = "qcom,msm8916", .data = &no_ubwc_data },
@@ -121,12 +131,14 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = {
{ .compatible = "qcom,msm8937", .data = &ubwc_1_0_hbb14 },
{ .compatible = "qcom,msm8929", .data = &no_ubwc_data },
{ .compatible = "qcom,msm8939", .data = &no_ubwc_data },
+ { .compatible = "qcom,msm8952", .data = &no_ubwc_data },
{ .compatible = "qcom,msm8953", .data = &ubwc_1_0_hbb14 },
{ .compatible = "qcom,msm8956", .data = &no_ubwc_data },
{ .compatible = "qcom,msm8974", .data = &no_ubwc_data },
{ .compatible = "qcom,msm8976", .data = &no_ubwc_data },
{ .compatible = "qcom,msm8996", .data = &ubwc_1_0_hbb15 },
{ .compatible = "qcom,msm8998", .data = &ubwc_1_0_hbb15 },
+ { .compatible = "qcom,nord", .data = &glymur_data },
{ .compatible = "qcom,qcm2290", .data = &ubwc_0_0_hbb15, },
{ .compatible = "qcom,qcm6490", .data = &ubwc_3_1_hbb14, },
{ .compatible = "qcom,qcs8300", .data = &ubwc_4_0_hbb16, },
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index eb8ac0d47d9d..a63df28df3b5 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -227,6 +227,14 @@ config ARCH_R8A774A1
help
This enables support for the Renesas RZ/G2M SoC.
+config ARCH_R8A774A3
+ bool "ARM64 Platform support for R8A774A3 (RZ/G2M v3.0)"
+ default y if ARCH_RENESAS
+ select ARCH_RCAR_GEN3
+ select SYSC_R8A774A3
+ help
+ This enables support for the Renesas RZ/G2M SoC (version 3.0).
+
config ARCH_R8A774B1
bool "ARM64 Platform support for R8A774B1 (RZ/G2N)"
default y if ARCH_RENESAS
@@ -410,6 +418,7 @@ config ARCH_R9A09G011
config ARCH_R9A09G047
bool "ARM64 Platform support for R9A09G047 (RZ/G3E)"
default y if ARCH_RENESAS
+ select RENESAS_RZV2H_ICU
select SYS_R9A09G047
help
This enables support for the Renesas RZ/G3E SoC variants.
@@ -417,6 +426,7 @@ config ARCH_R9A09G047
config ARCH_R9A09G056
bool "ARM64 Platform support for R9A09G056 (RZ/V2N)"
default y if ARCH_RENESAS
+ select RENESAS_RZV2H_ICU
select SYS_R9A09G056
help
This enables support for the Renesas RZ/V2N SoC variants.
@@ -468,11 +478,12 @@ endif # RISCV
config RCAR_MFIS
tristate "Renesas R-Car MFIS driver"
depends on ARCH_RENESAS || COMPILE_TEST
- depends on MAILBOX
+ depends on MAILBOX && HWSPINLOCK
help
- Select this option to enable the Renesas R-Car MFIS core driver for
- the MFIS device found on SoCs like R-Car. On families like Gen5, this
- is needed to communicate with the SCP.
+ Select this option to enable support for the Renesas R-Car
+ Multifunctional Interface (MFIS) device found on SoCs like R-Car.
+ On families like R-Car Gen5, this is needed to communicate with the
+ SCP.
config PWC_RZV2M
bool "Renesas RZ/V2M PWC support" if COMPILE_TEST
@@ -486,6 +497,7 @@ config RZN1_IRQMUX
config SYSC_RZ
bool "System controller for RZ SoCs" if COMPILE_TEST
select MFD_SYSCON
+ select AUXILIARY_BUS
config SYSC_R9A08G045
bool "Renesas System controller support for R9A08G045 (RZ/G3S)" if COMPILE_TEST
@@ -494,6 +506,8 @@ config SYSC_R9A08G045
config SYSC_R9A08G046
bool "Renesas System controller support for R9A08G046 (RZ/G3L)" if COMPILE_TEST
select SYSC_RZ
+ select POWER_SEQUENCING
+ select POWER_SEQUENCING_RENESAS_PWRRDY
config SYS_R9A09G047
bool "Renesas System controller support for R9A09G047 (RZ/G3E)" if COMPILE_TEST
diff --git a/drivers/soc/renesas/r9a08g046-sysc.c b/drivers/soc/renesas/r9a08g046-sysc.c
index 90db9d383539..cd129c727461 100644
--- a/drivers/soc/renesas/r9a08g046-sysc.c
+++ b/drivers/soc/renesas/r9a08g046-sysc.c
@@ -76,6 +76,7 @@ static const struct rz_sysc_soc_id_init_data rzg3l_sysc_soc_id_init_data __initc
.devid_offset = 0xa04,
.revision_mask = GENMASK(31, 28),
.specific_id_mask = GENMASK(27, 0),
+ .pwrrdy_pwrseq = true,
};
const struct rz_sysc_init_data rzg3l_sysc_init_data __initconst = {
diff --git a/drivers/soc/renesas/rcar-mfis.c b/drivers/soc/renesas/rcar-mfis.c
index 3435c3e16198..d5bbc3077373 100644
--- a/drivers/soc/renesas/rcar-mfis.c
+++ b/drivers/soc/renesas/rcar-mfis.c
@@ -8,6 +8,7 @@
*/
#include <dt-bindings/soc/renesas,r8a78000-mfis.h>
#include <linux/device.h>
+#include <linux/hwspinlock.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
@@ -19,12 +20,18 @@
#include <linux/platform_device.h>
#include <linux/spinlock.h>
+/* FIXME: hwspinlock core refactoring to not need internal header is on-going */
+#include "../../hwspinlock/hwspinlock_internal.h"
+
+#define MFISLCKR0 0xc0
+#define MFISLCKR8 0x0724
#define MFISWPCNTR 0x0900
#define MFISWACNTR 0x0904
#define MFIS_X5H_IICR(i) ((i) * 0x1000 + 0x00)
#define MFIS_X5H_EICR(i) ((i) * 0x1000 + 0x04)
+#define MFIS_NUM_LOCKS 64
#define MFIS_UNPROTECT_KEY 0xACCE0000
struct mfis_priv;
@@ -42,6 +49,7 @@ struct mfis_info {
unsigned int mb_tx_uses_eicr:1;
unsigned int mb_channels_are_unidir:1;
u32 (*mb_calc_reg)(u32 chan_num, bool tx_uses_eicr, bool is_only_rx);
+ int hwsp_base_id;
};
struct mfis_chan_priv {
@@ -50,7 +58,7 @@ struct mfis_chan_priv {
};
struct mfis_priv {
- spinlock_t unprotect_lock; /* guards access to the unprotection reg */
+ raw_spinlock_t unprotect_lock; /* guards access to unprotection reg */
struct device *dev;
struct mfis_reg common_reg;
struct mfis_reg mbox_reg;
@@ -59,6 +67,9 @@ struct mfis_priv {
/* mailbox private data */
struct mbox_controller mbox;
struct mfis_chan_priv *chan_privs;
+
+ /* hwspinlock private data */
+ struct hwspinlock_device bank; /* flex array inside, must be last! */
};
static u32 mfis_read(struct mfis_reg *mreg, unsigned int reg)
@@ -80,13 +91,45 @@ static void mfis_write(struct mfis_reg *mreg, u32 reg, u32 val)
unprotect_code = (MFIS_UNPROTECT_KEY & ~unprotect_mask) |
((mreg->start + reg) & unprotect_mask);
- spin_lock_irqsave(&priv->unprotect_lock, flags);
+ raw_spin_lock_irqsave(&priv->unprotect_lock, flags);
iowrite32(unprotect_code, priv->common_reg.base + MFISWACNTR);
iowrite32(val, mreg->base + reg);
- spin_unlock_irqrestore(&priv->unprotect_lock, flags);
+ raw_spin_unlock_irqrestore(&priv->unprotect_lock, flags);
}
/********************************************************
+ * HW Spinlocks *
+ ********************************************************/
+
+#define MFISLCKR8_CH_OFS (MFISLCKR8 - 8 * sizeof(u32))
+
+static int rcar_mfis_hwsp_trylock(struct hwspinlock *lock)
+{
+ struct mfis_priv *priv = lock->priv;
+ int id = hwlock_to_id(lock) - lock->bank->base_id;
+ u32 val, reg;
+
+ reg = id * sizeof(u32) + (id < 8 ? MFISLCKR0 : MFISLCKR8_CH_OFS);
+ val = mfis_read(&priv->common_reg, reg);
+ return !val;
+}
+
+static void rcar_mfis_hwsp_unlock(struct hwspinlock *lock)
+{
+ struct mfis_priv *priv = lock->priv;
+ int id = hwlock_to_id(lock) - lock->bank->base_id;
+ u32 reg;
+
+ reg = id * sizeof(u32) + (id < 8 ? MFISLCKR0 : MFISLCKR8_CH_OFS);
+ mfis_write(&priv->common_reg, reg, 0);
+}
+
+static const struct hwspinlock_ops rcar_mfis_hwsp_ops = {
+ .trylock = rcar_mfis_hwsp_trylock,
+ .unlock = rcar_mfis_hwsp_unlock,
+};
+
+/********************************************************
* Mailbox *
********************************************************/
@@ -314,7 +357,7 @@ static int mfis_probe(struct platform_device *pdev)
struct mfis_priv *priv;
int ret;
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(dev, struct_size(priv, bank.lock, MFIS_NUM_LOCKS), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -323,7 +366,7 @@ static int mfis_probe(struct platform_device *pdev)
if (!priv->info)
return -ENOENT;
- spin_lock_init(&priv->unprotect_lock);
+ raw_spin_lock_init(&priv->unprotect_lock);
ret = mfis_reg_probe(pdev, priv, &priv->common_reg, "common", true);
if (ret)
@@ -333,6 +376,14 @@ static int mfis_probe(struct platform_device *pdev)
if (ret)
return ret;
+ for (unsigned int ch = 0; ch < MFIS_NUM_LOCKS; ch++)
+ priv->bank.lock[ch].priv = priv;
+
+ ret = devm_hwspin_lock_register(dev, &priv->bank, &rcar_mfis_hwsp_ops,
+ priv->info->hwsp_base_id, MFIS_NUM_LOCKS);
+ if (ret)
+ return ret;
+
return mfis_mb_probe(priv);
}
@@ -357,6 +408,7 @@ static const struct mfis_info mfis_info_r8a78000_scp = {
.mb_tx_uses_eicr = true,
.mb_channels_are_unidir = true,
.mb_calc_reg = mfis_mb_r8a78000_calc_reg,
+ .hwsp_base_id = MFIS_NUM_LOCKS,
};
static const struct of_device_id mfis_mfd_of_match[] = {
diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c
index 0541990901fc..26f976880d3f 100644
--- a/drivers/soc/renesas/rcar-rst.c
+++ b/drivers/soc/renesas/rcar-rst.c
@@ -93,6 +93,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = {
{ .compatible = "renesas,r8a77470-rst", .data = &rcar_rst_gen2 },
/* RZ/G2 is handled like R-Car Gen3 */
{ .compatible = "renesas,r8a774a1-rst", .data = &rcar_rst_gen3 },
+ { .compatible = "renesas,r8a774a3-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a774b1-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a774c0-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a774e1-rst", .data = &rcar_rst_gen3 },
diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
index 18acca73064c..5a5d05013eb7 100644
--- a/drivers/soc/renesas/renesas-soc.c
+++ b/drivers/soc/renesas/renesas-soc.c
@@ -312,6 +312,9 @@ static const struct of_device_id renesas_socs[] __initconst __maybe_unused = {
#ifdef CONFIG_ARCH_R8A774A1
{ .compatible = "renesas,r8a774a1", .data = &soc_rz_g2m },
#endif
+#ifdef CONFIG_ARCH_R8A774A3
+ { .compatible = "renesas,r8a774a3", .data = &soc_rz_g2m },
+#endif
#ifdef CONFIG_ARCH_R8A774B1
{ .compatible = "renesas,r8a774b1", .data = &soc_rz_g2n },
#endif
diff --git a/drivers/soc/renesas/rz-sysc.c b/drivers/soc/renesas/rz-sysc.c
index 161e8c38eea6..0e92c415d4be 100644
--- a/drivers/soc/renesas/rz-sysc.c
+++ b/drivers/soc/renesas/rz-sysc.c
@@ -5,6 +5,7 @@
* Copyright (C) 2024 Renesas Electronics Corp.
*/
+#include <linux/auxiliary_bus.h>
#include <linux/bitfield.h>
#include <linux/cleanup.h>
#include <linux/io.h>
@@ -149,6 +150,10 @@ static int rz_sysc_probe(struct platform_device *pdev)
if (IS_ERR(regmap))
return PTR_ERR(regmap);
+ if (data->soc_id_init_data->pwrrdy_pwrseq &&
+ !devm_auxiliary_device_create(dev, "pwrseq-pwrrdy", regmap))
+ return -ENODEV;
+
return of_syscon_register_regmap(dev->of_node, regmap);
}
diff --git a/drivers/soc/renesas/rz-sysc.h b/drivers/soc/renesas/rz-sysc.h
index 921ee0d26c47..e55f3258d703 100644
--- a/drivers/soc/renesas/rz-sysc.h
+++ b/drivers/soc/renesas/rz-sysc.h
@@ -20,6 +20,7 @@
* @revision_mask: SYSC SoC ID revision mask
* @specific_id_mask: SYSC SoC ID specific ID mask
* @print_id: print SoC-specific extended device identification
+ * @pwrrdy_pwrseq: has pwrrdy register controlled through power sequencer
*/
struct rz_sysc_soc_id_init_data {
const char * const family;
@@ -29,6 +30,7 @@ struct rz_sysc_soc_id_init_data {
u32 specific_id_mask;
void (*print_id)(struct device *dev, void __iomem *sysc_base,
struct soc_device_attribute *soc_dev_attr);
+ bool pwrrdy_pwrseq;
};
/**
diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
index 6ef9751e2509..506a0bcdfe30 100644
--- a/drivers/soc/samsung/exynos-chipid.c
+++ b/drivers/soc/samsung/exynos-chipid.c
@@ -64,6 +64,7 @@ static const struct exynos_soc_id {
{ "EXYNOS8890", 0xE8890000 },
/* Compatible with: samsung,exynos850-chipid */
{ "EXYNOS2200", 0xE9925000 },
+ { "EXYNOS5515", 0xE5515000 },
{ "EXYNOS7885", 0xE7885000 },
{ "EXYNOS850", 0xE3830000 },
{ "EXYNOS8895", 0xE8895000 },
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index efccdd63e40e..702f7d21eda7 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -38,6 +38,8 @@ struct exynos_pmu_context {
unsigned long *in_cpuhp;
bool sys_insuspend;
bool sys_inreboot;
+ int cpuhp_prepare_state;
+ int cpuhp_online_state;
};
void __iomem *pmu_base_addr;
@@ -59,11 +61,14 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
{
unsigned int i;
const struct exynos_pmu_data *pmu_data;
+ struct exynos_pmu_context *ctx;
- if (!pmu_context || !pmu_context->pmu_data)
+ /* Pairs with the smp_store_release() in exynos_pmu_probe(). */
+ ctx = smp_load_acquire(&pmu_context);
+ if (!ctx || !ctx->pmu_data)
return;
- pmu_data = pmu_context->pmu_data;
+ pmu_data = ctx->pmu_data;
if (pmu_data->powerdown_conf)
pmu_data->powerdown_conf(mode);
@@ -458,22 +463,62 @@ static int setup_cpuhp_and_cpuidle(struct device *dev)
gs101_cpuhp_pmu_online(cpu);
/* register CPU hotplug callbacks */
- cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "soc/exynos-pmu:prepare",
- gs101_cpuhp_pmu_online, NULL);
+ pmu_context->cpuhp_prepare_state = CPUHP_INVALID;
+ pmu_context->cpuhp_online_state = CPUHP_INVALID;
- cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "soc/exynos-pmu:online",
- NULL, gs101_cpuhp_pmu_offline);
+ ret = cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "soc/exynos-pmu:prepare",
+ gs101_cpuhp_pmu_online, NULL);
+ if (ret < 0)
+ return ret;
+
+ pmu_context->cpuhp_prepare_state = ret;
+
+ ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "soc/exynos-pmu:online",
+ NULL, gs101_cpuhp_pmu_offline);
+ if (ret < 0)
+ goto clean_cpuhp_state_prepare;
+
+ pmu_context->cpuhp_online_state = ret;
/* register CPU PM notifiers for cpuidle */
- cpu_pm_register_notifier(&gs101_cpu_pm_notifier);
- register_reboot_notifier(&exynos_cpupm_reboot_nb);
- return 0;
+ ret = cpu_pm_register_notifier(&gs101_cpu_pm_notifier);
+ if (ret)
+ goto clean_cpuhp_states;
+
+ ret = register_reboot_notifier(&exynos_cpupm_reboot_nb);
+ if (!ret)
+ /* Success */
+ return ret;
+
+ cpu_pm_unregister_notifier(&gs101_cpu_pm_notifier);
+
+clean_cpuhp_states:
+ cpuhp_remove_state(pmu_context->cpuhp_online_state);
+ pmu_context->cpuhp_online_state = CPUHP_INVALID;
+
+clean_cpuhp_state_prepare:
+ cpuhp_remove_state(pmu_context->cpuhp_prepare_state);
+ pmu_context->cpuhp_prepare_state = CPUHP_INVALID;
+
+ return ret;
+}
+
+static void destroy_cpuhp_and_cpuidle(void)
+{
+ cpu_pm_unregister_notifier(&gs101_cpu_pm_notifier);
+ unregister_reboot_notifier(&exynos_cpupm_reboot_nb);
+
+ if (pmu_context->cpuhp_prepare_state != CPUHP_INVALID)
+ cpuhp_remove_state(pmu_context->cpuhp_prepare_state);
+ if (pmu_context->cpuhp_online_state != CPUHP_INVALID)
+ cpuhp_remove_state(pmu_context->cpuhp_online_state);
}
static int exynos_pmu_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct regmap_config pmu_regmcfg;
+ struct exynos_pmu_context *ctx;
struct regmap *regmap;
struct resource *res;
int ret;
@@ -482,12 +527,19 @@ static int exynos_pmu_probe(struct platform_device *pdev)
if (IS_ERR(pmu_base_addr))
return PTR_ERR(pmu_base_addr);
- pmu_context = devm_kzalloc(&pdev->dev,
- sizeof(struct exynos_pmu_context),
- GFP_KERNEL);
- if (!pmu_context)
+ ctx = devm_kzalloc(&pdev->dev, sizeof(struct exynos_pmu_context),
+ GFP_KERNEL);
+ if (!ctx)
return -ENOMEM;
+ /*
+ * exynos_sys_powerdown_conf() gates on pmu_context and then writes
+ * through pmu_base_addr, which is a separate global. Publish the
+ * context with release semantics so that the mapping is visible to
+ * a CPU that passes the gate.
+ */
+ smp_store_release(&pmu_context, ctx);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
@@ -541,8 +593,12 @@ static int exynos_pmu_probe(struct platform_device *pdev)
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, exynos_pmu_devs,
ARRAY_SIZE(exynos_pmu_devs), NULL, 0, NULL);
- if (ret)
+ if (ret) {
+ if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_cpuhp)
+ destroy_cpuhp_and_cpuidle();
+
return ret;
+ }
if (devm_of_platform_populate(dev))
dev_err(dev, "Error populating children, reboot and poweroff might not work properly\n");
diff --git a/drivers/soc/starfive/Kconfig b/drivers/soc/starfive/Kconfig
new file mode 100644
index 000000000000..04b020083d3e
--- /dev/null
+++ b/drivers/soc/starfive/Kconfig
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "StarFive SoC (System On Chip) specific Drivers"
+
+source "drivers/soc/starfive/socinfo/Kconfig"
+
+endmenu
diff --git a/drivers/soc/starfive/Makefile b/drivers/soc/starfive/Makefile
new file mode 100644
index 000000000000..ca1e609b8104
--- /dev/null
+++ b/drivers/soc/starfive/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y += socinfo/
diff --git a/drivers/soc/starfive/socinfo/Kconfig b/drivers/soc/starfive/socinfo/Kconfig
new file mode 100644
index 000000000000..64f1b1e04d01
--- /dev/null
+++ b/drivers/soc/starfive/socinfo/Kconfig
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config STARFIVE_JHB100_SOCINFO
+ bool "StarFive JHB100 SoC Information"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ select SOC_BUS
+ select MFD_CORE
+ select MFD_SYSCON
+ default y
+ help
+ Include support for the SoC bus socinfo for the StarFive JHB100 SoC
+ platforms to provide information about the SoC family and variant
+ to user space.
diff --git a/drivers/soc/starfive/socinfo/Makefile b/drivers/soc/starfive/socinfo/Makefile
new file mode 100644
index 000000000000..26c2bdf1de3b
--- /dev/null
+++ b/drivers/soc/starfive/socinfo/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_STARFIVE_JHB100_SOCINFO) += jhb100-socinfo.o
diff --git a/drivers/soc/starfive/socinfo/jhb100-socinfo.c b/drivers/soc/starfive/socinfo/jhb100-socinfo.c
new file mode 100644
index 000000000000..0a31cae9b4f5
--- /dev/null
+++ b/drivers/soc/starfive/socinfo/jhb100-socinfo.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2025 StarFive Technology Co., Ltd.
+ *
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/sys_soc.h>
+
+#define JHB100_REV_ID 0x38
+#define JHB100_REV_ID_CHAR GENMASK(3, 2)
+#define JHB100_REV_ID_NUM GENMASK(1, 0)
+
+/*
+ * The sys0 system controller region only contains the PLL controls, this
+ * revision ID register and a few debug registers, so instead of describing
+ * a child node in the devicetree the PLL device is instantiated from here.
+ */
+static const struct mfd_cell jhb100_sys0_syscon_cells[] = {
+ { .name = "jhb100-sys0-pll", },
+};
+
+static void jhb100_socinfo_unregister(void *data)
+{
+ soc_device_unregister(data);
+}
+
+static int jhb100_socinfo_probe(struct platform_device *pdev)
+{
+ struct soc_device_attribute *attrs;
+ struct device *dev = &pdev->dev;
+ struct soc_device *soc_dev;
+ struct regmap *regmap;
+ char rev_char;
+ u32 rev_id;
+ int ret;
+
+ regmap = syscon_node_to_regmap(dev->of_node);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap),
+ "failed to get syscon regmap\n");
+
+ ret = regmap_read(regmap, JHB100_REV_ID, &rev_id);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to read revision ID\n");
+
+ attrs = devm_kzalloc(dev, sizeof(*attrs), GFP_KERNEL);
+ if (!attrs)
+ return -ENOMEM;
+
+ rev_char = FIELD_GET(JHB100_REV_ID_CHAR, rev_id) + 'A';
+
+ attrs->family = "JH";
+ attrs->soc_id = "JHB100";
+ attrs->revision = devm_kasprintf(dev, GFP_KERNEL, "%c%lu", rev_char,
+ FIELD_GET(JHB100_REV_ID_NUM, rev_id));
+ if (!attrs->revision)
+ return -ENOMEM;
+
+ soc_dev = soc_device_register(attrs);
+ if (IS_ERR(soc_dev))
+ return dev_err_probe(dev, PTR_ERR(soc_dev),
+ "failed to register SoC device\n");
+
+ ret = devm_add_action_or_reset(dev, jhb100_socinfo_unregister, soc_dev);
+ if (ret)
+ return ret;
+
+ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO,
+ jhb100_sys0_syscon_cells,
+ ARRAY_SIZE(jhb100_sys0_syscon_cells),
+ NULL, 0, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to add mfd cells\n");
+
+ dev_info(dev, "StarFive %s SoC rev(%s)\n", attrs->soc_id, attrs->revision);
+
+ return 0;
+}
+
+static const struct of_device_id jhb100_socinfo_of_match[] = {
+ { .compatible = "starfive,jhb100-sys0-syscon" },
+ { /* sentinel */ }
+};
+
+static struct platform_driver jhb100_socinfo_driver = {
+ .probe = jhb100_socinfo_probe,
+ .driver = {
+ .name = "jhb100-socinfo",
+ .of_match_table = jhb100_socinfo_of_match,
+ },
+};
+
+static int __init jhb100_socinfo_init(void)
+{
+ return platform_driver_register(&jhb100_socinfo_driver);
+}
+subsys_initcall(jhb100_socinfo_init);
diff --git a/drivers/soc/tegra/cbb/tegra194-cbb.c b/drivers/soc/tegra/cbb/tegra194-cbb.c
index 69ef929e04f8..be35ec0f39de 100644
--- a/drivers/soc/tegra/cbb/tegra194-cbb.c
+++ b/drivers/soc/tegra/cbb/tegra194-cbb.c
@@ -1912,7 +1912,7 @@ static bool print_errlog0(struct seq_file *file, struct tegra194_cbb *cbb)
/*
* Print debug information about failed transaction using
- * ErrLog registers of error loggger having ErrVld set
+ * ErrLog registers of error logger having ErrVld set
*/
static bool print_errloggerX_info(struct seq_file *file, struct tegra194_cbb *cbb,
int errloggerX)
diff --git a/drivers/soc/tegra/flowctrl.c b/drivers/soc/tegra/flowctrl.c
index 221202db3313..d5c3af586d31 100644
--- a/drivers/soc/tegra/flowctrl.c
+++ b/drivers/soc/tegra/flowctrl.c
@@ -195,11 +195,14 @@ static int __init tegra_flowctrl_init(void)
np = of_find_matching_node(NULL, tegra_flowctrl_match);
if (np) {
- if (of_address_to_resource(np, 0, &res) < 0) {
+ int err = of_address_to_resource(np, 0, &res);
+
+ of_node_put(np);
+
+ if (err < 0) {
pr_err("failed to get flowctrl register\n");
return -ENXIO;
}
- of_node_put(np);
} else if (IS_ENABLED(CONFIG_ARM)) {
/*
* Hardcoded fallback for 32-bit Tegra
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index 39654964c35c..04075e2b6434 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -34,6 +34,7 @@ static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
[TEGRA_REVISION_A03] = "A03",
[TEGRA_REVISION_A03p] = "A03 prime",
[TEGRA_REVISION_A04] = "A04",
+ [TEGRA_REVISION_B01] = "B01",
};
static const char *tegra_platform_name[TEGRA_PLATFORM_MAX] = {
@@ -65,6 +66,9 @@ static struct tegra_fuse *fuse = &(struct tegra_fuse) {
};
static const struct of_device_id tegra_fuse_match[] = {
+#ifdef CONFIG_ARCH_TEGRA_264_SOC
+ { .compatible = "nvidia,tegra264-efuse", .data = &tegra264_fuse_soc },
+#endif
#ifdef CONFIG_ARCH_TEGRA_234_SOC
{ .compatible = "nvidia,tegra234-efuse", .data = &tegra234_fuse_soc },
#endif
@@ -176,6 +180,11 @@ static int tegra_fuse_probe(struct platform_device *pdev)
fuse->soc = &tegra241_fuse_soc;
break;
#endif
+#if defined(CONFIG_ARCH_TEGRA_264_SOC)
+ case TEGRA264:
+ fuse->soc = &tegra264_fuse_soc;
+ break;
+#endif
default:
return dev_err_probe(&pdev->dev, -EINVAL, "Unsupported SoC: %02x\n", chip);
}
@@ -413,7 +422,8 @@ const struct attribute_group tegra_soc_attr_group = {
#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \
- IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC)
+ IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC) || \
+ IS_ENABLED(CONFIG_ARCH_TEGRA_264_SOC)
static ssize_t platform_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c
index 2fad8b13a3b9..623848116b69 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra30.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra30.c
@@ -39,7 +39,8 @@
defined(CONFIG_ARCH_TEGRA_186_SOC) || \
defined(CONFIG_ARCH_TEGRA_194_SOC) || \
defined(CONFIG_ARCH_TEGRA_234_SOC) || \
- defined(CONFIG_ARCH_TEGRA_241_SOC)
+ defined(CONFIG_ARCH_TEGRA_241_SOC) || \
+ defined(CONFIG_ARCH_TEGRA_264_SOC)
static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset)
{
if (WARN_ON(!fuse->base))
@@ -802,3 +803,168 @@ const struct tegra_fuse_soc tegra241_fuse_soc = {
.soc_attr_group = &tegra194_soc_attr_group,
};
#endif
+
+#ifdef CONFIG_ARCH_TEGRA_264_SOC
+static const struct nvmem_keepout tegra264_fuse_keepouts[] = {
+ { .start = 0x0019c, .end = 0x001a0 },
+ { .start = 0x00308, .end = 0x00310 },
+ { .start = 0x0032c, .end = 0x00334 },
+ { .start = 0x00350, .end = 0x00354 },
+ { .start = 0x00494, .end = 0x0049c },
+ { .start = 0x0078c, .end = 0x00790 },
+ { .start = 0x007a0, .end = 0x007a8 },
+ { .start = 0x007dc, .end = 0x007e4 },
+ { .start = 0x008d8, .end = 0x008dc },
+ { .start = 0x0096c, .end = 0x00970 },
+ { .start = 0x00974, .end = 0x0097c },
+ { .start = 0x009f4, .end = 0x009f8 },
+ { .start = 0x00a14, .end = 0x00a20 },
+ { .start = 0x00a44, .end = 0x00a4c },
+ { .start = 0x00a50, .end = 0x00a58 },
+ { .start = 0x00a5c, .end = 0x00a64 },
+ { .start = 0x00a68, .end = 0x00a70 },
+ { .start = 0x00acc, .end = 0x00ad0 },
+ { .start = 0x00b0c, .end = 0x00b18 },
+ { .start = 0x00c80, .end = 0x00c8c },
+ { .start = 0x00dac, .end = 0x00db4 },
+ { .start = 0x00db8, .end = 0x00dbc },
+ { .start = 0x00e0c, .end = 0x00e10 },
+ { .start = 0x00fd0, .end = 0x01f00 },
+ { .start = 0x01f1c, .end = 0x10064 },
+ { .start = 0x10084, .end = 0x100a0 },
+ { .start = 0x100a4, .end = 0x1019c },
+ { .start = 0x101a0, .end = 0x101cc },
+ { .start = 0x101d0, .end = 0x10308 },
+ { .start = 0x10310, .end = 0x1055c },
+ { .start = 0x1057c, .end = 0x106b0 },
+ { .start = 0x106b4, .end = 0x11008 },
+ { .start = 0x1100c, .end = 0x11018 },
+ { .start = 0x11020, .end = 0x110b8 },
+ { .start = 0x110c4, .end = 0x110c8 },
+ { .start = 0x110e8, .end = 0x110ec },
+ { .start = 0x110f0, .end = 0x11124 },
+ { .start = 0x11128, .end = 0x11168 },
+ { .start = 0x1116c, .end = 0x111b8 },
+ { .start = 0x111bc, .end = 0x111e4 },
+ { .start = 0x111e8, .end = 0x111ec },
+ { .start = 0x111f0, .end = 0x1121c },
+ { .start = 0x11250, .end = 0x1133c },
+ { .start = 0x11340, .end = 0x113c8 },
+ { .start = 0x113d0, .end = 0x11420 },
+ { .start = 0x11430, .end = 0x11440 },
+ { .start = 0x11444, .end = 0x11468 },
+ { .start = 0x1146c, .end = 0x114a8 },
+ { .start = 0x114ac, .end = 0x115cc },
+ { .start = 0x115d0, .end = 0x115dc },
+ { .start = 0x115e0, .end = 0x116b4 },
+ { .start = 0x116bc, .end = 0x11740 },
+ { .start = 0x11744, .end = 0x117b8 },
+ { .start = 0x117bc, .end = 0x11810 },
+ { .start = 0x11814, .end = 0x11850 },
+ { .start = 0x11858, .end = 0x118a0 },
+ { .start = 0x118ac, .end = 0x11b48 },
+ { .start = 0x11b50, .end = 0x11b5c },
+ { .start = 0x11b60, .end = 0x11bf8 },
+ { .start = 0x11bfc, .end = 0x11c18 },
+ { .start = 0x11c40, .end = 0x12000 },
+ { .start = 0x12004, .end = 0x12010 },
+ { .start = 0x12014, .end = 0x120fc },
+ { .start = 0x1211c, .end = 0x12120 },
+ { .start = 0x12124, .end = 0x12144 },
+ { .start = 0x1214c, .end = 0x12300 },
+ { .start = 0x12308, .end = 0x1236c },
+ { .start = 0x12370, .end = 0x126ac },
+ { .start = 0x126b0, .end = 0x12c60 },
+ { .start = 0x12c64, .end = 0x12d94 },
+ { .start = 0x12da4, .end = 0x13004 },
+ { .start = 0x13008, .end = 0x1300c },
+ { .start = 0x13010, .end = 0x13014 },
+ { .start = 0x13018, .end = 0x13020 },
+ { .start = 0x13064, .end = 0x13084 },
+ { .start = 0x130a0, .end = 0x130a4 },
+ { .start = 0x130b8, .end = 0x130c4 },
+ { .start = 0x130c8, .end = 0x130e8 },
+ { .start = 0x130ec, .end = 0x130f0 },
+ { .start = 0x130fc, .end = 0x1311c },
+ { .start = 0x13120, .end = 0x13128 },
+ { .start = 0x13144, .end = 0x1314c },
+ { .start = 0x13168, .end = 0x1316c },
+ { .start = 0x1319c, .end = 0x131a0 },
+ { .start = 0x131ac, .end = 0x131c0 },
+ { .start = 0x131cc, .end = 0x131d0 },
+ { .start = 0x131e4, .end = 0x131e8 },
+ { .start = 0x131ec, .end = 0x131f0 },
+ { .start = 0x1321c, .end = 0x13250 },
+ { .start = 0x132f0, .end = 0x13310 },
+ { .start = 0x1332c, .end = 0x13334 },
+ { .start = 0x1333c, .end = 0x13344 },
+ { .start = 0x13350, .end = 0x13354 },
+ { .start = 0x1336c, .end = 0x13370 },
+ { .start = 0x133ac, .end = 0x133b0 },
+ { .start = 0x133c8, .end = 0x133d0 },
+ { .start = 0x13420, .end = 0x13430 },
+ { .start = 0x13440, .end = 0x13444 },
+ { .start = 0x13468, .end = 0x13470 },
+ { .start = 0x13494, .end = 0x1349c },
+ { .start = 0x134a8, .end = 0x134ac },
+ { .start = 0x13544, .end = 0x1354c },
+ { .start = 0x1355c, .end = 0x1357c },
+ { .start = 0x135cc, .end = 0x135e0 },
+ { .start = 0x135e4, .end = 0x13608 },
+ { .start = 0x1360c, .end = 0x13620 },
+ { .start = 0x136ac, .end = 0x136bc },
+ { .start = 0x136c0, .end = 0x136c8 },
+ { .start = 0x13714, .end = 0x13718 },
+ { .start = 0x13724, .end = 0x13728 },
+ { .start = 0x1372c, .end = 0x13730 },
+ { .start = 0x13734, .end = 0x1373c },
+ { .start = 0x13740, .end = 0x13744 },
+ { .start = 0x13754, .end = 0x13758 },
+ { .start = 0x13760, .end = 0x13784 },
+ { .start = 0x1378c, .end = 0x13790 },
+ { .start = 0x137a0, .end = 0x137a8 },
+ { .start = 0x137b8, .end = 0x137bc },
+ { .start = 0x137dc, .end = 0x137e4 },
+ { .start = 0x137ec, .end = 0x137f0 },
+ { .start = 0x13800, .end = 0x13818 },
+ { .start = 0x13820, .end = 0x13828 },
+ { .start = 0x13830, .end = 0x13858 },
+ { .start = 0x138a0, .end = 0x138b0 },
+ { .start = 0x138d0, .end = 0x138dc },
+ { .start = 0x1396c, .end = 0x13970 },
+ { .start = 0x13974, .end = 0x1397c },
+ { .start = 0x139f4, .end = 0x139f8 },
+ { .start = 0x13a14, .end = 0x13a20 },
+ { .start = 0x13a44, .end = 0x13a4c },
+ { .start = 0x13a50, .end = 0x13a58 },
+ { .start = 0x13a5c, .end = 0x13a64 },
+ { .start = 0x13a68, .end = 0x13a70 },
+ { .start = 0x13acc, .end = 0x13ad8 },
+ { .start = 0x13b0c, .end = 0x13b18 },
+ { .start = 0x13b48, .end = 0x13b50 },
+ { .start = 0x13b5c, .end = 0x13b60 },
+ { .start = 0x13bf8, .end = 0x13bfc },
+ { .start = 0x13c18, .end = 0x13c40 },
+ { .start = 0x13c60, .end = 0x13c64 },
+ { .start = 0x13c74, .end = 0x13c8c },
+ { .start = 0x13d94, .end = 0x13da4 },
+ { .start = 0x13dac, .end = 0x13db4 },
+ { .start = 0x13db8, .end = 0x13dbc },
+ { .start = 0x13df4, .end = 0x13e04 },
+ { .start = 0x13e0c, .end = 0x13e10 },
+};
+
+static const struct tegra_fuse_info tegra264_fuse_info = {
+ .read = tegra30_fuse_read,
+ .size = 0x13eb8,
+};
+
+const struct tegra_fuse_soc tegra264_fuse_soc = {
+ .init = tegra30_fuse_init,
+ .info = &tegra264_fuse_info,
+ .keepouts = tegra264_fuse_keepouts,
+ .num_keepouts = ARRAY_SIZE(tegra264_fuse_keepouts),
+ .soc_attr_group = &tegra194_soc_attr_group,
+ .clk_suspend_on = false,
+};
+#endif
diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h
index 9fee6ad6ad9e..0fb97508db0a 100644
--- a/drivers/soc/tegra/fuse/fuse.h
+++ b/drivers/soc/tegra/fuse/fuse.h
@@ -125,7 +125,8 @@ extern const struct tegra_fuse_soc tegra186_fuse_soc;
#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \
- IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC)
+ IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC) || \
+ IS_ENABLED(CONFIG_ARCH_TEGRA_264_SOC)
extern const struct attribute_group tegra194_soc_attr_group;
#endif
@@ -141,4 +142,8 @@ extern const struct tegra_fuse_soc tegra234_fuse_soc;
extern const struct tegra_fuse_soc tegra241_fuse_soc;
#endif
+#ifdef CONFIG_ARCH_TEGRA_264_SOC
+extern const struct tegra_fuse_soc tegra264_fuse_soc;
+#endif
+
#endif
diff --git a/drivers/soc/tegra/fuse/speedo-tegra210.c b/drivers/soc/tegra/fuse/speedo-tegra210.c
index 06c2bcbee573..699751f4bd0c 100644
--- a/drivers/soc/tegra/fuse/speedo-tegra210.c
+++ b/drivers/soc/tegra/fuse/speedo-tegra210.c
@@ -65,7 +65,25 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
sku_info->gpu_speedo_id = 0;
*threshold = THRESHOLD_INDEX_0;
- if (sku_info->revision >= TEGRA_REVISION_A02) {
+ if (sku_info->revision >= TEGRA_REVISION_B01) {
+ sku_info->gpu_speedo_id = 1;
+
+ switch (sku) {
+ case 0x00: /* Engineering SKU */
+ case 0x01: /* Engineering SKU */
+ case 0x83:
+ break;
+
+ case 0x87:
+ sku_info->cpu_speedo_id = 3;
+ break;
+
+ default:
+ pr_err("Tegra210B01: unknown SKU %#04x\n", sku);
+ /* Using the default for the error case */
+ break;
+ }
+ } else if (sku_info->revision >= TEGRA_REVISION_A02) {
switch (sku) {
case 0x00: /* Engineering SKU */
case 0x01: /* Engineering SKU */
@@ -154,7 +172,7 @@ void __init tegra210_init_speedo_data(struct tegra_sku_info *sku_info)
speedo_revision = get_speedo_revision();
pr_info("Speedo Revision %u\n", speedo_revision);
- if (speedo_revision >= 3) {
+ if (sku_info->revision == TEGRA_REVISION_B01 || speedo_revision >= 3) {
sku_info->cpu_speedo_value = cpu_speedo[0];
sku_info->gpu_speedo_value = cpu_speedo[2];
sku_info->soc_speedo_value = soc_speedo[0];
diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c
index f86c88fab168..3ad4629335fe 100644
--- a/drivers/soc/tegra/fuse/tegra-apbmisc.c
+++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c
@@ -167,30 +167,41 @@ static const struct of_device_id apbmisc_match[] __initconst = {
void __init tegra_init_revision(void)
{
- u8 chip_id, minor_rev;
+ u8 chip_id, major_rev, minor_rev;
chip_id = tegra_get_chip_id();
+ major_rev = tegra_get_major_rev();
minor_rev = tegra_get_minor_rev();
- switch (minor_rev) {
- case 1:
- tegra_sku_info.revision = TEGRA_REVISION_A01;
- break;
- case 2:
- tegra_sku_info.revision = TEGRA_REVISION_A02;
- break;
- case 3:
- if (chip_id == TEGRA20 && (tegra_fuse_read_spare(18) ||
- tegra_fuse_read_spare(19)))
- tegra_sku_info.revision = TEGRA_REVISION_A03p;
- else
- tegra_sku_info.revision = TEGRA_REVISION_A03;
- break;
- case 4:
- tegra_sku_info.revision = TEGRA_REVISION_A04;
- break;
- default:
- tegra_sku_info.revision = TEGRA_REVISION_UNKNOWN;
+ if (major_rev > 1) {
+ switch (minor_rev) {
+ case 1:
+ tegra_sku_info.revision = TEGRA_REVISION_B01;
+ break;
+ default:
+ tegra_sku_info.revision = TEGRA_REVISION_UNKNOWN;
+ }
+ } else {
+ switch (minor_rev) {
+ case 1:
+ tegra_sku_info.revision = TEGRA_REVISION_A01;
+ break;
+ case 2:
+ tegra_sku_info.revision = TEGRA_REVISION_A02;
+ break;
+ case 3:
+ if (chip_id == TEGRA20 && (tegra_fuse_read_spare(18) ||
+ tegra_fuse_read_spare(19)))
+ tegra_sku_info.revision = TEGRA_REVISION_A03p;
+ else
+ tegra_sku_info.revision = TEGRA_REVISION_A03;
+ break;
+ case 4:
+ tegra_sku_info.revision = TEGRA_REVISION_A04;
+ break;
+ default:
+ tegra_sku_info.revision = TEGRA_REVISION_UNKNOWN;
+ }
}
tegra_sku_info.sku_id = tegra_fuse_read_early(FUSE_SKU_INFO);
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index ea4dfe1994bd..2c70eedf514e 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -11,6 +11,7 @@
#define pr_fmt(fmt) "tegra-pmc: " fmt
+#include <linux/acpi.h>
#include <linux/arm-smccc.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
@@ -2694,7 +2695,7 @@ tegra_pmc_clk_out_register(struct tegra_pmc *pmc,
const struct pmc_clk_init_data *data,
unsigned long offset)
{
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct pmc_clk *pmc_clk;
pmc_clk = devm_kzalloc(pmc->dev, sizeof(*pmc_clk), GFP_KERNEL);
@@ -2752,7 +2753,7 @@ tegra_pmc_clk_gate_register(struct tegra_pmc *pmc, const char *name,
const char *parent_name, unsigned long offset,
u32 shift)
{
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct pmc_clk_gate *gate;
gate = devm_kzalloc(pmc->dev, sizeof(*gate), GFP_KERNEL);
@@ -2980,6 +2981,18 @@ static void tegra_pmc_reset_suspend_mode(void *data)
pmc->suspend_mode = TEGRA_SUSPEND_NOT_READY;
}
+static int tegra_pmc_acpi_probe(struct platform_device *pdev, struct tegra_pmc *pmc)
+{
+ pmc->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(pmc->base))
+ return PTR_ERR(pmc->base);
+
+ tegra_pmc_reset_sysfs_init(pmc);
+ platform_set_drvdata(pdev, pmc);
+
+ return 0;
+}
+
static int tegra_pmc_probe(struct platform_device *pdev)
{
struct tegra_pmc *pmc;
@@ -3004,6 +3017,9 @@ static int tegra_pmc_probe(struct platform_device *pdev)
mutex_init(&pmc->powergates_lock);
pmc->dev = &pdev->dev;
+ if (is_acpi_node(dev_fwnode(&pdev->dev)))
+ return tegra_pmc_acpi_probe(pdev, pmc);
+
err = tegra_pmc_parse_dt(pmc, pdev->dev.of_node);
if (err < 0)
return dev_err_probe(&pdev->dev, err, "failed to parse DT\n");
@@ -3901,6 +3917,67 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
.has_single_mmio_aperture = true,
};
+static const char * const tegra210b01_powergates[] = {
+ [TEGRA_POWERGATE_CPU] = "crail",
+ [TEGRA_POWERGATE_3D] = "3d",
+ [TEGRA_POWERGATE_VENC] = "venc",
+ [TEGRA_POWERGATE_PCIE] = "pcie",
+ [TEGRA_POWERGATE_MPE] = "mpe",
+ [TEGRA_POWERGATE_CPU1] = "cpu1",
+ [TEGRA_POWERGATE_CPU2] = "cpu2",
+ [TEGRA_POWERGATE_CPU3] = "cpu3",
+ [TEGRA_POWERGATE_CPU0] = "cpu0",
+ [TEGRA_POWERGATE_C0NC] = "c0nc",
+ [TEGRA_POWERGATE_SOR] = "sor",
+ [TEGRA_POWERGATE_DIS] = "dis",
+ [TEGRA_POWERGATE_DISB] = "disb",
+ [TEGRA_POWERGATE_XUSBA] = "xusba",
+ [TEGRA_POWERGATE_XUSBB] = "xusbb",
+ [TEGRA_POWERGATE_XUSBC] = "xusbc",
+ [TEGRA_POWERGATE_VIC] = "vic",
+ [TEGRA_POWERGATE_IRAM] = "iram",
+ [TEGRA_POWERGATE_NVDEC] = "nvdec",
+ [TEGRA_POWERGATE_NVJPG] = "nvjpg",
+ [TEGRA_POWERGATE_AUD] = "aud",
+ [TEGRA_POWERGATE_DFD] = "dfd",
+};
+
+static const struct tegra_pmc_soc tegra210b01_pmc_soc = {
+ .supports_core_domain = false,
+ .num_powergates = ARRAY_SIZE(tegra210b01_powergates),
+ .powergates = tegra210b01_powergates,
+ .num_cpu_powergates = ARRAY_SIZE(tegra210_cpu_powergates),
+ .cpu_powergates = tegra210_cpu_powergates,
+ .has_tsense_reset = true,
+ .has_gpu_clamps = true,
+ .needs_mbist_war = false,
+ .has_io_pad_wren = true,
+ .maybe_tz_only = true,
+ .num_io_pads = ARRAY_SIZE(tegra210_io_pads),
+ .io_pads = tegra210_io_pads,
+ .num_io_pad_vctrls = ARRAY_SIZE(tegra210_io_pad_vctrls),
+ .io_pad_vctrls = tegra210_io_pad_vctrls,
+ .num_pin_descs = ARRAY_SIZE(tegra210_pin_descs),
+ .pin_descs = tegra210_pin_descs,
+ .regs = &tegra20_pmc_regs,
+ .init = tegra20_pmc_init,
+ .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+ .powergate_set = tegra114_powergate_set,
+ .irq_set_wake = tegra210_pmc_irq_set_wake,
+ .irq_set_type = tegra210_pmc_irq_set_type,
+ .reset_sources = tegra210_reset_sources,
+ .num_reset_sources = ARRAY_SIZE(tegra210_reset_sources),
+ .reset_levels = NULL,
+ .num_reset_levels = 0,
+ .num_wake_events = ARRAY_SIZE(tegra210_wake_events),
+ .wake_events = tegra210_wake_events,
+ .pmc_clks_data = tegra_pmc_clks_data,
+ .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+ .has_blink_output = true,
+ .has_usb_sleepwalk = true,
+ .has_single_mmio_aperture = true,
+};
+
static const struct tegra_io_pad_soc tegra186_io_pads[] = {
TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, "csia"),
TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, "csib"),
@@ -4422,6 +4499,7 @@ static const char * const tegra234_reset_sources[] = {
};
static const struct tegra_wake_event tegra234_wake_events[] = {
+ TEGRA_WAKE_GPIO("pcie-wake", 1, 0, TEGRA234_MAIN_GPIO(L, 2)),
TEGRA_WAKE_GPIO("sd-wake", 8, 0, TEGRA234_MAIN_GPIO(G, 7)),
TEGRA_WAKE_GPIO("eqos", 20, 0, TEGRA234_MAIN_GPIO(G, 4)),
TEGRA_WAKE_IRQ("pmu", 24, 209),
@@ -4821,6 +4899,81 @@ static const struct tegra_pmc_soc tegra264_pmc_soc = {
.max_wake_vectors = 4,
};
+static const char * const tegra410_reset_sources[] = {
+ "SYS_RESET_N", /* 0x0 */
+ "CSDC_RTC_XTAL",
+ "VREFRO_POWER_BAD",
+ "FMON_32K",
+ "FMON_OSC",
+ "POD_RTC",
+ "POD_IO",
+ "POD_PLUS_IO_SPLL",
+ "POD_PLUS_IO_VMON", /* 0x8 */
+ "POD_PLUS_SOC",
+ "VMON_PLUS_UV",
+ "VMON_PLUS_OV",
+ "FUSECRC_FAULT",
+ "OSC_FAULT",
+ "BPMP_BOOT_FAULT",
+ "SCPM_BPMP_CORE_CLK",
+ "SCPM_PSC_SE_CLK", /* 0x10 */
+ "VMON_SOC_MIN",
+ "VMON_SOC_MAX",
+ "NVJTAG_SEL_MONITOR",
+ "L0_RST_REQ_N",
+ "NV_THERM_FAULT",
+ "PSC_SW",
+ "POD_C2C_LPI_0",
+ "POD_C2C_LPI_1", /* 0x18 */
+ "BPMP_FMON",
+ "FMON_SPLL_OUT",
+ "L1_RST_REQ_N",
+ "OCP_RECOVERY",
+ "AO_WDT_POR",
+ "BPMP_WDT_POR",
+ "RAS_WDT_POR",
+ "TOP_0_WDT_POR", /* 0x20 */
+ "TOP_1_WDT_POR",
+ "TOP_2_WDT_POR",
+ "PSC_WDT_POR",
+ "OOBHUB_WDT_POR",
+ "MSS_SEQ_WDT_POR",
+ "SW_MAIN",
+ "L0L1_RST_OUT_N",
+ "HSM", /* 0x28 */
+ "CSITE_SW",
+ "AO_WDT_DBG",
+ "BPMP_WDT_DBG",
+ "RAS_WDT_DBG",
+ "TOP_0_WDT_DBG",
+ "TOP_1_WDT_DBG",
+ "TOP_2_WDT_DBG",
+ "PSC_WDT_DBG", /* 0x30 */
+ "TSC_0_WDT_DBG",
+ "TSC_1_WDT_DBG",
+ "OOBHUB_WDT_DBG",
+ "MSS_SEQ_WDT_DBG",
+ "L2_RST_REQ_N",
+ "L2_RST_OUT_N",
+ "SC7"
+};
+
+static const struct tegra_pmc_regs tegra410_pmc_regs = {
+ .rst_status = 0x8,
+ .rst_source_shift = 0x2,
+ .rst_source_mask = 0xfc,
+ .rst_level_shift = 0x0,
+ .rst_level_mask = 0x3,
+};
+
+static const struct tegra_pmc_soc tegra410_pmc_soc = {
+ .regs = &tegra410_pmc_regs,
+ .reset_sources = tegra410_reset_sources,
+ .num_reset_sources = ARRAY_SIZE(tegra410_reset_sources),
+ .reset_levels = tegra186_reset_levels,
+ .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
+};
+
static const struct of_device_id tegra_pmc_match[] = {
{ .compatible = "nvidia,tegra264-pmc", .data = &tegra264_pmc_soc },
{ .compatible = "nvidia,tegra238-pmc", .data = &tegra238_pmc_soc },
@@ -4828,6 +4981,7 @@ static const struct of_device_id tegra_pmc_match[] = {
{ .compatible = "nvidia,tegra194-pmc", .data = &tegra194_pmc_soc },
{ .compatible = "nvidia,tegra186-pmc", .data = &tegra186_pmc_soc },
{ .compatible = "nvidia,tegra210-pmc", .data = &tegra210_pmc_soc },
+ { .compatible = "nvidia,tegra210b01-pmc", .data = &tegra210b01_pmc_soc },
{ .compatible = "nvidia,tegra132-pmc", .data = &tegra124_pmc_soc },
{ .compatible = "nvidia,tegra124-pmc", .data = &tegra124_pmc_soc },
{ .compatible = "nvidia,tegra114-pmc", .data = &tegra114_pmc_soc },
@@ -4836,6 +4990,12 @@ static const struct of_device_id tegra_pmc_match[] = {
{ }
};
+static const struct acpi_device_id tegra_pmc_acpi_match[] = {
+ { .id = "NVDA2016", .driver_data = (kernel_ulong_t)&tegra410_pmc_soc },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, tegra_pmc_acpi_match);
+
static void tegra_pmc_sync_state(struct device *dev)
{
struct tegra_pmc *pmc = dev_get_drvdata(dev);
@@ -4887,6 +5047,7 @@ static struct platform_driver tegra_pmc_driver = {
.name = "tegra-pmc",
.suppress_bind_attrs = true,
.of_match_table = tegra_pmc_match,
+ .acpi_match_table = tegra_pmc_acpi_match,
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
.pm = &tegra_pmc_pm_ops,
#endif
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index 3e4041454f69..6186454dff51 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -509,7 +509,7 @@ static int knav_queue_flush(struct knav_queue *qh)
/**
* knav_queue_open() - open a hardware queue
* @name: - name to give the queue handle
- * @id: - desired queue number if any or specifes the type
+ * @id: - desired queue number if any or specifies the type
* of queue
* @flags: - the following flags are applicable to queues:
* KNAV_QUEUE_SHARED - allow the queue to be shared. Queues are
@@ -805,7 +805,7 @@ void *knav_pool_create(const char *name,
}
/* Region maintains a sorted (by region offset) list of pools
- * use the first free slot which is large enough to accomodate
+ * use the first free slot which is large enough to accommodate
* the request
*/
last_offset = 0;
diff --git a/drivers/ufs/host/ufs-amd-versal2.c b/drivers/ufs/host/ufs-amd-versal2.c
index 2154d6286817..dff0c2c95486 100644
--- a/drivers/ufs/host/ufs-amd-versal2.c
+++ b/drivers/ufs/host/ufs-amd-versal2.c
@@ -225,8 +225,6 @@ static int ufs_versal2_setup_phy(struct ufs_hba *hba)
static int ufs_versal2_phy_init(struct ufs_hba *hba)
{
struct ufs_versal2_host *host = ufshcd_get_variant(hba);
- u32 time_left;
- bool is_ready;
int ret;
static const struct ufshcd_dme_attr_val rmmi_attrs[] = {
{ UIC_ARG_MIB(CBREFCLKCTRL2), CBREFREFCLK_GATE_OVR_EN, DME_LOCAL },
@@ -235,23 +233,15 @@ static int ufs_versal2_phy_init(struct ufs_hba *hba)
{ UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL }
};
- /* Wait for Tx/Rx config_rdy */
- time_left = TIMEOUT_MICROSEC;
- do {
- time_left--;
- ret = zynqmp_pm_is_mphy_tx_rx_config_ready(&is_ready);
- if (ret)
- return ret;
-
- if (!is_ready)
- break;
-
- usleep_range(1, 5);
- } while (time_left);
-
- if (!time_left) {
+ /*
+ * Wait for Tx/Rx config_rdy. The poll loop lives in the firmware
+ * backend (EEMI today, SCMI in future) so this driver stays
+ * backend-agnostic; the timeout budget stays here with the consumer.
+ */
+ ret = zynqmp_pm_wait_mphy_tx_rx_config_ready(TIMEOUT_MICROSEC);
+ if (ret) {
dev_err(hba->dev, "Tx/Rx configuration signal busy.\n");
- return -ETIMEDOUT;
+ return ret;
}
ret = ufshcd_dwc_dme_set_attrs(hba, rmmi_attrs, ARRAY_SIZE(rmmi_attrs));
@@ -264,23 +254,11 @@ static int ufs_versal2_phy_init(struct ufs_hba *hba)
return ret;
}
- /* Wait for SRAM init done */
- time_left = TIMEOUT_MICROSEC;
- do {
- time_left--;
- ret = zynqmp_pm_is_sram_init_done(&is_ready);
- if (ret)
- return ret;
-
- if (is_ready)
- break;
-
- usleep_range(1, 5);
- } while (time_left);
-
- if (!time_left) {
+ /* Wait for SRAM init done (poll handled by the firmware backend). */
+ ret = zynqmp_pm_wait_sram_init_done(TIMEOUT_MICROSEC);
+ if (ret) {
dev_err(hba->dev, "SRAM initialization failed.\n");
- return -ETIMEDOUT;
+ return ret;
}
ret = ufs_versal2_setup_phy(hba);
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c
index 71e785f445a3..d572f0c1dffa 100644
--- a/drivers/usb/host/fhci-hcd.c
+++ b/drivers/usb/host/fhci-hcd.c
@@ -643,7 +643,7 @@ static int of_fhci_probe(struct platform_device *ofdev)
}
for (j = 0; j < NUM_PINS; j++) {
- fhci->pins[j] = qe_pin_request(dev, j);
+ fhci->pins[j] = qe_pin_request(dev, fhci->gpiods[j]);
if (IS_ERR(fhci->pins[j])) {
ret = PTR_ERR(fhci->pins[j]);
dev_err(dev, "can't get pin %d: %d\n", j, ret);
diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h
index b63e4a0b8e54..135297027580 100644
--- a/include/dt-bindings/arm/qcom,ids.h
+++ b/include/dt-bindings/arm/qcom,ids.h
@@ -301,8 +301,10 @@
#define QCOM_ID_QCS9075 676
#define QCOM_ID_QCS615 680
#define QCOM_ID_SA8797P 690
+#define QCOM_ID_SM8975 707
#define QCOM_ID_CQ7790M 731
#define QCOM_ID_CQ7790S 732
+#define QCOM_ID_SM8950 735
#define QCOM_ID_CQ2390M 756
#define QCOM_ID_CQ2390S 758
#define QCOM_ID_IQ2390S 759
diff --git a/include/dt-bindings/clock/starfive,jhb100-crg.h b/include/dt-bindings/clock/starfive,jhb100-crg.h
new file mode 100644
index 000000000000..4270bfa532e8
--- /dev/null
+++ b/include/dt-bindings/clock/starfive,jhb100-crg.h
@@ -0,0 +1,554 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__
+#define __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__
+
+/* SYS0PLL clocks */
+#define JHB100_SYS0PLL_PLL2_OUT 0
+#define JHB100_SYS0PLL_PLL3_OUT 1
+#define JHB100_SYS0PLL_PLL4_OUT 2
+#define JHB100_SYS0PLL_PLL5_OUT 3
+
+/* PER0PLL clocks */
+#define JHB100_PER0PLL_PLL6_OUT 0
+
+/* PER1PLL clocks */
+#define JHB100_PER1PLL_PLL7_OUT 0
+
+/* SYS0CRG clocks */
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_MAIN 17
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_CFG 18
+
+#define JHB100_SYS0CLK_PCIE_REF_CML 20
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_DATA_INIT 21
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_CFG_INIT 22
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_TARG 23
+
+#define JHB100_SYS0CLK_BMCPCIERP_PCU 26
+#define JHB100_SYS0CLK_HOSTSS0_NCNOC_CFG 27
+#define JHB100_SYS0CLK_HOSTSS0_NCNOC_DATA 28
+#define JHB100_SYS0CLK_HOSTSS0_PHY_SCAN_400 29
+#define JHB100_SYS0CLK_GPIO_ESPI0_EXT 30
+
+#define JHB100_SYS0CLK_BMCUSB_NCNOC_INIT 34
+#define JHB100_SYS0CLK_BMCUSB_NCNOC_TARG 35
+#define JHB100_SYS0CLK_BMCUSB_SCANCLK 36
+#define JHB100_SYS0CLK_BMCUSB_480M_SCANCLK 37
+
+#define JHB100_SYS0CLK_VCE_NCNOC_INIT 50
+#define JHB100_SYS0CLK_VCE_NCNOC_TARG 51
+#define JHB100_SYS0CLK_BMCPER2_NCNOC_INIT 52
+#define JHB100_SYS0CLK_BMCPER2_NCNOC_TARG 53
+#define JHB100_SYS0CLK_BMCPER2_CFG_400 54
+#define JHB100_SYS0CLK_BMCPER2_CFG_125 55
+
+#define JHB100_SYS0CLK_HOSTSS1_NCNOC_DATA 58
+#define JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400 59
+#define JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400_ICG_BUF 60
+#define JHB100_SYS0CLK_NPU_NCNOC_INIT 61
+#define JHB100_SYS0CLK_VOUT_NCNOC_INIT 62
+#define JHB100_SYS0CLK_VOUT_AUX 63
+
+#define JHB100_SYS0CLK_BMCPER3_NCNOC_INIT 65
+#define JHB100_SYS0CLK_HOSTUSB_NCNOC_INIT 66
+#define JHB100_SYS0CLK_HOSTUSBCMN_CFG_480 67
+#define JHB100_SYS0CLK_BMCPER1_NCNOC_INIT 68
+#define JHB100_SYS0CLK_BMCPER1_CFG_800 69
+#define JHB100_SYS0CLK_BMCPER0_NCNOC_INIT 70
+#define JHB100_SYS0CLK_BMCPER0_CFG_400 71
+#define JHB100_SYS0CLK_BMCPER0_CFG_800 72
+#define JHB100_SYS0CLK_GPU0_NCNOC_INIT 73
+#define JHB100_SYS0CLK_GPU1_NCNOC_INIT 74
+
+/* SYS1CRG clocks */
+#define JHB100_SYS1CLK_APB_MAIN_SYS1 0
+#define JHB100_SYS1CLK_APB_SENSOR_ICG_BUF 1
+
+#define JHB100_SYS1CLK_GPIO_ESPI1_EXT 5
+
+#define JHB100_SYS1CLK_HOSTSS1_NCNOC_CFG 7
+#define JHB100_SYS1CLK_HOSTSS1_PHY_SCAN_1000_ICG_BUF 8
+#define JHB100_SYS1CLK_NPU_NCNOC_CFG 9
+#define JHB100_SYS1CLK_NPU_CORE_DIV 10
+#define JHB100_SYS1CLK_DOM_NPU_CORE_CLK 11
+#define JHB100_SYS1CLK_DOM_NPU_BUS_CLK 12
+#define JHB100_SYS1CLK_DOM_NPU_INIT_CLK 13
+#define JHB100_SYS1CLK_DOM_NPU_OSC_CLK 14
+#define JHB100_SYS1CLK_VOUT_NCNOC_TARG 15
+#define JHB100_SYS1CLK_VOUT_PIX0 16
+#define JHB100_SYS1CLK_VOUT_PIX1 17
+#define JHB100_SYS1CLK_BMCPER3_NCNOC_TARG 18
+#define JHB100_SYS1CLK_BMCPER3_CFG_125 19
+
+/* SYS2CRG clocks */
+#define JHB100_SYS2CLK_JTAGM0_HCLK 3
+#define JHB100_SYS2CLK_JTAGM1_HCLK 4
+#define JHB100_SYS2CLK_JTAGM0_ATPG 5
+#define JHB100_SYS2CLK_JTAGM1_ATPG 6
+#define JHB100_SYS2CLK_JTAGM0_ATPG_TCLOCK 7
+#define JHB100_SYS2CLK_JTAGM1_ATPG_TCLOCK 8
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_HCLK 9
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_CLK_JTAG 10
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_APB_PCLK 11
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_ATPG_TCLOCK 12
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_HCLK 13
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_CLK_JTAG 14
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_APB_PCLK 15
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_ATPG_TCLOCK 16
+#define JHB100_SYS2CLK_HOSTUSB_NCNOC_TARG 17
+#define JHB100_SYS2CLK_HOSTUSBCMN_CFG_500 18
+#define JHB100_SYS2CLK_BMCPER1_NCNOC_TARG 19
+#define JHB100_SYS2CLK_BMCPER1_CFG_250 20
+#define JHB100_SYS2CLK_BMCPER1_CFG_143_DFT 21
+#define JHB100_SYS2CLK_BMCPER1_CFG_143 22
+#define JHB100_SYS2CLK_BMCPER0_NCNOC_TARG 23
+#define JHB100_SYS2CLK_GPU0_NCNOC_TARG 24
+#define JHB100_SYS2CLK_GPU0_BUS_CLK 25
+#define JHB100_SYS2CLK_GPU0_APB_CLK 26
+#define JHB100_SYS2CLK_GPU0_OSC_CLK 27
+#define JHB100_SYS2CLK_GPU1_NCNOC_TARG 28
+#define JHB100_SYS2CLK_GPU1_BUS_CLK 29
+#define JHB100_SYS2CLK_GPU1_APB_CLK 30
+#define JHB100_SYS2CLK_GPU1_OSC_CLK 31
+#define JHB100_SYS2CLK_MAIN_ICG_EN_JTAG0 32
+#define JHB100_SYS2CLK_MAIN_ICG_EN_JTAG1 33
+
+/* PER0CRG clocks */
+#define JHB100_PER0CLK_CDR_I3C0 0
+#define JHB100_PER0CLK_CDR_I3C1 1
+#define JHB100_PER0CLK_CDR_I3C2 2
+#define JHB100_PER0CLK_CDR_I3C3 3
+#define JHB100_PER0CLK_CDR_I3C4 4
+#define JHB100_PER0CLK_CDR_I3C5 5
+#define JHB100_PER0CLK_CDR_I3C6 6
+#define JHB100_PER0CLK_CDR_I3C7 7
+#define JHB100_PER0CLK_CDR_I3C8 8
+#define JHB100_PER0CLK_CDR_I3C9 9
+#define JHB100_PER0CLK_CDR_I3C10 10
+#define JHB100_PER0CLK_CDR_I3C11 11
+#define JHB100_PER0CLK_CDR_I3C12 12
+#define JHB100_PER0CLK_CDR_I3C13 13
+#define JHB100_PER0CLK_CDR_I3C14 14
+#define JHB100_PER0CLK_CDR_I3C15 15
+#define JHB100_PER0CLK_200 16
+#define JHB100_PER0CLK_600_DIV6 17
+#define JHB100_PER0CLK_600_DIV6_DIV5 18
+#define JHB100_PER0CLK_TIMER0_DUALTIMER0 19
+#define JHB100_PER0CLK_TIMER1_DUALTIMER0 20
+#define JHB100_PER0CLK_TIMER0_DUALTIMER1 21
+#define JHB100_PER0CLK_TIMER1_DUALTIMER1 22
+#define JHB100_PER0CLK_TIMER0_DUALTIMER2 23
+#define JHB100_PER0CLK_TIMER1_DUALTIMER2 24
+#define JHB100_PER0CLK_1200_PH0_LVDS0 25
+#define JHB100_PER0CLK_1200_PH0_LVDS1 26
+#define JHB100_PER0CLK_1200_CORE0 27
+#define JHB100_PER0CLK_1200_CORE1 28
+#define JHB100_PER0CLK_1200_SHIFT90_LVDS0 29
+#define JHB100_PER0CLK_1200_SHIFT90_LVDS1 30
+#define JHB100_PER0CLK_1200_DIV5_CORE0 31
+#define JHB100_PER0CLK_1200_DIV5_CORE1 32
+#define JHB100_PER0CLK_PH0_LTPI0 33
+
+#define JHB100_PER0CLK_PH0_LTPI1 35
+
+#define JHB100_PER0CLK_PH90_LTPI0 37
+
+#define JHB100_PER0CLK_PH90_LTPI1 39
+
+#define JHB100_PER0CLK_240_CORE_LTPI0 41
+
+#define JHB100_PER0CLK_240_CORE_LTPI1 43
+
+#define JHB100_PER0CLK_AXI_DMA_I2C_INIT 45
+#define JHB100_PER0CLK_AXI_DMA_I3C_INIT 46
+#define JHB100_PER0CLK_AXI_DMA_UART_INIT 47
+#define JHB100_PER0CLK_CORE_DMAC0 48
+#define JHB100_PER0CLK_CORE_DMAC1 49
+#define JHB100_PER0CLK_CORE_DMAC2 50
+
+#define JHB100_PER0CLK_HDR_TX_I3C0 78
+#define JHB100_PER0CLK_HDR_TX_I3C1 79
+#define JHB100_PER0CLK_HDR_TX_I3C2 80
+#define JHB100_PER0CLK_HDR_TX_I3C3 81
+#define JHB100_PER0CLK_HDR_TX_I3C4 82
+#define JHB100_PER0CLK_HDR_TX_I3C5 83
+#define JHB100_PER0CLK_HDR_TX_I3C6 84
+#define JHB100_PER0CLK_HDR_TX_I3C7 85
+#define JHB100_PER0CLK_HDR_TX_I3C8 86
+#define JHB100_PER0CLK_HDR_TX_I3C9 87
+#define JHB100_PER0CLK_HDR_TX_I3C10 88
+#define JHB100_PER0CLK_HDR_TX_I3C11 89
+#define JHB100_PER0CLK_HDR_TX_I3C12 90
+#define JHB100_PER0CLK_HDR_TX_I3C13 91
+#define JHB100_PER0CLK_HDR_TX_I3C14 92
+#define JHB100_PER0CLK_HDR_TX_I3C15 93
+#define JHB100_PER0CLK_CORE_I2C0 94
+#define JHB100_PER0CLK_CORE_I2C1 95
+#define JHB100_PER0CLK_CORE_I2C2 96
+#define JHB100_PER0CLK_CORE_I2C3 97
+#define JHB100_PER0CLK_CORE_I2C4 98
+#define JHB100_PER0CLK_CORE_I2C5 99
+#define JHB100_PER0CLK_CORE_I2C6 100
+#define JHB100_PER0CLK_CORE_I2C7 101
+#define JHB100_PER0CLK_CORE_I2C8 102
+#define JHB100_PER0CLK_CORE_I2C9 103
+#define JHB100_PER0CLK_CORE_I2C10 104
+#define JHB100_PER0CLK_CORE_I2C11 105
+#define JHB100_PER0CLK_CORE_I2C12 106
+#define JHB100_PER0CLK_CORE_I2C13 107
+#define JHB100_PER0CLK_CORE_I2C14 108
+#define JHB100_PER0CLK_CORE_I2C15 109
+
+#define JHB100_PER0CLK_WDOGCLK_WDT0 126
+#define JHB100_PER0CLK_WDOGCLK_WDT1 127
+#define JHB100_PER0CLK_WDOGCLK_WDT2 128
+#define JHB100_PER0CLK_WDOGCLK_WDT3 129
+#define JHB100_PER0CLK_WDOGCLK_WDT_EXTERNAL 130
+#define JHB100_PER0CLK_SCLK_UART4 131
+#define JHB100_PER0CLK_SCLK_UART5 132
+#define JHB100_PER0CLK_SCLK_UART6 133
+#define JHB100_PER0CLK_SCLK_UART7 134
+#define JHB100_PER0CLK_SCLK_UART8 135
+#define JHB100_PER0CLK_SCLK_UART9 136
+#define JHB100_PER0CLK_SCLK_UART10 137
+#define JHB100_PER0CLK_SCLK_UART11 138
+#define JHB100_PER0CLK_SCLK_UART12 139
+#define JHB100_PER0CLK_SCLK_UART13 140
+#define JHB100_PER0CLK_SCLK_UART14 141
+
+#define JHB100_PER0CLK_PCLK_DMA_UART_CFG 148
+#define JHB100_PER0CLK_PCLK_DMA_I2C_CFG 149
+#define JHB100_PER0CLK_PCLK_DMA_I3C_CFG 150
+#define JHB100_PER0CLK_PCLK_DUALTIMER0 151
+#define JHB100_PER0CLK_PCLK_DUALTIMER1 152
+#define JHB100_PER0CLK_PCLK_DUALTIMER2 153
+
+#define JHB100_PER0CLK_HCLK_TRNG 156
+#define JHB100_PER0CLK_APB_I2C0 157
+#define JHB100_PER0CLK_APB_I2C1 158
+#define JHB100_PER0CLK_APB_I2C2 159
+#define JHB100_PER0CLK_APB_I2C3 160
+#define JHB100_PER0CLK_APB_I2C4 161
+#define JHB100_PER0CLK_APB_I2C5 162
+#define JHB100_PER0CLK_APB_I2C6 163
+#define JHB100_PER0CLK_APB_I2C7 164
+#define JHB100_PER0CLK_APB_I2C8 165
+#define JHB100_PER0CLK_APB_I2C9 166
+#define JHB100_PER0CLK_APB_I2C10 167
+#define JHB100_PER0CLK_APB_I2C11 168
+#define JHB100_PER0CLK_APB_I2C12 169
+#define JHB100_PER0CLK_APB_I2C13 170
+#define JHB100_PER0CLK_APB_I2C14 171
+#define JHB100_PER0CLK_APB_I2C15 172
+#define JHB100_PER0CLK_APB_I2CF0 173
+#define JHB100_PER0CLK_APB_I2CF1 174
+#define JHB100_PER0CLK_APB_I2CF2 175
+#define JHB100_PER0CLK_APB_I2CF3 176
+#define JHB100_PER0CLK_APB_I2CF4 177
+#define JHB100_PER0CLK_APB_I2CF5 178
+#define JHB100_PER0CLK_APB_I2CF6 179
+#define JHB100_PER0CLK_APB_I2CF7 180
+#define JHB100_PER0CLK_APB_I2CF8 181
+#define JHB100_PER0CLK_APB_I2CF9 182
+#define JHB100_PER0CLK_APB_I2CF10 183
+#define JHB100_PER0CLK_APB_I2CF11 184
+#define JHB100_PER0CLK_APB_I2CF12 185
+#define JHB100_PER0CLK_APB_I2CF13 186
+#define JHB100_PER0CLK_APB_I2CF14 187
+#define JHB100_PER0CLK_APB_I2CF15 188
+#define JHB100_PER0CLK_APB_I3C0 189
+#define JHB100_PER0CLK_APB_I3C1 190
+#define JHB100_PER0CLK_APB_I3C2 191
+#define JHB100_PER0CLK_APB_I3C3 192
+#define JHB100_PER0CLK_APB_I3C4 193
+#define JHB100_PER0CLK_APB_I3C5 194
+#define JHB100_PER0CLK_APB_I3C6 195
+#define JHB100_PER0CLK_APB_I3C7 196
+#define JHB100_PER0CLK_APB_I3C8 197
+#define JHB100_PER0CLK_APB_I3C9 198
+#define JHB100_PER0CLK_APB_I3C10 199
+#define JHB100_PER0CLK_APB_I3C11 200
+#define JHB100_PER0CLK_APB_I3C12 201
+#define JHB100_PER0CLK_APB_I3C13 202
+#define JHB100_PER0CLK_APB_I3C14 203
+#define JHB100_PER0CLK_APB_I3C15 204
+#define JHB100_PER0CLK_APB_UART0 205
+#define JHB100_PER0CLK_APB_UART1 206
+#define JHB100_PER0CLK_APB_UART2 207
+#define JHB100_PER0CLK_APB_UART3 208
+#define JHB100_PER0CLK_APB_UART4 209
+#define JHB100_PER0CLK_APB_UART5 210
+#define JHB100_PER0CLK_APB_UART6 211
+#define JHB100_PER0CLK_APB_UART7 212
+#define JHB100_PER0CLK_APB_UART8 213
+#define JHB100_PER0CLK_APB_UART9 214
+#define JHB100_PER0CLK_APB_UART10 215
+#define JHB100_PER0CLK_APB_UART11 216
+#define JHB100_PER0CLK_APB_UART12 217
+#define JHB100_PER0CLK_APB_UART13 218
+#define JHB100_PER0CLK_APB_UART14 219
+#define JHB100_PER0CLK_DMA_I3C0 220
+#define JHB100_PER0CLK_DMA_I3C1 221
+#define JHB100_PER0CLK_DMA_I3C2 222
+#define JHB100_PER0CLK_DMA_I3C3 223
+#define JHB100_PER0CLK_DMA_I3C4 224
+#define JHB100_PER0CLK_DMA_I3C5 225
+#define JHB100_PER0CLK_DMA_I3C6 226
+#define JHB100_PER0CLK_DMA_I3C7 227
+#define JHB100_PER0CLK_DMA_I3C8 228
+#define JHB100_PER0CLK_DMA_I3C9 229
+#define JHB100_PER0CLK_DMA_I3C10 230
+#define JHB100_PER0CLK_DMA_I3C11 231
+#define JHB100_PER0CLK_DMA_I3C12 232
+#define JHB100_PER0CLK_DMA_I3C13 233
+#define JHB100_PER0CLK_DMA_I3C14 234
+#define JHB100_PER0CLK_DMA_I3C15 235
+#define JHB100_PER0CLK_CORE_I3C0 236
+#define JHB100_PER0CLK_CORE_I3C1 237
+#define JHB100_PER0CLK_CORE_I3C2 238
+#define JHB100_PER0CLK_CORE_I3C3 239
+#define JHB100_PER0CLK_CORE_I3C4 240
+#define JHB100_PER0CLK_CORE_I3C5 241
+#define JHB100_PER0CLK_CORE_I3C6 242
+#define JHB100_PER0CLK_CORE_I3C7 243
+#define JHB100_PER0CLK_CORE_I3C8 244
+#define JHB100_PER0CLK_CORE_I3C9 245
+#define JHB100_PER0CLK_CORE_I3C10 246
+#define JHB100_PER0CLK_CORE_I3C11 247
+#define JHB100_PER0CLK_CORE_I3C12 248
+#define JHB100_PER0CLK_CORE_I3C13 249
+#define JHB100_PER0CLK_CORE_I3C14 250
+#define JHB100_PER0CLK_CORE_I3C15 251
+#define JHB100_PER0CLK_DMAC_AXI_PERIPH0_HS_CLK_I2C 252
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C0 253
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C1 254
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C2 255
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C3 256
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C4 257
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C5 258
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C6 259
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C7 260
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C8 261
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C9 262
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C10 263
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C11 264
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C12 265
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C13 266
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C14 267
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C15 268
+#define JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER0 269
+#define JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER1 270
+#define JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER2 271
+#define JHB100_PER0CLK_MAIN_ICG_EN_LTPI0 272
+#define JHB100_PER0CLK_MAIN_ICG_EN_LTPI1 273
+#define JHB100_PER0CLK_MAIN_ICG_EN_DMAC_I2C 274
+#define JHB100_PER0CLK_MAIN_ICG_EN_DMAC_I3C 275
+#define JHB100_PER0CLK_MAIN_ICG_EN_DMAC_UART 276
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL4 277
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL5 278
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL6 279
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL7 280
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL8 281
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL9 282
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL10 283
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL11 284
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL12 285
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL13 286
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL14 287
+
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C0 304
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C1 305
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C2 306
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C3 307
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C4 308
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C5 309
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C6 310
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C7 311
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C8 312
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C9 313
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C10 314
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C11 315
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C12 316
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C13 317
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C14 318
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C15 319
+#define JHB100_PER0CLK_MAIN_ICG_EN_WDT0 320
+#define JHB100_PER0CLK_MAIN_ICG_EN_WDT1 321
+#define JHB100_PER0CLK_MAIN_ICG_EN_WDT2 322
+#define JHB100_PER0CLK_MAIN_ICG_EN_WDT3 323
+#define JHB100_PER0CLK_MAIN_ICG_EN_WDT_EXTERNAL 324
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART4 325
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART5 326
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART6 327
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART7 328
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART8 329
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART9 330
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART10 331
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART11 332
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART12 333
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART13 334
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART14 335
+#define JHB100_PER0CLK_MAIN_ICG_EN_LDO0 336
+#define JHB100_PER0CLK_MAIN_ICG_EN_LDO1 337
+#define JHB100_PER0CLK_MAIN_ICG_EN_SENSORS_PERIPH0 338
+#define JHB100_PER0CLK_MAIN_ICG_EN_SENSORS_DMAC 339
+#define JHB100_PER0CLK_MAIN_ICG_EN_TRNG 340
+
+/* PER1CRG clocks */
+#define JHB100_PER1CLK_100 0
+#define JHB100_PER1CLK_1 1
+#define JHB100_PER1CLK_200_DIVN0 2
+#define JHB100_PER1CLK_200_DIVN1 3
+#define JHB100_PER1CLK_200_DIVN2 4
+#define JHB100_PER1CLK_200_DIVN3 5
+#define JHB100_PER1CLK_200_CCLK_DIV 6
+
+#define JHB100_PER1CLK_SGPIO0_PCLK 15
+#define JHB100_PER1CLK_SGPIO0_DCLK 16
+#define JHB100_PER1CLK_SGPIO1_PCLK 17
+#define JHB100_PER1CLK_SGPIO1_DCLK 18
+
+#define JHB100_PER1CLK_EMMC0_BCLK 22
+
+#define JHB100_PER1CLK_EMMC0_CCLK 25
+
+#define JHB100_PER1CLK_DMAC1_1CH_CORE 29
+
+#define JHB100_PER1CLK_DMAC1_1CH_ACLK 31
+
+#define JHB100_PER1CLK_DMAC2_1CH_CORE 33
+
+#define JHB100_PER1CLK_DMAC2_1CH_ACLK 35
+
+#define JHB100_PER1CLK_DMAC3_1CH_CORE 37
+
+#define JHB100_PER1CLK_DMAC3_1CH_ACLK 39
+
+#define JHB100_PER1CLK_DMAC0_2CH_CORE 41
+
+#define JHB100_PER1CLK_DMAC0_2CH_ACLK 43
+
+#define JHB100_PER1CLK_UFS_REF 45
+#define JHB100_PER1CLK_UFS_300 46
+#define JHB100_PER1CLK_UFS_150 47
+#define JHB100_PER1CLK_UFS_400 48
+#define JHB100_PER1CLK_UFS_75 49
+#define JHB100_PER1CLK_UFS_37_5 50
+#define JHB100_PER1CLK_UFS_7_5 51
+#define JHB100_PER1CLK_UFS_1_875 52
+#define JHB100_PER1CLK_UFS_7_143 53
+#define JHB100_PER1CLK_UFS_3_5715 54
+
+#define JHB100_PER1CLK_MAIN_ICG_EN_SFC0 63
+#define JHB100_PER1CLK_MAIN_ICG_EN_SFC1 64
+#define JHB100_PER1CLK_MAIN_ICG_EN_SFC2 65
+#define JHB100_PER1CLK_MAIN_ICG_EN_SPI0 66
+#define JHB100_PER1CLK_MAIN_ICG_EN_SGPIO0 67
+#define JHB100_PER1CLK_MAIN_ICG_EN_SGPIO1 68
+#define JHB100_PER1CLK_MAIN_ICG_EN_SENSORS_PERIPH1 69
+#define JHB100_PER1CLK_MAIN_ICG_EN_EMMC0 70
+#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC0 71
+#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC1 72
+#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC2 73
+#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SPI0 74
+#define JHB100_PER1CLK_MAIN_ICG_EN_RAS 75
+#define JHB100_PER1CLK_MAIN_ICG_EN_UFS 76
+
+/* PER2CRG clocks */
+#define JHB100_PER2CLK_300 0
+#define JHB100_PER2CLK_100 1
+#define JHB100_PER2CLK_50 2
+#define JHB100_PER2CLK_GMAC2_RMII_50 3
+#define JHB100_PER2CLK_CAN0_CORE_DIV 4
+#define JHB100_PER2CLK_CAN1_CORE_DIV 5
+#define JHB100_PER2CLK_CAN0_TIMER 6
+#define JHB100_PER2CLK_CAN1_TIMER 7
+
+#define JHB100_PER2CLK_RTC_CORE_DIV 11
+#define JHB100_PER2CLK_GMAC2_RMII_MUX_DLY 12
+#define JHB100_PER2CLK_GMAC2_RMII_DIV 13
+
+#define JHB100_PER2CLK_GMAC2_RGMII_125_MUX 15
+#define JHB100_PER2CLK_GMAC2_RGMII_DIV 16
+#define JHB100_PER2CLK_GMAC2_TX_MUX 17
+#define JHB100_PER2CLK_GMAC2_TX_180_BUF 18
+#define JHB100_PER2CLK_GMAC2_RX_MUX_DLY 19
+#define JHB100_PER2CLK_GMAC2_RX_180_BUF 20
+#define JHB100_PER2CLK_GMAC2_TXCK_MUX_DLY 21
+#define JHB100_PER2CLK_GMAC3_TX_125_MUX 22
+#define JHB100_PER2CLK_GMAC3_RX_125_MUX 23
+#define JHB100_PER2CLK_GMAC3_TX_DIV 24
+#define JHB100_PER2CLK_GMAC3_RX_DIV 25
+#define JHB100_PER2CLK_SENSORS_PERIPH2 26
+
+#define JHB100_PER2CLK_FAN_TACH_PCLK 33
+
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_TX_I 44
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RX_I 45
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_TX_180_I 46
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RX_180_I 47
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_PTP_REF_I 48
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RMII_I 49
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_CSR_I 50
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_ACLK_I 51
+#define JHB100_PER2CLK_RMIIANDRGMII_IOMUX_GMAC2_TXCK 52
+#define JHB100_PER2CLK_ETHER1_SGMII_TX_I 53
+#define JHB100_PER2CLK_ETHER1_SGMII_RX_I 54
+#define JHB100_PER2CLK_ETHER1_SGMII_TX_125_I 55
+#define JHB100_PER2CLK_ETHER1_SGMII_RX_125_I 56
+#define JHB100_PER2CLK_ETHER1_SGMII_PTP_REF_I 57
+#define JHB100_PER2CLK_ETHER1_SGMII_CSR_I 58
+#define JHB100_PER2CLK_ETHER1_SGMII_ACLK_I 59
+#define JHB100_PER2CLK_ETHER1_SGMII_PHY_PCLK_I 60
+#define JHB100_PER2CLK_ETHER1_SGMII_REF_25_I 61
+#define JHB100_PER2CLK_MAIN_ICG_EN_CAN0 62
+#define JHB100_PER2CLK_MAIN_ICG_EN_CAN1 63
+
+#define JHB100_PER2CLK_MAIN_ICG_EN_DMAC_8CH 65
+#define JHB100_PER2CLK_MAIN_ICG_EN_RTC_SCAN 66
+#define JHB100_PER2CLK_MAIN_ICG_EN_ADC0 67
+#define JHB100_PER2CLK_MAIN_ICG_EN_ADC1 68
+#define JHB100_PER2CLK_MAIN_ICG_EN_GMAC2 69
+#define JHB100_PER2CLK_MAIN_ICG_EN_GMAC3 70
+
+/* PER3CRG clocks */
+#define JHB100_PER3CLK_300 0
+#define JHB100_PER3CLK_200 1
+#define JHB100_PER3CLK_GMAC1_PTP_REF 2
+#define JHB100_PER3CLK_GMAC1_TX_125_MUX 3
+#define JHB100_PER3CLK_GMAC1_TX 4
+#define JHB100_PER3CLK_GMAC1_RX_125_MUX 5
+#define JHB100_PER3CLK_GMAC1_RX 6
+#define JHB100_PER3CLK_GMAC0_PTP_REF 7
+#define JHB100_PER3CLK_GMAC0_RMII_PLL 8
+#define JHB100_PER3CLK_GMAC0_RMII_MUX 9
+#define JHB100_PER3CLK_GMAC0_RMII_MUX_DIV2 10
+
+#define JHB100_PER3CLK_ETHER0_RMII_CLK_TX_I 17
+#define JHB100_PER3CLK_ETHER0_RMII_CLK_RX_I 18
+#define JHB100_PER3CLK_ETHER0_RMII_CLK_PTP_REF_I 19
+#define JHB100_PER3CLK_ETHER0_RMII_CLK_RMII_I 20
+#define JHB100_PER3CLK_ETHER0_RMII_CLK_CSR_I 21
+#define JHB100_PER3CLK_ETHER0_RMII_ACLK_I 22
+#define JHB100_PER3CLK_GMAC0_RMII_RCLKO 23
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_TX_I 24
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_RX_I 25
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_TX_125_I 26
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_RX_125_I 27
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_PTP_REF_I 28
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_REF_25_I 29
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_CSR_I 30
+#define JHB100_PER3CLK_ETHER0_SGMII_ACLK_I 31
+#define JHB100_PER3CLK_ETHER0_SGMII_PHY_PCLK_I 32
+#define JHB100_PER3CLK_MAIN_ICG_EN_SENSORS_PERIPH3 33
+#define JHB100_PER3CLK_MAIN_ICG_EN_PECI0 34
+#define JHB100_PER3CLK_MAIN_ICG_EN_PECI1 35
+#define JHB100_PER3CLK_MAIN_ICG_EN_GMAC0 36
+#define JHB100_PER3CLK_MAIN_ICG_EN_GMAC1 37
+
+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__ */
diff --git a/include/dt-bindings/reset/starfive,jhb100-crg.h b/include/dt-bindings/reset/starfive,jhb100-crg.h
new file mode 100644
index 000000000000..1489bb01c2bd
--- /dev/null
+++ b/include/dt-bindings/reset/starfive,jhb100-crg.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#ifndef __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__
+#define __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__
+
+/* SYS0CRG resets */
+#define JHB100_SYS0RST_RESOURCE_ARB 0
+#define JHB100_SYS0RST_SYS0_IOMUX_PRESETN 1
+#define JHB100_SYS0RST_SYS0H_IOMUX_PRESETN 2
+#define JHB100_SYS0RST_RST_ADAPTOR_TIMEOUT_RSTN 3
+#define JHB100_SYS0RST_BMCPCIERP_RSTN_BUS 4
+#define JHB100_SYS0RST_BMCPCIERP_RSTN_CRG 5
+#define JHB100_SYS0RST_HOSTSS0_RSTN_BUS_ESPI 6
+#define JHB100_SYS0RST_HOSTSS0_RSTN_BUS_PCIE 7
+#define JHB100_SYS0RST_HOSTSS0_RSTN_CRG 8
+#define JHB100_SYS0RST_BMCPERIPH2_RSTN_CRG 9
+#define JHB100_SYS0RST_BMCPERIPH2_RSTN_BUS 10
+#define JHB100_SYS0RST_VCE_RSTN_CRG 11
+#define JHB100_SYS0RST_VCE_RSTN_BUS 12
+#define JHB100_SYS0RST_BMCUSB_RSTN_BUS 13
+#define JHB100_SYS0RST_BMCUSB_RSTN_CRG 14
+
+/* SYS1CRG resets */
+#define JHB100_SYS1RST_SYS1_IOMUX_PRESETN 0
+#define JHB100_SYS1RST_MAIN_RSTN_CHIPTOP_SENSOR 1
+#define JHB100_SYS1RST_VOUT_RSTN_HOST0 2
+#define JHB100_SYS1RST_VOUT_RSTN_HOST1 3
+#define JHB100_SYS1RST_HOSTSS1_RSTN_BUS_ESPI 4
+#define JHB100_SYS1RST_HOSTSS1_RSTN_BUS_PCIE 5
+#define JHB100_SYS1RST_HOSTSS1_RSTN_CRG 6
+#define JHB100_SYS1RST_BMCPERIPH3_RSTN_CRG 7
+#define JHB100_SYS1RST_BMCPERIPH3_RSTN_BUS 8
+
+/* SYS2CRG resets */
+#define JHB100_SYS2RST_JTAG0_MST_WRAP_HRESETN 0
+#define JHB100_SYS2RST_JTAG0_MST_WRAP_APB_PRESETN 1
+#define JHB100_SYS2RST_JTAG1_MST_WRAP_HRESETN 2
+#define JHB100_SYS2RST_JTAG1_MST_WRAP_APB_PRESETN 3
+#define JHB100_SYS2RST_HUSBCMN_HOSTCMN_RSTN_BUS_NCNOC_INIT 4
+#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTCMN_CRG 5
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB0_RSTN_BUS_NCNOC_BMC_TARG 6
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB0_RSTN_BUS_NCNOC_HOST_TARG 7
+#define JHB100_SYS2RST_HUSBCMN_RSTN_BMC_CRG 8
+#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTUSB0_CRG 9
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB1_RSTN_BUS_NCNOC_BMC_TARG 10
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB1_RSTN_BUS_NCNOC_HOST_TARG 11
+#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTUSB1_CRG 12
+#define JHB100_SYS2RST_BMCPERIPH1_RSTN_CRG 13
+#define JHB100_SYS2RST_BMCPERIPH1_RSTN_BUS 14
+#define JHB100_SYS2RST_BMCPERIPH0_RSTN_CRG 15
+#define JHB100_SYS2RST_BMCPERIPH0_RSTN_BUS 16
+#define JHB100_SYS2RST_GPU0_RSTN_CRG 17
+#define JHB100_SYS2RST_GPU0_RSTN_BUS 18
+#define JHB100_SYS2RST_GPU0_HOST_PCIE_RST_N 19
+#define JHB100_SYS2RST_GPU1_RSTN_CRG 20
+#define JHB100_SYS2RST_GPU1_RSTN_BUS 21
+#define JHB100_SYS2RST_GPU1_HOST_PCIE_RST_N 22
+
+/* PER0CRG resets */
+#define JHB100_PER0RST_MAIN_RSTN_UART4 0
+#define JHB100_PER0RST_MAIN_RSTN_UART5 1
+#define JHB100_PER0RST_MAIN_RSTN_UART6 2
+#define JHB100_PER0RST_MAIN_RSTN_UART7 3
+#define JHB100_PER0RST_MAIN_RSTN_UART8 4
+#define JHB100_PER0RST_MAIN_RSTN_UART9 5
+#define JHB100_PER0RST_MAIN_RSTN_UART10 6
+#define JHB100_PER0RST_MAIN_RSTN_UART11 7
+#define JHB100_PER0RST_MAIN_RSTN_UART12 8
+#define JHB100_PER0RST_MAIN_RSTN_UART13 9
+#define JHB100_PER0RST_MAIN_RSTN_UART14 10
+#define JHB100_PER0RST_MAIN_RSTN_I2C0 11
+#define JHB100_PER0RST_MAIN_RSTN_I2C1 12
+#define JHB100_PER0RST_MAIN_RSTN_I2C2 13
+#define JHB100_PER0RST_MAIN_RSTN_I2C3 14
+#define JHB100_PER0RST_MAIN_RSTN_I2C4 15
+#define JHB100_PER0RST_MAIN_RSTN_I2C5 16
+#define JHB100_PER0RST_MAIN_RSTN_I2C6 17
+#define JHB100_PER0RST_MAIN_RSTN_I2C7 18
+#define JHB100_PER0RST_MAIN_RSTN_I2C8 19
+#define JHB100_PER0RST_MAIN_RSTN_I2C9 20
+#define JHB100_PER0RST_MAIN_RSTN_I2C10 21
+#define JHB100_PER0RST_MAIN_RSTN_I2C11 22
+#define JHB100_PER0RST_MAIN_RSTN_I2C12 23
+#define JHB100_PER0RST_MAIN_RSTN_I2C13 24
+#define JHB100_PER0RST_MAIN_RSTN_I2C14 25
+#define JHB100_PER0RST_MAIN_RSTN_I2C15 26
+#define JHB100_PER0RST_MAIN_RSTN_I3C0 27
+#define JHB100_PER0RST_MAIN_RSTN_I3C1 28
+#define JHB100_PER0RST_MAIN_RSTN_I3C2 29
+#define JHB100_PER0RST_MAIN_RSTN_I3C3 30
+#define JHB100_PER0RST_MAIN_RSTN_I3C4 31
+#define JHB100_PER0RST_MAIN_RSTN_I3C5 32
+#define JHB100_PER0RST_MAIN_RSTN_I3C6 33
+#define JHB100_PER0RST_MAIN_RSTN_I3C7 34
+#define JHB100_PER0RST_MAIN_RSTN_I3C8 35
+#define JHB100_PER0RST_MAIN_RSTN_I3C9 36
+#define JHB100_PER0RST_MAIN_RSTN_I3C10 37
+#define JHB100_PER0RST_MAIN_RSTN_I3C11 38
+#define JHB100_PER0RST_MAIN_RSTN_I3C12 39
+#define JHB100_PER0RST_MAIN_RSTN_I3C13 40
+#define JHB100_PER0RST_MAIN_RSTN_I3C14 41
+#define JHB100_PER0RST_MAIN_RSTN_I3C15 42
+#define JHB100_PER0RST_MAIN_RSTN_WDT0 43
+#define JHB100_PER0RST_MAIN_RSTN_WDT1 44
+#define JHB100_PER0RST_MAIN_RSTN_WDT2 45
+#define JHB100_PER0RST_MAIN_RSTN_WDT3 46
+#define JHB100_PER0RST_MAIN_RSTN_WDT4 47
+#define JHB100_PER0RST_MAIN_RSTN_DUALTIMER0 48
+#define JHB100_PER0RST_MAIN_RSTN_DUALTIMER1 49
+#define JHB100_PER0RST_MAIN_RSTN_DUALTIMER2 50
+#define JHB100_PER0RST_MAIN_RSTN_TRNG 51
+#define JHB100_PER0RST_MAIN_RSTN_DMAC0 52
+#define JHB100_PER0RST_MAIN_RSTN_DMAC1 53
+#define JHB100_PER0RST_MAIN_RSTN_DMAC2 54
+#define JHB100_PER0RST_MAIN_RSTN_LTPI0 55
+#define JHB100_PER0RST_MAIN_RSTN_LTPI1 56
+#define JHB100_PER0RST_MAIN_RSTN_SOL4 57
+#define JHB100_PER0RST_MAIN_RSTN_SOL5 58
+#define JHB100_PER0RST_MAIN_RSTN_SOL6 59
+#define JHB100_PER0RST_MAIN_RSTN_SOL7 60
+#define JHB100_PER0RST_MAIN_RSTN_SOL8 61
+#define JHB100_PER0RST_MAIN_RSTN_SOL9 62
+#define JHB100_PER0RST_MAIN_RSTN_SOL10 63
+#define JHB100_PER0RST_MAIN_RSTN_SOL11 64
+#define JHB100_PER0RST_MAIN_RSTN_SOL12 65
+#define JHB100_PER0RST_MAIN_RSTN_SOL13 66
+#define JHB100_PER0RST_MAIN_RSTN_SOL14 67
+#define JHB100_PER0RST_MAIN_RSTN_LDO0 68
+#define JHB100_PER0RST_MAIN_RSTN_LDO1 69
+#define JHB100_PER0RST_MAIN_RSTN_PERIPH0_SENSORS 70
+#define JHB100_PER0RST_MAIN_RSTN_DMAC0_SENSORS 71
+#define JHB100_PER0RST_SYSCON_PRESETN 72
+#define JHB100_PER0RST_GPIO_IOMUX_PRESETN 73
+#define JHB100_PER0RST_UART_MUX_REG_WRAP 74
+
+/* PER1CRG resets */
+#define JHB100_PER1RST_IOMUX_PRESETN 0
+#define JHB100_PER1RST_SYSCON_PRESETN 1
+#define JHB100_PER1RST_MAIN_RSTN_SFC0 2
+#define JHB100_PER1RST_MAIN_RSTN_SFC1 3
+#define JHB100_PER1RST_MAIN_RSTN_SFC2 4
+#define JHB100_PER1RST_MAIN_RSTN_SPI0 5
+#define JHB100_PER1RST_MAIN_RSTN_PERIPH1_SENSORS 6
+#define JHB100_PER1RST_MAIN_RSTN_SGPIO0 7
+#define JHB100_PER1RST_MAIN_RSTN_SGPIO1 8
+#define JHB100_PER1RST_MAIN_RSTN_EMMC0 9
+#define JHB100_PER1RST_MAIN_RSTN_UFS 10
+#define JHB100_PER1RST_MAIN_RSTN_UFS_PHY 11
+#define JHB100_PER1RST_MAIN_RSTN_DMAC_SFC0 12
+#define JHB100_PER1RST_MAIN_RSTN_DMAC_SFC1 13
+#define JHB100_PER1RST_MAIN_RSTN_DMAC_SFC2 14
+#define JHB100_PER1RST_MAIN_RSTN_DMAC_SPI0 15
+#define JHB100_PER1RST_MAIN_RSTN_PERIPH1_RAS 16
+
+/* PER2CRG resets */
+#define JHB100_PER2RST_IOMUX_PRESETN 0
+#define JHB100_PER2RST_POK_IOMUX_PRESETN 1
+#define JHB100_PER2RST_SYSREG_RSTN 2
+#define JHB100_PER2RST_MAIN_RSTN_CAN0 3
+#define JHB100_PER2RST_MAIN_RSTN_CAN1 4
+#define JHB100_PER2RST_FAN_TACH_PRESETN 5
+#define JHB100_PER2RST_MAIN_RSTN_GMAC2 6
+#define JHB100_PER2RST_MAIN_RSTN_GMAC3 7
+#define JHB100_PER2RST_MAIN_RSTN_DMAC_8CH 8
+#define JHB100_PER2RST_MAIN_RSTN_RTC 9
+#define JHB100_PER2RST_ADC0_PRESETN 10
+#define JHB100_PER2RST_ADC0_IOMUX_PRESETN 11
+#define JHB100_PER2RST_ADC1_PRESETN 12
+#define JHB100_PER2RST_ADC1_IOMUX_PRESETN 13
+#define JHB100_PER2RST_MAIN_RSTN_PERIPH2_SENSORS 14
+
+/* PER3CRG resets */
+#define JHB100_PER3RST_SYSREG_RSTN 0
+#define JHB100_PER3RST_MAIN_RSTN_GMAC0 1
+#define JHB100_PER3RST_MAIN_RSTN_GMAC1 2
+#define JHB100_PER3RST_MAIN_RSTN_PECI0 3
+#define JHB100_PER3RST_MAIN_RSTN_PECI1 4
+#define JHB100_PER3RST_MAIN_RSTN_PERIPH3_SENSORS 5
+#define JHB100_PER3RST_IOMUX_PRESETN 6
+
+/* PCIERP SYSCON resets */
+#define JHB100_PCIERP_SYSCONRST_PE2RST_OUT 0
+
+#endif /* __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__ */
diff --git a/include/linux/device-id/apr.h b/include/linux/device-id/apr.h
deleted file mode 100644
index f282608ea018..000000000000
--- a/include/linux/device-id/apr.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LINUX_DEVICE_ID_APR_H
-#define LINUX_DEVICE_ID_APR_H
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-typedef unsigned long kernel_ulong_t;
-#endif
-
-#define APR_NAME_SIZE 32
-#define APR_MODULE_PREFIX "apr:"
-
-struct apr_device_id {
- char name[APR_NAME_SIZE];
- __u32 domain_id;
- __u32 svc_id;
- __u32 svc_version;
- kernel_ulong_t driver_data; /* Data private to the driver */
-};
-
-#endif /* ifndef LINUX_DEVICE_ID_APR_H */
diff --git a/include/linux/device-id/scmi.h b/include/linux/device-id/scmi.h
new file mode 100644
index 000000000000..1b4ccfa9dcc5
--- /dev/null
+++ b/include/linux/device-id/scmi.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef LINUX_DEVICE_ID_SCMI_H
+#define LINUX_DEVICE_ID_SCMI_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#endif
+
+#define SCMI_NAME_SIZE 32
+#define SCMI_MODULE_PREFIX "scmi:"
+
+struct scmi_device_id {
+ __u8 protocol_id;
+ char name[SCMI_NAME_SIZE];
+};
+
+#endif /* ifndef LINUX_DEVICE_ID_SCMI_H */
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index 5747bd191bf1..a0a6bc0229c4 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -64,35 +64,6 @@ bool qcom_scm_is_available(void);
int qcom_scm_set_cold_boot_addr(void *entry);
int qcom_scm_set_warm_boot_addr(void *entry);
void qcom_scm_cpu_power_down(u32 flags);
-int qcom_scm_set_remote_state(u32 state, u32 id);
-
-struct qcom_scm_pas_context {
- struct device *dev;
- u32 pas_id;
- phys_addr_t mem_phys;
- size_t mem_size;
- void *ptr;
- dma_addr_t phys;
- ssize_t size;
- bool use_tzmem;
-};
-
-struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev,
- u32 pas_id,
- phys_addr_t mem_phys,
- size_t mem_size);
-int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
- struct qcom_scm_pas_context *ctx);
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx);
-int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
-int qcom_scm_pas_auth_and_reset(u32 pas_id);
-int qcom_scm_pas_shutdown(u32 pas_id);
-bool qcom_scm_pas_supported(u32 pas_id);
-struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx,
- void *input_rt, size_t input_rt_size,
- size_t *output_rt_size);
-
-int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx);
int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
diff --git a/include/linux/firmware/xlnx-zynqmp-ufs.h b/include/linux/firmware/xlnx-zynqmp-ufs.h
index d3538dd5822a..00383dd835f2 100644
--- a/include/linux/firmware/xlnx-zynqmp-ufs.h
+++ b/include/linux/firmware/xlnx-zynqmp-ufs.h
@@ -9,17 +9,17 @@
#define __FIRMWARE_XLNX_ZYNQMP_UFS_H__
#if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE)
-int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready);
-int zynqmp_pm_is_sram_init_done(bool *is_done);
+int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us);
+int zynqmp_pm_wait_sram_init_done(u32 timeout_us);
int zynqmp_pm_set_sram_bypass(void);
int zynqmp_pm_get_ufs_calibration_values(u32 *val);
#else
-static inline int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready)
+static inline int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us)
{
return -ENODEV;
}
-static inline int zynqmp_pm_is_sram_init_done(bool *is_done)
+static inline int zynqmp_pm_wait_sram_init_done(u32 timeout_us)
{
return -ENODEV;
}
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index f4b3df614c77..41a1cd810bda 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -277,11 +277,6 @@ enum rpu_oper_mode {
PM_RPU_MODE_SPLIT = 1,
};
-enum rpu_boot_mem {
- PM_RPU_BOOTMEM_LOVEC = 0,
- PM_RPU_BOOTMEM_HIVEC = 1,
-};
-
enum rpu_tcm_comb {
PM_RPU_TCM_SPLIT = 0,
PM_RPU_TCM_COMB = 1,
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index c25f0f7e6dd4..0b2c0eb9b605 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -336,7 +336,7 @@ struct fsl_mc_io {
u16 flags;
u32 portal_size;
phys_addr_t portal_phys_addr;
- void __iomem *portal_virt_addr;
+ void __iomem *portal_virt_addr __counted_by_ptr(portal_size);
struct fsl_mc_device *dpmcp_dev;
union {
/*
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 318c4b5c3451..d1581bb64729 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -15,7 +15,6 @@
#include "device-id/acpi.h"
#include "device-id/amba.h"
#include "device-id/ap.h"
-#include "device-id/apr.h"
#include "device-id/arm_smccc.h"
#include "device-id/auxiliary.h"
#include "device-id/bcma.h"
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 5ab73b1ab9aa..3f7cc35eb861 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -9,6 +9,7 @@
#define _LINUX_SCMI_PROTOCOL_H
#include <linux/bitfield.h>
+#include <linux/device-id/scmi.h>
#include <linux/device.h>
#include <linux/notifier.h>
#include <linux/types.h>
@@ -528,22 +529,25 @@ struct scmi_sensor_proto_ops {
u32 sensor_id, u32 sensor_config);
};
+struct scmi_reset_domain_info {
+ char name[SCMI_MAX_STR_SIZE];
+ u32 latency_us;
+};
+
/**
* struct scmi_reset_proto_ops - represents the various operations provided
* by SCMI Reset Protocol
*
* @num_domains_get: get the count of reset domains provided by SCMI
- * @name_get: gets the name of a reset domain
- * @latency_get: gets the reset latency for the specified reset domain
+ * @info_get: gets the information of the specified reset domain
* @reset: resets the specified reset domain
* @assert: explicitly assert reset signal of the specified reset domain
* @deassert: explicitly deassert reset signal of the specified reset domain
*/
struct scmi_reset_proto_ops {
int (*num_domains_get)(const struct scmi_protocol_handle *ph);
- const char *(*name_get)(const struct scmi_protocol_handle *ph,
- u32 domain);
- int (*latency_get)(const struct scmi_protocol_handle *ph, u32 domain);
+ const struct scmi_reset_domain_info __must_check *(*info_get)
+ (const struct scmi_protocol_handle *ph, u32 domain);
int (*reset)(const struct scmi_protocol_handle *ph, u32 domain);
int (*assert)(const struct scmi_protocol_handle *ph, u32 domain);
int (*deassert)(const struct scmi_protocol_handle *ph, u32 domain);
@@ -930,6 +934,7 @@ enum scmi_std_protocol {
SCMI_PROTOCOL_VOLTAGE = 0x17,
SCMI_PROTOCOL_POWERCAP = 0x18,
SCMI_PROTOCOL_PINCTRL = 0x19,
+ SCMI_PROTOCOL_TELEMETRY = 0x1B,
};
enum scmi_system_events {
@@ -951,11 +956,6 @@ struct scmi_device {
#define to_scmi_dev(d) container_of_const(d, struct scmi_device, dev)
-struct scmi_device_id {
- u8 protocol_id;
- const char *name;
-};
-
struct scmi_driver {
const char *name;
int (*probe)(struct scmi_device *sdev);
diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h
index 909e84f84e0c..2e4231092088 100644
--- a/include/linux/soc/qcom/apr.h
+++ b/include/linux/soc/qcom/apr.h
@@ -5,7 +5,6 @@
#include <linux/spinlock.h>
#include <linux/device.h>
-#include <linux/device-id/apr.h>
#include <dt-bindings/soc/qcom,apr.h>
#include <dt-bindings/soc/qcom,gpr.h>
@@ -135,6 +134,8 @@ struct pkt_router_svc {
typedef struct pkt_router_svc gpr_port_t;
+#define APR_NAME_SIZE 32
+
struct apr_device {
struct device dev;
uint16_t svc_id;
@@ -158,7 +159,6 @@ struct apr_driver {
const struct apr_resp_pkt *d);
gpr_port_cb gpr_callback;
struct device_driver driver;
- const struct apr_device_id *id_table;
};
typedef struct apr_driver gpr_driver_t;
diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h
index 5f18d281e6a4..645609b57df8 100644
--- a/include/linux/soc/qcom/geni-se.h
+++ b/include/linux/soc/qcom/geni-se.h
@@ -568,7 +568,7 @@ void geni_se_tx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len);
void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len);
-int geni_icc_get(struct geni_se *se, const char *icc_ddr);
+int geni_icc_get(struct geni_se *se);
int geni_icc_set_bw(struct geni_se *se);
int geni_icc_set_bw_ab(struct geni_se *se, u32 core_ab, u32 cfg_ab, u32 ddr_ab);
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index f3ed63e475ab..713cb0221b14 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -74,6 +74,7 @@
#define LLCC_CAMSRTIP 73
#define LLCC_CAMRTRF 74
#define LLCC_CAMSRTRF 75
+#define LLCC_GPU_LITTLE 80
#define LLCC_OOBM_NS 81
#define LLCC_OOBM_S 82
#define LLCC_VIDEO_APV 83
@@ -85,7 +86,12 @@
#define LLCC_CAM_OFE_STROV 93
#define LLCC_CPUSS_HEU 94
#define LLCC_PCIE_TCU 97
+#define LLCC_GPUHTW_LITTLE 98
#define LLCC_MDM_PNG_FIXED 100
+#define LLCC_PPE_RXDESC 101
+#define LLCC_PPE_RXFILL 102
+#define LLCC_WLAN_5G 103
+#define LLCC_WLAN_6G 104
/**
* struct llcc_slice_desc - Cache slice descriptor
diff --git a/include/linux/soc/qcom/ubwc.h b/include/linux/soc/qcom/ubwc.h
index f3a70360b177..b09ae05cbeae 100644
--- a/include/linux/soc/qcom/ubwc.h
+++ b/include/linux/soc/qcom/ubwc.h
@@ -36,6 +36,7 @@ struct qcom_ubwc_cfg_data {
#define UBWC_4_3 0x40030000
#define UBWC_5_0 0x50000000
#define UBWC_6_0 0x60000000
+#define UBWC_7_0 0x70000000
#if IS_ENABLED(CONFIG_QCOM_UBWC_CONFIG)
const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void);
@@ -108,6 +109,8 @@ static inline u32 qcom_ubwc_swizzle(const struct qcom_ubwc_cfg_data *cfg)
static inline u32 qcom_ubwc_version_tag(const struct qcom_ubwc_cfg_data *cfg)
{
+ if (cfg->ubwc_enc_version >= UBWC_7_0)
+ return 6;
if (cfg->ubwc_enc_version >= UBWC_6_0)
return 5;
if (cfg->ubwc_enc_version >= UBWC_5_0)
diff --git a/include/linux/soc/ti/k3-ringacc.h b/include/linux/soc/ti/k3-ringacc.h
index 39b022b92598..7b7fc237c08f 100644
--- a/include/linux/soc/ti/k3-ringacc.h
+++ b/include/linux/soc/ti/k3-ringacc.h
@@ -57,13 +57,13 @@ struct k3_ringacc;
struct k3_ring;
/**
- * enum k3_ring_cfg - RA ring configuration structure
+ * struct k3_ring_cfg - RA ring configuration structure
*
* @size: Ring size, number of elements
* @elm_size: Ring element size
* @mode: Ring operational mode
* @flags: Ring configuration flags. Possible values:
- * @K3_RINGACC_RING_SHARED: when set allows to request the same ring
+ * %K3_RINGACC_RING_SHARED: when set allows to request the same ring
* few times. It's usable when the same ring is used as Free Host PD ring
* for different flows, for example.
* Note: Locking should be done by consumer if required
@@ -88,11 +88,10 @@ struct k3_ring_cfg {
/**
* of_k3_ringacc_get_by_phandle - find a RA by phandle property
* @np: device node
- * @propname: property name containing phandle on RA node
+ * @property: property name containing phandle on RA node
*
- * Returns pointer on the RA - struct k3_ringacc
- * or -ENODEV if not found,
- * or -EPROBE_DEFER if not yet registered
+ * Return: Pointer to the RA, or ERR_PTR(-ENODEV) if the phandle cannot
+ * be resolved, or ERR_PTR(-EPROBE_DEFER) if the RA is not yet registered.
*/
struct k3_ringacc *of_k3_ringacc_get_by_phandle(struct device_node *np,
const char *property);
@@ -103,10 +102,8 @@ struct k3_ringacc *of_k3_ringacc_get_by_phandle(struct device_node *np,
* k3_ringacc_request_ring - request ring from ringacc
* @ringacc: pointer on ringacc
* @id: ring id or K3_RINGACC_RING_ID_ANY for any general purpose ring
- * @flags:
- * @K3_RINGACC_RING_USE_PROXY: if set - proxy will be allocated and
- * used to access ring memory. Sopported only for rings in
- * Message/Credentials/Queue mode.
+ * @flags: Set %K3_RINGACC_RING_USE_PROXY to allocate a proxy for
+ * accessing ring memory in Message mode.
*
* Returns pointer on the Ring - struct k3_ring
* or NULL in case of failure.
@@ -126,8 +123,9 @@ int k3_ringacc_request_rings_pair(struct k3_ringacc *ringacc,
*/
void k3_ringacc_ring_reset(struct k3_ring *ring);
/**
- * k3_ringacc_ring_reset - ring reset for DMA rings
+ * k3_ringacc_ring_reset_dma - ring reset for DMA rings
* @ring: pointer on Ring
+ * @occ: occupancy used by the DMA reset quirk, or zero to read it from hardware
*
* Resets ring internal state ((hw)occ, (hw)idx). Should be used for rings
* which are read by K3 UDMA, like TX or Free Host PD rings.
@@ -217,8 +215,8 @@ int k3_ringacc_ring_push(struct k3_ring *ring, void *elem);
* @ring: pointer on ring
* @elem: pointer on ring element buffer
*
- * Push one ring element from the ring head. Size of the ring element is
- * determined by ring configuration &struct k3_ring_cfg elm_size..
+ * Pop one ring element from the ring head. Size of the ring element is
+ * determined by ring configuration &struct k3_ring_cfg elm_size.
*
* Returns 0 on success, errno otherwise.
*/
@@ -242,7 +240,7 @@ int k3_ringacc_ring_push_head(struct k3_ring *ring, void *elem);
* @ring: pointer on ring
* @elem: pointer on ring element buffer
*
- * Push one ring element from the ring tail. Size of the ring element is
+ * Pop one ring element from the ring tail. Size of the ring element is
* determined by ring configuration &struct k3_ring_cfg elm_size.
*
* Returns 0 on success, errno otherwise.
@@ -256,7 +254,10 @@ u32 k3_ringacc_get_tisci_dev_id(struct k3_ring *ring);
struct ti_sci_handle;
/**
- * struct struct k3_ringacc_init_data - Initialization data for DMA rings
+ * struct k3_ringacc_init_data - Initialization data for DMA rings
+ * @tisci: TI SCI firmware handle
+ * @tisci_dev_id: TI SCI device ID of the DMA controller
+ * @num_rings: Total number of available rings
*/
struct k3_ringacc_init_data {
const struct ti_sci_handle *tisci;
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h
index 8f967d15e479..7f0e4165c3b0 100644
--- a/include/soc/fsl/qe/qe.h
+++ b/include/soc/fsl/qe/qe.h
@@ -24,6 +24,7 @@
#include <linux/types.h>
struct device;
+struct gpio_desc;
#define QE_NUM_OF_SNUM 256 /* There are 256 serial number in QE */
#define QE_NUM_OF_BRGS 16
@@ -193,12 +194,13 @@ static inline int par_io_data_set(u8 port, u8 pin, u8 val) { return -ENOSYS; }
*/
struct qe_pin;
#ifdef CONFIG_QE_GPIO
-extern struct qe_pin *qe_pin_request(struct device *dev, int index);
+extern struct qe_pin *qe_pin_request(struct device *dev, struct gpio_desc *gpiod);
extern void qe_pin_free(struct qe_pin *qe_pin);
extern void qe_pin_set_gpio(struct qe_pin *qe_pin);
extern void qe_pin_set_dedicated(struct qe_pin *pin);
#else
-static inline struct qe_pin *qe_pin_request(struct device *dev, int index)
+static inline struct qe_pin *
+qe_pin_request(struct device *dev, struct gpio_desc *gpiod)
{
return ERR_PTR(-ENOSYS);
}
diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h
index c4f7a1b97c54..14822f981fec 100644
--- a/include/soc/tegra/fuse.h
+++ b/include/soc/tegra/fuse.h
@@ -33,6 +33,7 @@ enum tegra_revision {
TEGRA_REVISION_A03,
TEGRA_REVISION_A03p,
TEGRA_REVISION_A04,
+ TEGRA_REVISION_B01,
TEGRA_REVISION_MAX,
};
diff --git a/include/trace/events/scmi.h b/include/trace/events/scmi.h
index 703b7bb68e44..b421c253df00 100644
--- a/include/trace/events/scmi.h
+++ b/include/trace/events/scmi.h
@@ -7,8 +7,6 @@
#include <linux/tracepoint.h>
-#define TRACE_SCMI_MAX_TAG_LEN 6
-
TRACE_EVENT(scmi_fc_call,
TP_PROTO(u8 protocol_id, u8 msg_id, u32 res_id, u32 val1, u32 val2),
TP_ARGS(protocol_id, msg_id, res_id, val1, val2),
@@ -156,7 +154,7 @@ TRACE_EVENT(scmi_msg_dump,
__field(u8, channel_id)
__field(u8, protocol_id)
__field(u8, msg_id)
- __array(char, tag, TRACE_SCMI_MAX_TAG_LEN)
+ __string(tag, tag)
__field(u16, seq)
__field(int, status)
__field(size_t, len)
@@ -168,7 +166,7 @@ TRACE_EVENT(scmi_msg_dump,
__entry->channel_id = channel_id;
__entry->protocol_id = protocol_id;
__entry->msg_id = msg_id;
- strscpy(__entry->tag, tag, TRACE_SCMI_MAX_TAG_LEN);
+ __assign_str(tag);
__entry->seq = seq;
__entry->status = status;
__entry->len = len;
@@ -177,7 +175,7 @@ TRACE_EVENT(scmi_msg_dump,
TP_printk("id=%d ch=%02X pt=%02X t=%s msg_id=%02X seq=%04X s=%d pyld=%s",
__entry->id, __entry->channel_id, __entry->protocol_id,
- __entry->tag, __entry->msg_id, __entry->seq, __entry->status,
+ __get_str(tag), __entry->msg_id, __entry->seq, __entry->status,
__print_hex_str(__get_dynamic_array(cmd), __entry->len))
);
#endif /* _TRACE_SCMI_H */
diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
index 5203977ed35d..76815b0f4b66 100644
--- a/include/uapi/linux/tee.h
+++ b/include/uapi/linux/tee.h
@@ -385,24 +385,6 @@ struct tee_iocl_supp_send_arg {
struct tee_ioctl_buf_data)
/**
- * struct tee_ioctl_shm_register_data - Shared memory register argument
- * @addr: [in] Start address of shared memory to register
- * @length: [in/out] Length of shared memory to register
- * @flags: [in/out] Flags to/from registration.
- * @id: [out] Identifier of the shared memory
- *
- * The flags field should currently be zero as input. Updated by the call
- * with actual flags as defined by TEE_IOCTL_SHM_* above.
- * This structure is used as argument for TEE_IOC_SHM_REGISTER below.
- */
-struct tee_ioctl_shm_register_data {
- __u64 addr;
- __u64 length;
- __u32 flags;
- __s32 id;
-};
-
-/**
* struct tee_ioctl_shm_register_fd_data - Shared memory registering argument
* @fd: [in] File descriptor identifying dmabuf reference
* @size: [out] Size of referenced memory
@@ -426,7 +408,7 @@ struct tee_ioctl_shm_register_fd_data {
* Returns a file descriptor on success or < 0 on failure
*
* The returned file descriptor refers to the shared memory object in the
- * kernel. The supplied file deccriptor can be closed if it's not needed
+ * kernel. The supplied file descriptor can be closed if it's not needed
* for other purposes. The shared memory is freed when the descriptor is
* closed.
*/
@@ -434,13 +416,31 @@ struct tee_ioctl_shm_register_fd_data {
struct tee_ioctl_shm_register_fd_data)
/**
+ * struct tee_ioctl_shm_register_data - Shared memory register argument
+ * @addr: [in] Start address of shared memory to register
+ * @length: [in/out] Length of shared memory to register
+ * @flags: [in/out] Flags to/from registration.
+ * @id: [out] Identifier of the shared memory
+ *
+ * The flags field should currently be zero as input. Updated by the call
+ * with actual flags as defined by TEE_IOCTL_SHM_* above.
+ * This structure is used as argument for TEE_IOC_SHM_REGISTER below.
+ */
+struct tee_ioctl_shm_register_data {
+ __u64 addr;
+ __u64 length;
+ __u32 flags;
+ __s32 id;
+};
+
+/**
* TEE_IOC_SHM_REGISTER - Register shared memory argument
*
* Registers shared memory between the user space process and secure OS.
*
* Returns a file descriptor on success or < 0 on failure
*
- * The shared memory is unregisterred when the descriptor is closed.
+ * The shared memory is unregistered when the descriptor is closed.
*/
#define TEE_IOC_SHM_REGISTER _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \
struct tee_ioctl_shm_register_data)
diff --git a/lib/cache_maint.c b/lib/cache_maint.c
index 9256a9ffc34c..132d2816d6b1 100644
--- a/lib/cache_maint.c
+++ b/lib/cache_maint.c
@@ -59,12 +59,12 @@ static int cache_inval_done_one(struct cache_coherency_ops_inst *cci)
static int cache_invalidate_memregion(phys_addr_t addr, size_t size)
{
- int ret;
struct cache_coherency_ops_inst *cci;
struct cc_inval_params params = {
.addr = addr,
.size = size,
};
+ int ret = -ENXIO;
guard(rwsem_read)(&cache_ops_instance_list_lock);
list_for_each_entry(cci, &cache_ops_instance_list, node) {
@@ -78,7 +78,7 @@ static int cache_invalidate_memregion(phys_addr_t addr, size_t size)
return ret;
}
- return 0;
+ return ret;
}
struct cache_coherency_ops_inst *
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index 1492e9fdc7cb..92596bfa6aec 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#define COMPILE_OFFSETS
+#include <linux/device-id/scmi.h>
#include <linux/kbuild.h>
#include <linux/mod_devicetable.h>
@@ -144,6 +145,10 @@ int main(void)
DEVID(rpmsg_device_id);
DEVID_FIELD(rpmsg_device_id, name);
+ DEVID(scmi_device_id);
+ DEVID_FIELD(scmi_device_id, protocol_id);
+ DEVID_FIELD(scmi_device_id, name);
+
DEVID(i2c_device_id);
DEVID_FIELD(i2c_device_id, name);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 980d7da456bb..61a831c18721 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -121,6 +121,7 @@ typedef struct {
/* Big exception to the "don't include kernel headers into userspace, which
* even potentially has different endianness and word sizes, since
* we handle those differences explicitly below */
+#include "../../include/linux/device-id/scmi.h"
#include "../../include/linux/mod_devicetable.h"
struct devtable {
@@ -852,6 +853,16 @@ static void do_rpmsg_entry(struct module *mod, void *symval)
module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name);
}
+/* Looks like: scmi:NN:S */
+static void do_scmi_entry(struct module *mod, void *symval)
+{
+ DEF_FIELD(symval, scmi_device_id, protocol_id);
+ DEF_FIELD_ADDR(symval, scmi_device_id, name);
+
+ module_alias_printf(mod, false, SCMI_MODULE_PREFIX "%02x:%s",
+ protocol_id, *name);
+}
+
/* Looks like: i2c:S */
static void do_i2c_entry(struct module *mod, void *symval)
{
@@ -1498,6 +1509,7 @@ static const struct devtable devtable[] = {
{"virtio", SIZE_virtio_device_id, do_virtio_entry},
{"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry},
{"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry},
+ {"scmi", SIZE_scmi_device_id, do_scmi_entry},
{"i2c", SIZE_i2c_device_id, do_i2c_entry},
{"i3c", SIZE_i3c_device_id, do_i3c_entry},
{"slim", SIZE_slim_device_id, do_slim_entry},