diff --git a/drivers/soc/qcom/msm_glink_ssr.c b/drivers/soc/qcom/msm_glink_ssr.c index b64496b24d1a..2ba7aa017c39 100644 --- a/drivers/soc/qcom/msm_glink_ssr.c +++ b/drivers/soc/qcom/msm_glink_ssr.c @@ -16,6 +16,7 @@ #define MSM_SSR_LOG_PAGE_CNT 4 static void *ssr_ilc; +static DEFINE_MUTEX(ssr_lock); #define MSM_SSR_INFO(x, ...) ipc_log_string(ssr_ilc, x, ##__VA_ARGS__) @@ -97,14 +98,15 @@ static int glink_ssr_ssr_cb(struct notifier_block *this, { struct glink_ssr_nb *nb = container_of(this, struct glink_ssr_nb, nb); struct glink_ssr *ssr = nb->ssr; - struct device *dev = ssr->dev; + struct device *dev; struct do_cleanup_msg msg; int ret; - if (!dev || !ssr->ept) - return NOTIFY_DONE; - kref_get(&ssr->refcount); + mutex_lock(&ssr_lock); + dev = ssr->dev; + if (!dev || !ssr->ept) + goto out; if (code == SUBSYS_AFTER_SHUTDOWN || code == SUBSYS_POWERUP_FAILURE) { ssr->seq_num++; @@ -124,14 +126,15 @@ static int glink_ssr_ssr_cb(struct notifier_block *this, if (ret) { MSM_SSR_ERR(dev, "fail to send do cleanup to %s %d\n", nb->ssr_label, ret); - kref_put(&ssr->refcount, glink_ssr_release); - return NOTIFY_DONE; + goto out; } ret = wait_for_completion_timeout(&ssr->completion, HZ); if (!ret) MSM_SSR_ERR(dev, "timeout waiting for cleanup resp\n"); } +out: + mutex_unlock(&ssr_lock); kref_put(&ssr->refcount, glink_ssr_release); return NOTIFY_DONE; } @@ -252,11 +255,12 @@ static void glink_ssr_remove(struct rpmsg_device *rpdev) { struct glink_ssr *ssr = dev_get_drvdata(&rpdev->dev); + mutex_lock(&ssr_lock); ssr->dev = NULL; ssr->ept = NULL; + mutex_unlock(&ssr_lock); dev_set_drvdata(&rpdev->dev, NULL); - schedule_work(&ssr->unreg_work); }