summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorRobin Gong <yibin.gong@nxp.com>2017-02-20 08:58:30 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit883ba86cc52c2365d6222c0f8226e7776def7b17 (patch)
tree539ae2d8270c7086addf814f74d8a860a534e0f2 /arch/arm
parent3044417b34d68efd9a5af13119f3277fd6bdd23c (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.c20
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);