Message ID | 20230531-rpm-rproc-v2-0-56a4a00c8260@gerhold.net |
---|---|
Headers | show |
Series | Add dedicated device tree node for RPM processor/subsystem | expand |
On 8.06.2023 09:10, Stephan Gerhold wrote: > Rather than looking up a dummy item from SMEM, use the new > qcom_smem_is_available() function to make the code more clear > (and reduce the overhead slightly). > > Add the same check to qcom_smd_register_edge() as well to ensure that > it only succeeds if SMEM is already available - if a driver calls the > function and SMEM is not available yet then the initial state will be > read incorrectly and the RPMSG devices might never become available. > > Signed-off-by: Stephan Gerhold <stephan@gerhold.net> > --- Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org> Konrad > drivers/rpmsg/qcom_smd.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > > diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c > index 7b9c298aa491..43f601c84b4f 100644 > --- a/drivers/rpmsg/qcom_smd.c > +++ b/drivers/rpmsg/qcom_smd.c > @@ -1479,6 +1479,9 @@ struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent, > struct qcom_smd_edge *edge; > int ret; > > + if (!qcom_smem_is_available()) > + return ERR_PTR(-EPROBE_DEFER); > + > edge = kzalloc(sizeof(*edge), GFP_KERNEL); > if (!edge) > return ERR_PTR(-ENOMEM); > @@ -1553,12 +1556,9 @@ EXPORT_SYMBOL(qcom_smd_unregister_edge); > static int qcom_smd_probe(struct platform_device *pdev) > { > struct device_node *node; > - void *p; > > - /* Wait for smem */ > - p = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[0].alloc_tbl_id, NULL); > - if (PTR_ERR(p) == -EPROBE_DEFER) > - return PTR_ERR(p); > + if (!qcom_smem_is_available()) > + return -EPROBE_DEFER; > > for_each_available_child_of_node(pdev->dev.of_node, node) > qcom_smd_register_edge(&pdev->dev, node); >
On 8.06.2023 09:10, Stephan Gerhold wrote: > Add a simple driver for the qcom,rpm-proc compatible that registers the > "smd-edge" and populates other children defined in the device tree. > > Note that the DT schema belongs to the remoteproc subsystem while this > driver is added inside soc/qcom. I argue that the RPM *is* a remoteproc, > but as an implementation detail in Linux it can currently not benefit > from anything provided by the remoteproc subsystem. The RPM firmware is > usually already loaded and started by earlier components in the boot > chain and is not meant to be ever restarted. > > To avoid breaking existing kernel configurations the driver is always > built when smd-rpm.c is also built. They belong closely together anyway. > To avoid build errors CONFIG_RPMSG_QCOM_SMD must be also built-in if > rpm-proc is. > > Signed-off-by: Stephan Gerhold <stephan@gerhold.net> > --- Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org> Konrad > drivers/soc/qcom/Kconfig | 1 + > drivers/soc/qcom/Makefile | 2 +- > drivers/soc/qcom/rpm-proc.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 79 insertions(+), 1 deletion(-) > > diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig > index e597799e8121..715348869d04 100644 > --- a/drivers/soc/qcom/Kconfig > +++ b/drivers/soc/qcom/Kconfig > @@ -191,6 +191,7 @@ config QCOM_SMD_RPM > tristate "Qualcomm Resource Power Manager (RPM) over SMD" > depends on ARCH_QCOM || COMPILE_TEST > depends on RPMSG > + depends on RPMSG_QCOM_SMD || RPMSG_QCOM_SMD=n > help > If you say yes to this option, support will be included for the > Resource Power Manager system found in the Qualcomm 8974 based > diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile > index 99114c71092b..113b9ff2ad43 100644 > --- a/drivers/soc/qcom/Makefile > +++ b/drivers/soc/qcom/Makefile > @@ -18,7 +18,7 @@ obj-$(CONFIG_QCOM_RPM_MASTER_STATS) += rpm_master_stats.o > obj-$(CONFIG_QCOM_RPMH) += qcom_rpmh.o > qcom_rpmh-y += rpmh-rsc.o > qcom_rpmh-y += rpmh.o > -obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o > +obj-$(CONFIG_QCOM_SMD_RPM) += rpm-proc.o smd-rpm.o > obj-$(CONFIG_QCOM_SMEM) += smem.o > obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o > obj-$(CONFIG_QCOM_SMP2P) += smp2p.o > diff --git a/drivers/soc/qcom/rpm-proc.c b/drivers/soc/qcom/rpm-proc.c > new file mode 100644 > index 000000000000..2995d9b90190 > --- /dev/null > +++ b/drivers/soc/qcom/rpm-proc.c > @@ -0,0 +1,77 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net> */ > + > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/of_platform.h> > +#include <linux/platform_device.h> > +#include <linux/rpmsg/qcom_smd.h> > + > +static int rpm_proc_probe(struct platform_device *pdev) > +{ > + struct qcom_smd_edge *edge = NULL; > + struct device *dev = &pdev->dev; > + struct device_node *edge_node; > + int ret; > + > + edge_node = of_get_child_by_name(dev->of_node, "smd-edge"); > + if (edge_node) { > + edge = qcom_smd_register_edge(dev, edge_node); > + of_node_put(edge_node); > + if (IS_ERR(edge)) > + return dev_err_probe(dev, PTR_ERR(edge), > + "Failed to register smd-edge\n"); > + } > + > + ret = devm_of_platform_populate(dev); > + if (ret) { > + dev_err(dev, "Failed to populate child devices: %d\n", ret); > + goto err; > + } > + > + platform_set_drvdata(pdev, edge); > + return 0; > +err: > + if (edge) > + qcom_smd_unregister_edge(edge); > + return ret; > +} > + > +static void rpm_proc_remove(struct platform_device *pdev) > +{ > + struct qcom_smd_edge *edge = platform_get_drvdata(pdev); > + > + if (edge) > + qcom_smd_unregister_edge(edge); > +} > + > +static const struct of_device_id rpm_proc_of_match[] = { > + { .compatible = "qcom,rpm-proc", }, > + { /* sentinel */ } > +}; > +MODULE_DEVICE_TABLE(of, rpm_proc_of_match); > + > +static struct platform_driver rpm_proc_driver = { > + .probe = rpm_proc_probe, > + .remove_new = rpm_proc_remove, > + .driver = { > + .name = "qcom-rpm-proc", > + .of_match_table = rpm_proc_of_match, > + }, > +}; > + > +static int __init rpm_proc_init(void) > +{ > + return platform_driver_register(&rpm_proc_driver); > +} > +arch_initcall(rpm_proc_init); > + > +static void __exit rpm_proc_exit(void) > +{ > + platform_driver_unregister(&rpm_proc_driver); > +} > +module_exit(rpm_proc_exit); > + > +MODULE_DESCRIPTION("Qualcomm RPM processor/subsystem driver"); > +MODULE_AUTHOR("Stephan Gerhold <stephan@gerhold.net>"); > +MODULE_LICENSE("GPL"); >
On 8.06.2023 09:10, Stephan Gerhold wrote: > Rather than having the RPM SMD channels as the only child of a dummy > SMD node, switch to representing the RPM as remoteproc like all the > other remoteprocs (WCNSS, modem DSP). > > This allows assigning additional subdevices to it like the MPM > interrupt-controller or rpm-master-stats. > > Signed-off-by: Stephan Gerhold <stephan@gerhold.net> > --- Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org> Konrad > arch/arm/boot/dts/qcom-apq8084.dtsi | 6 ++--- > arch/arm/boot/dts/qcom-msm8226.dtsi | 38 ++++++++++++++++---------------- > arch/arm/boot/dts/qcom-msm8974.dtsi | 44 ++++++++++++++++++------------------- > 3 files changed, 44 insertions(+), 44 deletions(-) > > diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi > index 8f178bc87e1d..2b1f9d0fb510 100644 > --- a/arch/arm/boot/dts/qcom-apq8084.dtsi > +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi > @@ -784,10 +784,10 @@ spmi_bus: spmi@fc4cf000 { > }; > }; > > - smd { > - compatible = "qcom,smd"; > + rpm: remoteproc { > + compatible = "qcom,apq8084-rpm-proc", "qcom,rpm-proc"; > > - rpm { > + smd-edge { > interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>; > qcom,ipc = <&apcs 8 0>; > qcom,smd-edge = <15>; > diff --git a/arch/arm/boot/dts/qcom-msm8226.dtsi b/arch/arm/boot/dts/qcom-msm8226.dtsi > index a3a9162e9c28..a3e8d023d0e6 100644 > --- a/arch/arm/boot/dts/qcom-msm8226.dtsi > +++ b/arch/arm/boot/dts/qcom-msm8226.dtsi > @@ -53,26 +53,10 @@ pmu { > IRQ_TYPE_LEVEL_HIGH)>; > }; > > - reserved-memory { > - #address-cells = <1>; > - #size-cells = <1>; > - ranges; > - > - smem_region: smem@3000000 { > - reg = <0x3000000 0x100000>; > - no-map; > - }; > - > - adsp_region: adsp@dc00000 { > - reg = <0x0dc00000 0x1900000>; > - no-map; > - }; > - }; > - > - smd { > - compatible = "qcom,smd"; > + rpm: remoteproc { > + compatible = "qcom,msm8226-rpm-proc", "qcom,rpm-proc"; > > - rpm { > + smd-edge { > interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>; > qcom,ipc = <&apcs 8 0>; > qcom,smd-edge = <15>; > @@ -120,6 +104,22 @@ rpmpd_opp_super_turbo: opp6 { > }; > }; > > + reserved-memory { > + #address-cells = <1>; > + #size-cells = <1>; > + ranges; > + > + smem_region: smem@3000000 { > + reg = <0x3000000 0x100000>; > + no-map; > + }; > + > + adsp_region: adsp@dc00000 { > + reg = <0x0dc00000 0x1900000>; > + no-map; > + }; > + }; > + > smem { > compatible = "qcom,smem"; > > diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi > index 58e144957c5d..0a5b5ecb5dfa 100644 > --- a/arch/arm/boot/dts/qcom-msm8974.dtsi > +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi > @@ -113,6 +113,28 @@ pmu { > interrupts = <GIC_PPI 7 0xf04>; > }; > > + rpm: remoteproc { > + compatible = "qcom,msm8974-rpm-proc", "qcom,rpm-proc"; > + > + smd-edge { > + interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>; > + qcom,ipc = <&apcs 8 0>; > + qcom,smd-edge = <15>; > + > + rpm_requests: rpm-requests { > + compatible = "qcom,rpm-msm8974"; > + qcom,smd-channels = "rpm_requests"; > + > + rpmcc: clock-controller { > + compatible = "qcom,rpmcc-msm8974", "qcom,rpmcc"; > + #clock-cells = <1>; > + clocks = <&xo_board>; > + clock-names = "xo"; > + }; > + }; > + }; > + }; > + > reserved-memory { > #address-cells = <1>; > #size-cells = <1>; > @@ -293,28 +315,6 @@ wcnss_smsm: wcnss@7 { > }; > }; > > - smd { > - compatible = "qcom,smd"; > - > - rpm { > - interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>; > - qcom,ipc = <&apcs 8 0>; > - qcom,smd-edge = <15>; > - > - rpm_requests: rpm-requests { > - compatible = "qcom,rpm-msm8974"; > - qcom,smd-channels = "rpm_requests"; > - > - rpmcc: clock-controller { > - compatible = "qcom,rpmcc-msm8974", "qcom,rpmcc"; > - #clock-cells = <1>; > - clocks = <&xo_board>; > - clock-names = "xo"; > - }; > - }; > - }; > - }; > - > soc: soc { > #address-cells = <1>; > #size-cells = <1>; >
The Resource Power Manager (RPM) currently does not have a dedicated device tree node that represents the remoteproc/subsystem. The functionality exposed through the SMD/GLINK channels is described in top-level nodes of the device tree. This makes it hard to group other functionality provided by the RPM together in the device tree. This series adds a single top-level remoteproc-rpm/rpm-proc device tree node that groups all RPM functionality together. Signed-off-by: Stephan Gerhold <stephan@gerhold.net> --- Changes in v2: - Pick up review/test tags from Konrad and Krzysztof - Rename "remoteproc-rpm" -> "remoteproc" everywhere (Krzysztof/Konrad) - "dt-bindings: remoteproc: Add Qualcomm RPM processor/subsystem" - Squash with other dt-bindings changes to have atomic refactoring (Krzysztof) - Add diagrams from discussion as clarification - "soc: qcom: smem: Add qcom_smem_is_available()" - Add return documentation in qcom_smem_is_available() (Konrad) - "soc: qcom: Add RPM processor/subsystem driver" - Add missing of_node_put(), fix children (Konrad) - Add depends on RPMSG_QCOM_SMD || RPMSG_QCOM_SMD=n to fix build error in weird kernel configurations (kernel test robot) - Link to v1: https://lore.kernel.org/r/20230531-rpm-rproc-v1-0-e0a3b6de1f14@gerhold.net --- Stephan Gerhold (12): dt-bindings soc: qcom: smd-rpm: Fix sort order dt-bindings: soc: qcom: smd-rpm: Add MSM8909 to qcom,smd-channels dt-bindings: soc: qcom: smd-rpm: Add some more compatibles soc: qcom: smd-rpm: Match rpmsg channel instead of compatible dt-bindings: remoteproc: Add Qualcomm RPM processor/subsystem soc: qcom: smem: Add qcom_smem_is_available() rpmsg: qcom_smd: Use qcom_smem_is_available() soc: qcom: Add RPM processor/subsystem driver arm64: dts: qcom: Add rpm-proc node for SMD platforms arm64: dts: qcom: Add rpm-proc node for GLINK gplatforms ARM: dts: qcom: Add rpm-proc node for SMD platforms ARM: dts: qcom: apq8064: Drop redundant /smd node .../bindings/remoteproc/qcom,rpm-proc.yaml | 171 +++++++++++++++++++++ .../devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml | 23 ++- .../devicetree/bindings/soc/qcom/qcom,smd.yaml | 7 + arch/arm/boot/dts/qcom-apq8064.dtsi | 40 ----- arch/arm/boot/dts/qcom-apq8084.dtsi | 6 +- arch/arm/boot/dts/qcom-msm8226.dtsi | 38 ++--- arch/arm/boot/dts/qcom-msm8974.dtsi | 44 +++--- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 48 +++--- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 28 ++-- arch/arm64/boot/dts/qcom/msm8916.dtsi | 6 +- arch/arm64/boot/dts/qcom/msm8939.dtsi | 112 +++++++------- arch/arm64/boot/dts/qcom/msm8953.dtsi | 136 ++++++++-------- arch/arm64/boot/dts/qcom/msm8976.dtsi | 152 +++++++++--------- arch/arm64/boot/dts/qcom/msm8994.dtsi | 99 ++++++------ arch/arm64/boot/dts/qcom/msm8996.dtsi | 113 +++++++------- arch/arm64/boot/dts/qcom/msm8998.dtsi | 98 ++++++------ arch/arm64/boot/dts/qcom/qcm2290.dtsi | 126 +++++++-------- arch/arm64/boot/dts/qcom/qcs404.dtsi | 152 +++++++++--------- arch/arm64/boot/dts/qcom/sdm630.dtsi | 132 ++++++++-------- arch/arm64/boot/dts/qcom/sm6115.dtsi | 128 +++++++-------- arch/arm64/boot/dts/qcom/sm6125.dtsi | 140 +++++++++-------- arch/arm64/boot/dts/qcom/sm6375.dtsi | 126 +++++++-------- drivers/rpmsg/qcom_smd.c | 10 +- drivers/soc/qcom/Kconfig | 1 + drivers/soc/qcom/Makefile | 2 +- drivers/soc/qcom/rpm-proc.c | 77 ++++++++++ drivers/soc/qcom/smd-rpm.c | 35 ++--- drivers/soc/qcom/smem.c | 11 ++ include/linux/soc/qcom/smem.h | 1 + 29 files changed, 1161 insertions(+), 901 deletions(-) --- base-commit: 8d5a57ea6a0b1722725170e32e511701ca7c454c change-id: 20230531-rpm-rproc-758364839cdd Best regards,