From 006d72da28db06a0762b1f536458ac1a9a4ba8d1 Mon Sep 17 00:00:00 2001 From: Clement Leger Date: Fri, 4 Oct 2019 19:44:24 +0200 Subject: remoteproc: remove useless typedef rproc_handle_resources_t is not used anymore, remove it. Signed-off-by: Clement Leger Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 3c5fbbbfb0f1..8cdbb0a88e34 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -44,8 +44,6 @@ static DEFINE_MUTEX(rproc_list_mutex); static LIST_HEAD(rproc_list); -typedef int (*rproc_handle_resources_t)(struct rproc *rproc, - struct resource_table *table, int len); typedef int (*rproc_handle_resource_t)(struct rproc *rproc, void *, int offset, int avail); -- cgit From 0ad82e3a2234dfa38ec835d1772e8c9af176d458 Mon Sep 17 00:00:00 2001 From: Ding Xiang Date: Tue, 24 Sep 2019 10:58:54 +0800 Subject: remoteproc: debug: Remove unneeded NULL check debugfs_remove_recursive will do NULL check, so remove the redundant null check Signed-off-by: Ding Xiang Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_debugfs.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c index 8cd4a0a3892b..dd93cf04e17f 100644 --- a/drivers/remoteproc/remoteproc_debugfs.c +++ b/drivers/remoteproc/remoteproc_debugfs.c @@ -333,9 +333,6 @@ struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, void rproc_delete_debug_dir(struct rproc *rproc) { - if (!rproc->dbg_dir) - return; - debugfs_remove_recursive(rproc->dbg_dir); } -- cgit From 1665cbd5731fa7c66103ec719c57922bbc457447 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Thu, 31 Oct 2019 19:45:01 -0700 Subject: remoteproc: qcom_q6v5_mss: Add support for MSM8998 MSM8998 sits between MSM8996 and SDM845 in terms of functionality needed to boot the modem subsystem. Booting mss allows for servicing the traditional cellular usecases along with the wireless usecases such as wifi. Signed-off-by: Jeffrey Hugo Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_mss.c | 52 +++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index de919f2e8b94..471128a2e723 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -61,6 +61,7 @@ #define QDSP6SS_GFMUX_CTL_REG 0x020 #define QDSP6SS_PWR_CTL_REG 0x030 #define QDSP6SS_MEM_PWR_CTL 0x0B0 +#define QDSP6V6SS_MEM_PWR_CTL 0x034 #define QDSP6SS_STRAP_ACC 0x110 /* AXI Halt Register Offsets */ @@ -196,6 +197,7 @@ enum { MSS_MSM8916, MSS_MSM8974, MSS_MSM8996, + MSS_MSM8998, MSS_SDM845, }; @@ -498,7 +500,10 @@ static int q6v5proc_reset(struct q6v5 *qproc) } goto pbl_wait; - } else if (qproc->version == MSS_MSM8996) { + } else if (qproc->version == MSS_MSM8996 || + qproc->version == MSS_MSM8998) { + int mem_pwr_ctl; + /* Override the ACC value if required */ writel(QDSP6SS_ACC_OVERRIDE_VAL, qproc->reg_base + QDSP6SS_STRAP_ACC); @@ -543,17 +548,24 @@ static int q6v5proc_reset(struct q6v5 *qproc) writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); /* Turn on L1, L2, ETB and JU memories 1 at a time */ - val = readl(qproc->reg_base + QDSP6SS_MEM_PWR_CTL); - for (i = 19; i >= 0; i--) { + if (qproc->version == MSS_MSM8996) { + mem_pwr_ctl = QDSP6SS_MEM_PWR_CTL; + i = 19; + } else { + /* MSS_MSM8998 */ + mem_pwr_ctl = QDSP6V6SS_MEM_PWR_CTL; + i = 28; + } + val = readl(qproc->reg_base + mem_pwr_ctl); + for (; i >= 0; i--) { val |= BIT(i); - writel(val, qproc->reg_base + - QDSP6SS_MEM_PWR_CTL); + writel(val, qproc->reg_base + mem_pwr_ctl); /* * Read back value to ensure the write is done then * wait for 1us for both memory peripheral and data * array to turn on. */ - val |= readl(qproc->reg_base + QDSP6SS_MEM_PWR_CTL); + val |= readl(qproc->reg_base + mem_pwr_ctl); udelay(1); } /* Remove word line clamp */ @@ -1571,6 +1583,33 @@ static const struct rproc_hexagon_res sdm845_mss = { .version = MSS_SDM845, }; +static const struct rproc_hexagon_res msm8998_mss = { + .hexagon_mba_image = "mba.mbn", + .proxy_clk_names = (char*[]){ + "xo", + "qdss", + "mem", + NULL + }, + .active_clk_names = (char*[]){ + "iface", + "bus", + "mem", + "gpll0_mss", + "mnoc_axi", + "snoc_axi", + NULL + }, + .proxy_pd_names = (char*[]){ + "cx", + "mx", + NULL + }, + .need_mem_protection = true, + .has_alt_reset = false, + .version = MSS_MSM8998, +}; + static const struct rproc_hexagon_res msm8996_mss = { .hexagon_mba_image = "mba.mbn", .proxy_supply = (struct qcom_mss_reg_res[]) { @@ -1677,6 +1716,7 @@ static const struct of_device_id q6v5_of_match[] = { { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss}, { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss}, { .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss}, + { .compatible = "qcom,msm8998-mss-pil", .data = &msm8998_mss}, { .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss}, { }, }; -- cgit From 99cf0361e7af29511309804bbedd240bf939cebd Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Thu, 17 Oct 2019 12:59:52 +0100 Subject: remoteproc: fix argument 2 of rproc_mem_entry_init The rproc_mem_entry_init() call takes a pointer to a vm as the second argument. The code is currently using a plain 0 as "NULL". Change to using NULL to fix the following sparse warnings: drivers/remoteproc/remoteproc_core.c:339:49: warning: Using plain integer as NULL pointer drivers/remoteproc/remoteproc_core.c:916:46: warning: Using plain integer as NULL pointer Signed-off-by: Ben Dooks Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 8cdbb0a88e34..c5689be3ebe2 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -334,7 +334,8 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i) return -ENOMEM; } else { /* Register carveout in in list */ - mem = rproc_mem_entry_init(dev, 0, 0, size, rsc->vring[i].da, + mem = rproc_mem_entry_init(dev, NULL, 0, + size, rsc->vring[i].da, rproc_alloc_carveout, rproc_release_carveout, "vdev%dvring%d", @@ -911,7 +912,7 @@ static int rproc_handle_carveout(struct rproc *rproc, } /* Register carveout in in list */ - carveout = rproc_mem_entry_init(dev, 0, 0, rsc->len, rsc->da, + carveout = rproc_mem_entry_init(dev, NULL, 0, rsc->len, rsc->da, rproc_alloc_carveout, rproc_release_carveout, rsc->name); if (!carveout) { -- cgit From 714cf5e3846047052fae89c7b927b886cc69d60c Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Fri, 25 Oct 2019 10:56:39 +0200 Subject: remoteproc: stm32: use workqueue to treat mailbox callback The mailbox callback is under interrupt context. A consequence is that RPMsg Callbacks are also in interrupt context. Create workqueue to treat the callbacks in normal context. Signed-off-by: Arnaud Pouliquen Signed-off-by: Bjorn Andersson --- drivers/remoteproc/stm32_rproc.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c index 2cf4b2992bfc..f791770b8850 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "remoteproc_internal.h" @@ -31,7 +32,9 @@ #define STM32_SMC_REG_WRITE 0x1 #define STM32_MBX_VQ0 "vq0" +#define STM32_MBX_VQ0_ID 0 #define STM32_MBX_VQ1 "vq1" +#define STM32_MBX_VQ1_ID 1 #define STM32_MBX_SHUTDOWN "shutdown" struct stm32_syscon { @@ -58,6 +61,7 @@ struct stm32_mbox { const unsigned char name[10]; struct mbox_chan *chan; struct mbox_client client; + struct work_struct vq_work; int vq_id; }; @@ -68,6 +72,7 @@ struct stm32_rproc { u32 nb_rmems; struct stm32_rproc_mem *rmems; struct stm32_mbox mb[MBOX_NB_MBX]; + struct workqueue_struct *workqueue; bool secured_soc; }; @@ -261,13 +266,22 @@ static irqreturn_t stm32_rproc_wdg(int irq, void *data) return IRQ_HANDLED; } +static void stm32_rproc_mb_vq_work(struct work_struct *work) +{ + struct stm32_mbox *mb = container_of(work, struct stm32_mbox, vq_work); + struct rproc *rproc = dev_get_drvdata(mb->client.dev); + + if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE) + dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id); +} + static void stm32_rproc_mb_callback(struct mbox_client *cl, void *data) { struct rproc *rproc = dev_get_drvdata(cl->dev); struct stm32_mbox *mb = container_of(cl, struct stm32_mbox, client); + struct stm32_rproc *ddata = rproc->priv; - if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE) - dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id); + queue_work(ddata->workqueue, &mb->vq_work); } static void stm32_rproc_free_mbox(struct rproc *rproc) @@ -285,7 +299,7 @@ static void stm32_rproc_free_mbox(struct rproc *rproc) static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = { { .name = STM32_MBX_VQ0, - .vq_id = 0, + .vq_id = STM32_MBX_VQ0_ID, .client = { .rx_callback = stm32_rproc_mb_callback, .tx_block = false, @@ -293,7 +307,7 @@ static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = { }, { .name = STM32_MBX_VQ1, - .vq_id = 1, + .vq_id = STM32_MBX_VQ1_ID, .client = { .rx_callback = stm32_rproc_mb_callback, .tx_block = false, @@ -332,6 +346,10 @@ static void stm32_rproc_request_mbox(struct rproc *rproc) dev_warn(dev, "cannot get %s mbox\n", name); ddata->mb[i].chan = NULL; } + if (ddata->mb[i].vq_id >= 0) { + INIT_WORK(&ddata->mb[i].vq_work, + stm32_rproc_mb_vq_work); + } } } @@ -589,12 +607,18 @@ static int stm32_rproc_probe(struct platform_device *pdev) rproc->has_iommu = false; ddata = rproc->priv; + ddata->workqueue = create_workqueue(dev_name(dev)); + if (!ddata->workqueue) { + dev_err(dev, "cannot create workqueue\n"); + ret = -ENOMEM; + goto free_rproc; + } platform_set_drvdata(pdev, rproc); ret = stm32_rproc_parse_dt(pdev); if (ret) - goto free_rproc; + goto free_wkq; stm32_rproc_request_mbox(rproc); @@ -606,6 +630,8 @@ static int stm32_rproc_probe(struct platform_device *pdev) free_mb: stm32_rproc_free_mbox(rproc); +free_wkq: + destroy_workqueue(ddata->workqueue); free_rproc: rproc_free(rproc); return ret; @@ -614,12 +640,14 @@ free_rproc: static int stm32_rproc_remove(struct platform_device *pdev) { struct rproc *rproc = platform_get_drvdata(pdev); + struct stm32_rproc *ddata = rproc->priv; if (atomic_read(&rproc->power) > 0) rproc_shutdown(rproc); rproc_del(rproc); stm32_rproc_free_mbox(rproc); + destroy_workqueue(ddata->workqueue); rproc_free(rproc); return 0; -- cgit From 00a0eec59ddbb1ce966b19097d8a8d2f777e726a Mon Sep 17 00:00:00 2001 From: Clement Leger Date: Fri, 4 Oct 2019 09:37:36 +0200 Subject: remoteproc: Fix wrong rvring index computation Index of rvring is computed using pointer arithmetic. However, since rvring->rvdev->vring is the base of the vring array, computation of rvring idx should be reversed. It previously lead to writing at negative indices in the resource table. Signed-off-by: Clement Leger Link: https://lore.kernel.org/r/20191004073736.8327-1-cleger@kalray.eu Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index c5689be3ebe2..307df98347ba 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -399,7 +399,7 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i) void rproc_free_vring(struct rproc_vring *rvring) { struct rproc *rproc = rvring->rvdev->rproc; - int idx = rvring->rvdev->vring - rvring; + int idx = rvring - rvring->rvdev->vring; struct fw_rsc_vdev *rsc; idr_remove(&rproc->notifyids, rvring->notifyid); -- cgit From 410119ee29b6c14b88bae8cfa87b202e3fbe0488 Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Mon, 26 Aug 2019 17:38:43 +0200 Subject: remoteproc: stm32: wakeup the system by wdg irq If the device node defines the 'wakeup-source' property, use the WDG exti IRQ as a wakeup source of the system. Signed-off-by: Fabien Dessenne Link: https://lore.kernel.org/r/1566833923-16718-3-git-send-email-fabien.dessenne@st.com [bjorn: Replace ifdef with __maybe_unused for suspend/resume functions] Signed-off-by: Bjorn Andersson --- drivers/remoteproc/stm32_rproc.c | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'drivers') diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c index f791770b8850..4adc9cefb532 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,7 @@ struct stm32_rproc { struct reset_control *rst; struct stm32_syscon hold_boot; struct stm32_syscon pdds; + int wdg_irq; u32 nb_rmems; struct stm32_rproc_mem *rmems; struct stm32_mbox mb[MBOX_NB_MBX]; @@ -546,6 +548,13 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev) return err; } + ddata->wdg_irq = irq; + + if (of_property_read_bool(np, "wakeup-source")) { + device_init_wakeup(dev, true); + dev_pm_set_wake_irq(dev, irq); + } + dev_info(dev, "wdg irq registered\n"); } @@ -633,6 +642,10 @@ free_mb: free_wkq: destroy_workqueue(ddata->workqueue); free_rproc: + if (device_may_wakeup(dev)) { + dev_pm_clear_wake_irq(dev); + device_init_wakeup(dev, false); + } rproc_free(rproc); return ret; } @@ -641,6 +654,7 @@ static int stm32_rproc_remove(struct platform_device *pdev) { struct rproc *rproc = platform_get_drvdata(pdev); struct stm32_rproc *ddata = rproc->priv; + struct device *dev = &pdev->dev; if (atomic_read(&rproc->power) > 0) rproc_shutdown(rproc); @@ -648,16 +662,47 @@ static int stm32_rproc_remove(struct platform_device *pdev) rproc_del(rproc); stm32_rproc_free_mbox(rproc); destroy_workqueue(ddata->workqueue); + + if (device_may_wakeup(dev)) { + dev_pm_clear_wake_irq(dev); + device_init_wakeup(dev, false); + } rproc_free(rproc); return 0; } +static int __maybe_unused stm32_rproc_suspend(struct device *dev) +{ + struct rproc *rproc = dev_get_drvdata(dev); + struct stm32_rproc *ddata = rproc->priv; + + if (device_may_wakeup(dev)) + return enable_irq_wake(ddata->wdg_irq); + + return 0; +} + +static int __maybe_unused stm32_rproc_resume(struct device *dev) +{ + struct rproc *rproc = dev_get_drvdata(dev); + struct stm32_rproc *ddata = rproc->priv; + + if (device_may_wakeup(dev)) + return disable_irq_wake(ddata->wdg_irq); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(stm32_rproc_pm_ops, + stm32_rproc_suspend, stm32_rproc_resume); + static struct platform_driver stm32_rproc_driver = { .probe = stm32_rproc_probe, .remove = stm32_rproc_remove, .driver = { .name = "stm32-rproc", + .pm = &stm32_rproc_pm_ops, .of_match_table = of_match_ptr(stm32_rproc_match), }, }; -- cgit From 4a56e423e0e19b616c2f2615674a7dffdb77afd6 Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Fri, 15 Nov 2019 11:03:08 +0100 Subject: remoteproc: stm32: fix probe error case If the rproc driver is probed before the mailbox driver and if the rproc Device Tree node has some mailbox properties, the rproc driver probe shall be deferred instead of being probed without mailbox support. Tested-by: Mathieu Poirier Signed-off-by: Fabien Dessenne Link: https://lore.kernel.org/r/1573812188-19842-1-git-send-email-fabien.dessenne@st.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/stm32_rproc.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c index 4adc9cefb532..a18f88044111 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -326,11 +326,12 @@ static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = { } }; -static void stm32_rproc_request_mbox(struct rproc *rproc) +static int stm32_rproc_request_mbox(struct rproc *rproc) { struct stm32_rproc *ddata = rproc->priv; struct device *dev = &rproc->dev; unsigned int i; + int j; const unsigned char *name; struct mbox_client *cl; @@ -345,6 +346,8 @@ static void stm32_rproc_request_mbox(struct rproc *rproc) ddata->mb[i].chan = mbox_request_channel_byname(cl, name); if (IS_ERR(ddata->mb[i].chan)) { + if (PTR_ERR(ddata->mb[i].chan) == -EPROBE_DEFER) + goto err_probe; dev_warn(dev, "cannot get %s mbox\n", name); ddata->mb[i].chan = NULL; } @@ -353,6 +356,14 @@ static void stm32_rproc_request_mbox(struct rproc *rproc) stm32_rproc_mb_vq_work); } } + + return 0; + +err_probe: + for (j = i - 1; j >= 0; j--) + if (ddata->mb[j].chan) + mbox_free_channel(ddata->mb[j].chan); + return -EPROBE_DEFER; } static int stm32_rproc_set_hold_boot(struct rproc *rproc, bool hold) @@ -629,7 +640,9 @@ static int stm32_rproc_probe(struct platform_device *pdev) if (ret) goto free_wkq; - stm32_rproc_request_mbox(rproc); + ret = stm32_rproc_request_mbox(rproc); + if (ret) + goto free_rproc; ret = rproc_add(rproc); if (ret) -- cgit