Commit 714cf5e3 authored by Arnaud Pouliquen's avatar Arnaud Pouliquen Committed by Bjorn Andersson

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: default avatarArnaud Pouliquen <arnaud.pouliquen@st.com>
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
parent 99cf0361
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/remoteproc.h> #include <linux/remoteproc.h>
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/workqueue.h>
#include "remoteproc_internal.h" #include "remoteproc_internal.h"
...@@ -31,7 +32,9 @@ ...@@ -31,7 +32,9 @@
#define STM32_SMC_REG_WRITE 0x1 #define STM32_SMC_REG_WRITE 0x1
#define STM32_MBX_VQ0 "vq0" #define STM32_MBX_VQ0 "vq0"
#define STM32_MBX_VQ0_ID 0
#define STM32_MBX_VQ1 "vq1" #define STM32_MBX_VQ1 "vq1"
#define STM32_MBX_VQ1_ID 1
#define STM32_MBX_SHUTDOWN "shutdown" #define STM32_MBX_SHUTDOWN "shutdown"
struct stm32_syscon { struct stm32_syscon {
...@@ -58,6 +61,7 @@ struct stm32_mbox { ...@@ -58,6 +61,7 @@ struct stm32_mbox {
const unsigned char name[10]; const unsigned char name[10];
struct mbox_chan *chan; struct mbox_chan *chan;
struct mbox_client client; struct mbox_client client;
struct work_struct vq_work;
int vq_id; int vq_id;
}; };
...@@ -68,6 +72,7 @@ struct stm32_rproc { ...@@ -68,6 +72,7 @@ struct stm32_rproc {
u32 nb_rmems; u32 nb_rmems;
struct stm32_rproc_mem *rmems; struct stm32_rproc_mem *rmems;
struct stm32_mbox mb[MBOX_NB_MBX]; struct stm32_mbox mb[MBOX_NB_MBX];
struct workqueue_struct *workqueue;
bool secured_soc; bool secured_soc;
}; };
...@@ -261,13 +266,22 @@ static irqreturn_t stm32_rproc_wdg(int irq, void *data) ...@@ -261,13 +266,22 @@ static irqreturn_t stm32_rproc_wdg(int irq, void *data)
return IRQ_HANDLED; 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) static void stm32_rproc_mb_callback(struct mbox_client *cl, void *data)
{ {
struct rproc *rproc = dev_get_drvdata(cl->dev); struct rproc *rproc = dev_get_drvdata(cl->dev);
struct stm32_mbox *mb = container_of(cl, struct stm32_mbox, client); 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) queue_work(ddata->workqueue, &mb->vq_work);
dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id);
} }
static void stm32_rproc_free_mbox(struct rproc *rproc) static void stm32_rproc_free_mbox(struct rproc *rproc)
...@@ -285,7 +299,7 @@ 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] = { static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = {
{ {
.name = STM32_MBX_VQ0, .name = STM32_MBX_VQ0,
.vq_id = 0, .vq_id = STM32_MBX_VQ0_ID,
.client = { .client = {
.rx_callback = stm32_rproc_mb_callback, .rx_callback = stm32_rproc_mb_callback,
.tx_block = false, .tx_block = false,
...@@ -293,7 +307,7 @@ static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = { ...@@ -293,7 +307,7 @@ static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = {
}, },
{ {
.name = STM32_MBX_VQ1, .name = STM32_MBX_VQ1,
.vq_id = 1, .vq_id = STM32_MBX_VQ1_ID,
.client = { .client = {
.rx_callback = stm32_rproc_mb_callback, .rx_callback = stm32_rproc_mb_callback,
.tx_block = false, .tx_block = false,
...@@ -332,6 +346,10 @@ static void stm32_rproc_request_mbox(struct rproc *rproc) ...@@ -332,6 +346,10 @@ static void stm32_rproc_request_mbox(struct rproc *rproc)
dev_warn(dev, "cannot get %s mbox\n", name); dev_warn(dev, "cannot get %s mbox\n", name);
ddata->mb[i].chan = NULL; 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) ...@@ -589,12 +607,18 @@ static int stm32_rproc_probe(struct platform_device *pdev)
rproc->has_iommu = false; rproc->has_iommu = false;
ddata = rproc->priv; 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); platform_set_drvdata(pdev, rproc);
ret = stm32_rproc_parse_dt(pdev); ret = stm32_rproc_parse_dt(pdev);
if (ret) if (ret)
goto free_rproc; goto free_wkq;
stm32_rproc_request_mbox(rproc); stm32_rproc_request_mbox(rproc);
...@@ -606,6 +630,8 @@ static int stm32_rproc_probe(struct platform_device *pdev) ...@@ -606,6 +630,8 @@ static int stm32_rproc_probe(struct platform_device *pdev)
free_mb: free_mb:
stm32_rproc_free_mbox(rproc); stm32_rproc_free_mbox(rproc);
free_wkq:
destroy_workqueue(ddata->workqueue);
free_rproc: free_rproc:
rproc_free(rproc); rproc_free(rproc);
return ret; return ret;
...@@ -614,12 +640,14 @@ static int stm32_rproc_probe(struct platform_device *pdev) ...@@ -614,12 +640,14 @@ static int stm32_rproc_probe(struct platform_device *pdev)
static int stm32_rproc_remove(struct platform_device *pdev) static int stm32_rproc_remove(struct platform_device *pdev)
{ {
struct rproc *rproc = platform_get_drvdata(pdev); struct rproc *rproc = platform_get_drvdata(pdev);
struct stm32_rproc *ddata = rproc->priv;
if (atomic_read(&rproc->power) > 0) if (atomic_read(&rproc->power) > 0)
rproc_shutdown(rproc); rproc_shutdown(rproc);
rproc_del(rproc); rproc_del(rproc);
stm32_rproc_free_mbox(rproc); stm32_rproc_free_mbox(rproc);
destroy_workqueue(ddata->workqueue);
rproc_free(rproc); rproc_free(rproc);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment