diff options
author | Robin Gong <yibin.gong@nxp.com> | 2017-02-20 08:58:30 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 883ba86cc52c2365d6222c0f8226e7776def7b17 (patch) | |
tree | 539ae2d8270c7086addf814f74d8a860a534e0f2 /arch/arm | |
parent | 3044417b34d68efd9a5af13119f3277fd6bdd23c (diff) |
MLK-14241-2 ARM: imx: pm-rpmsg: add mutex protect for pm_send_message
Heatbeat workqueue and suspend/resume may call pm_send_message at the same
time as pf1550-regulator-rpmsg driver, so add mutex to avoid the potential
pm_qpos_* reentry issue.
Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-imx/pm-rpmsg.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/arm/mach-imx/pm-rpmsg.c b/arch/arm/mach-imx/pm-rpmsg.c index e6f02d991133..4cd9262c3150 100644 --- a/arch/arm/mach-imx/pm-rpmsg.c +++ b/arch/arm/mach-imx/pm-rpmsg.c @@ -54,6 +54,7 @@ struct pm_rpmsg_info { struct pm_qos_request pm_qos_req; struct notifier_block restart_handler; struct completion cmd_complete; + struct mutex lock; }; static struct pm_rpmsg_info pm_rpmsg; @@ -75,6 +76,8 @@ static int pm_send_message(struct pm_rpmsg_data *msg, "rpmsg channel not ready, m4 image ready?\n"); return -EINVAL; } + + mutex_lock(&info->lock); pm_qos_add_request(&info->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0); @@ -83,11 +86,9 @@ static int pm_send_message(struct pm_rpmsg_data *msg, err = rpmsg_send(info->rpdev->ept, (void *)msg, sizeof(struct pm_rpmsg_data)); - pm_qos_remove_request(&info->pm_qos_req); - if (err) { dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err); - return err; + goto err_out; } if (ack) { @@ -95,18 +96,24 @@ static int pm_send_message(struct pm_rpmsg_data *msg, msecs_to_jiffies(RPMSG_TIMEOUT)); if (!err) { dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n"); - return -ETIMEDOUT; + err = -ETIMEDOUT; + goto err_out; } if (info->msg->data != 0) { dev_err(&info->rpdev->dev, "rpmsg not ack %d!\n", info->msg->data); - return -EINVAL; + err = -EINVAL; + goto err_out; } err = 0; } +err_out: + pm_qos_remove_request(&info->pm_qos_req); + mutex_unlock(&info->lock); + return err; } @@ -188,12 +195,13 @@ static int pm_rpmsg_probe(struct rpmsg_device *rpdev) rpdev->src, rpdev->dst); init_completion(&pm_rpmsg.cmd_complete); + mutex_init(&pm_rpmsg.lock); INIT_DELAYED_WORK(&heart_beat_work, pm_heart_beat_work_handler); schedule_delayed_work(&heart_beat_work, - msecs_to_jiffies(10000)); + msecs_to_jiffies(10000)); pm_vlls_notify_m4(false); |