From 3103405f0a570b5472560ed094e562cba9d33028 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Fri, 12 Aug 2016 18:18:58 -0700 Subject: dt-binding: remoteproc: Introduce Qualcomm WCNSS loader binding The document defines the binding for a component that loads firmware for and boots the Qualcomm WCNSS core. Acked-by: Rob Herring Signed-off-by: Bjorn Andersson Signed-off-by: Bjorn Andersson --- .../bindings/remoteproc/qcom,wcnss-pil.txt | 132 +++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt b/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt new file mode 100644 index 000000000000..0d2361ebe3d7 --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt @@ -0,0 +1,132 @@ +Qualcomm WCNSS Peripheral Image Loader + +This document defines the binding for a component that loads and boots firmware +on the Qualcomm WCNSS core. + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,riva-pil", + "qcom,pronto-v1-pil", + "qcom,pronto-v2-pil" + +- reg: + Usage: required + Value type: + Definition: must specify the base address and size of the CCU, DXE and + PMU register blocks + +- reg-names: + Usage: required + Value type: + Definition: must be "ccu", "dxe", "pmu" + +- interrupts-extended: + Usage: required + Value type: + Definition: must list the watchdog and fatal IRQs and may specify the + ready, handover and stop-ack IRQs + +- interrupt-names: + Usage: required + Value type: + Definition: should be "wdog", "fatal", optionally followed by "ready", + "handover", "stop-ack" + +- vddmx-supply: +- vddcx-supply: +- vddpx-supply: + Usage: required + Value type: + Definition: reference to the regulators to be held on behalf of the + booting of the WCNSS core + +- qcom,smem-states: + Usage: optional + Value type: + Definition: reference to the SMEM state used to indicate to WCNSS that + it should shut down + +- qcom,smem-state-names: + Usage: optional + Value type: + Definition: should be "stop" + +- memory-region: + Usage: required + Value type: + Definition: reference to reserved-memory node for the remote processor + see ../reserved-memory/reserved-memory.txt + += SUBNODES +A single subnode of the WCNSS PIL describes the attached rf module and its +resource dependencies. + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,wcn3620", + "qcom,wcn3660", + "qcom,wcn3680" + +- clocks: + Usage: required + Value type: + Definition: should specify the xo clock and optionally the rf clock + +- clock-names: + Usage: required + Value type: + Definition: should be "xo", optionally followed by "rf" + +- vddxo-supply: +- vddrfa-supply: +- vddpa-supply: +- vdddig-supply: + Usage: required + Value type: + Definition: reference to the regulators to be held on behalf of the + booting of the WCNSS core + += EXAMPLE +The following example describes the resources needed to boot control the WCNSS, +with attached WCN3680, as it is commonly found on MSM8974 boards. + +pronto@fb204000 { + compatible = "qcom,pronto-v2-pil"; + reg = <0xfb204000 0x2000>, <0xfb202000 0x1000>, <0xfb21b000 0x3000>; + reg-names = "ccu", "dxe", "pmu"; + + interrupts-extended = <&intc 0 149 1>, + <&wcnss_smp2p_slave 0 0>, + <&wcnss_smp2p_slave 1 0>, + <&wcnss_smp2p_slave 2 0>, + <&wcnss_smp2p_slave 3 0>; + interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack"; + + vddmx-supply = <&pm8841_s1>; + vddcx-supply = <&pm8841_s2>; + vddpx-supply = <&pm8941_s3>; + + qcom,smem-states = <&wcnss_smp2p_out 0>; + qcom,smem-state-names = "stop"; + + memory-region = <&wcnss_region>; + + pinctrl-names = "default"; + pinctrl-0 = <&wcnss_pin_a>; + + iris { + compatible = "qcom,wcn3680"; + + clocks = <&rpmcc RPM_CXO_CLK_SRC>, <&rpmcc RPM_CXO_A2>; + clock-names = "xo", "rf"; + + vddxo-supply = <&pm8941_l6>; + vddrfa-supply = <&pm8941_l11>; + vddpa-supply = <&pm8941_l19>; + vdddig-supply = <&pm8941_s3>; + }; +}; -- cgit v1.2.3 From 433c0e04bc06da6d049c691a9ef238d61edb841c Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Sun, 2 Oct 2016 17:46:38 -0700 Subject: remoteproc: Split driver and consumer dereferencing In order to be able to lock a rproc driver implementations only when used by a client, we must differ between the dereference operation of a client and the implementation itself. This patch brings no functional change. Signed-off-by: Bjorn Andersson --- Documentation/remoteproc.txt | 6 +++--- drivers/remoteproc/da8xx_remoteproc.c | 4 ++-- drivers/remoteproc/omap_remoteproc.c | 4 ++-- drivers/remoteproc/qcom_q6v5_pil.c | 4 ++-- drivers/remoteproc/qcom_wcnss.c | 4 ++-- drivers/remoteproc/remoteproc_core.c | 21 ++++++++++++++++++--- drivers/remoteproc/st_remoteproc.c | 4 ++-- drivers/remoteproc/ste_modem_rproc.c | 4 ++-- drivers/remoteproc/wkup_m3_rproc.c | 4 ++-- include/linux/remoteproc.h | 1 + 10 files changed, 36 insertions(+), 20 deletions(-) (limited to 'Documentation') diff --git a/Documentation/remoteproc.txt b/Documentation/remoteproc.txt index ef0219fa4bb4..f07597482351 100644 --- a/Documentation/remoteproc.txt +++ b/Documentation/remoteproc.txt @@ -101,9 +101,9 @@ int dummy_rproc_example(struct rproc *my_rproc) On success, the new rproc is returned, and on failure, NULL. Note: _never_ directly deallocate @rproc, even if it was not registered - yet. Instead, when you need to unroll rproc_alloc(), use rproc_put(). + yet. Instead, when you need to unroll rproc_alloc(), use rproc_free(). - void rproc_put(struct rproc *rproc) + void rproc_free(struct rproc *rproc) - Free an rproc handle that was allocated by rproc_alloc. This function essentially unrolls rproc_alloc(), by decrementing the rproc's refcount. It doesn't directly free rproc; that would happen @@ -131,7 +131,7 @@ int dummy_rproc_example(struct rproc *my_rproc) has completed successfully. After rproc_del() returns, @rproc is still valid, and its - last refcount should be decremented by calling rproc_put(). + last refcount should be decremented by calling rproc_free(). Returns 0 on success and -EINVAL if @rproc isn't valid. diff --git a/drivers/remoteproc/da8xx_remoteproc.c b/drivers/remoteproc/da8xx_remoteproc.c index 12823d078e1e..1afac8f31be0 100644 --- a/drivers/remoteproc/da8xx_remoteproc.c +++ b/drivers/remoteproc/da8xx_remoteproc.c @@ -261,7 +261,7 @@ static int da8xx_rproc_probe(struct platform_device *pdev) return 0; free_rproc: - rproc_put(rproc); + rproc_free(rproc); return ret; } @@ -290,7 +290,7 @@ static int da8xx_rproc_remove(struct platform_device *pdev) disable_irq(drproc->irq); rproc_del(rproc); - rproc_put(rproc); + rproc_free(rproc); return 0; } diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index 01e234cb9157..fa63bf2eb885 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -215,7 +215,7 @@ static int omap_rproc_probe(struct platform_device *pdev) return 0; free_rproc: - rproc_put(rproc); + rproc_free(rproc); return ret; } @@ -224,7 +224,7 @@ static int omap_rproc_remove(struct platform_device *pdev) struct rproc *rproc = platform_get_drvdata(pdev); rproc_del(rproc); - rproc_put(rproc); + rproc_free(rproc); return 0; } diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c index 05b04573e87d..2e0caaaa766a 100644 --- a/drivers/remoteproc/qcom_q6v5_pil.c +++ b/drivers/remoteproc/qcom_q6v5_pil.c @@ -875,7 +875,7 @@ static int q6v5_probe(struct platform_device *pdev) return 0; free_rproc: - rproc_put(rproc); + rproc_free(rproc); return ret; } @@ -885,7 +885,7 @@ static int q6v5_remove(struct platform_device *pdev) struct q6v5 *qproc = platform_get_drvdata(pdev); rproc_del(qproc->rproc); - rproc_put(qproc->rproc); + rproc_free(qproc->rproc); return 0; } diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c index 1917de7db91c..f5cedeaafba1 100644 --- a/drivers/remoteproc/qcom_wcnss.c +++ b/drivers/remoteproc/qcom_wcnss.c @@ -585,7 +585,7 @@ static int wcnss_probe(struct platform_device *pdev) return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); free_rproc: - rproc_put(rproc); + rproc_free(rproc); return ret; } @@ -598,7 +598,7 @@ static int wcnss_remove(struct platform_device *pdev) qcom_smem_state_put(wcnss->state); rproc_del(wcnss->rproc); - rproc_put(wcnss->rproc); + rproc_free(wcnss->rproc); return 0; } diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 3da566b0d437..ede3af14b9d0 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1307,7 +1307,7 @@ static struct device_type rproc_type = { * On success the new rproc is returned, and on failure, NULL. * * Note: _never_ directly deallocate @rproc, even if it was not registered - * yet. Instead, when you need to unroll rproc_alloc(), use rproc_put(). + * yet. Instead, when you need to unroll rproc_alloc(), use rproc_free(). */ struct rproc *rproc_alloc(struct device *dev, const char *name, const struct rproc_ops *ops, @@ -1386,7 +1386,22 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, EXPORT_SYMBOL(rproc_alloc); /** - * rproc_put() - unroll rproc_alloc() + * rproc_free() - unroll rproc_alloc() + * @rproc: the remote processor handle + * + * This function decrements the rproc dev refcount. + * + * If no one holds any reference to rproc anymore, then its refcount would + * now drop to zero, and it would be freed. + */ +void rproc_free(struct rproc *rproc) +{ + put_device(&rproc->dev); +} +EXPORT_SYMBOL(rproc_free); + +/** + * rproc_put() - release rproc reference * @rproc: the remote processor handle * * This function decrements the rproc dev refcount. @@ -1411,7 +1426,7 @@ EXPORT_SYMBOL(rproc_put); * * After rproc_del() returns, @rproc isn't freed yet, because * of the outstanding reference created by rproc_alloc. To decrement that - * one last refcount, one still needs to call rproc_put(). + * one last refcount, one still needs to call rproc_free(). * * Returns 0 on success and -EINVAL if @rproc isn't valid. */ diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c index 6f056caa8a56..ae8963fcc8c8 100644 --- a/drivers/remoteproc/st_remoteproc.c +++ b/drivers/remoteproc/st_remoteproc.c @@ -262,7 +262,7 @@ static int st_rproc_probe(struct platform_device *pdev) return 0; free_rproc: - rproc_put(rproc); + rproc_free(rproc); return ret; } @@ -277,7 +277,7 @@ static int st_rproc_remove(struct platform_device *pdev) of_reserved_mem_device_release(&pdev->dev); - rproc_put(rproc); + rproc_free(rproc); return 0; } diff --git a/drivers/remoteproc/ste_modem_rproc.c b/drivers/remoteproc/ste_modem_rproc.c index 53dc17bdd54e..03d69a9a3c5b 100644 --- a/drivers/remoteproc/ste_modem_rproc.c +++ b/drivers/remoteproc/ste_modem_rproc.c @@ -257,7 +257,7 @@ static int sproc_drv_remove(struct platform_device *pdev) rproc_del(sproc->rproc); dma_free_coherent(sproc->rproc->dev.parent, SPROC_FW_SIZE, sproc->fw_addr, sproc->fw_dma_addr); - rproc_put(sproc->rproc); + rproc_free(sproc->rproc); mdev->drv_data = NULL; @@ -325,7 +325,7 @@ free_mem: free_rproc: /* Reset device data upon error */ mdev->drv_data = NULL; - rproc_put(rproc); + rproc_free(rproc); return err; } diff --git a/drivers/remoteproc/wkup_m3_rproc.c b/drivers/remoteproc/wkup_m3_rproc.c index 3811cb522af3..18175d0331fd 100644 --- a/drivers/remoteproc/wkup_m3_rproc.c +++ b/drivers/remoteproc/wkup_m3_rproc.c @@ -208,7 +208,7 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev) return 0; err_put_rproc: - rproc_put(rproc); + rproc_free(rproc); err: pm_runtime_put_noidle(dev); pm_runtime_disable(dev); @@ -220,7 +220,7 @@ static int wkup_m3_rproc_remove(struct platform_device *pdev) struct rproc *rproc = platform_get_drvdata(pdev); rproc_del(rproc); - rproc_put(rproc); + rproc_free(rproc); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index c321eab5054e..930023b7c825 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -493,6 +493,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, void rproc_put(struct rproc *rproc); int rproc_add(struct rproc *rproc); int rproc_del(struct rproc *rproc); +void rproc_free(struct rproc *rproc); int rproc_boot(struct rproc *rproc); void rproc_shutdown(struct rproc *rproc); -- cgit v1.2.3