mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 04:42:04 -04:00
Merge "soc: qcom: glink_probe: use lock while sending ssr notification"
This commit is contained in:
commit
75e68a7d23
1 changed files with 27 additions and 6 deletions
|
|
@ -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__)
|
||||
|
||||
|
|
@ -64,8 +65,21 @@ struct glink_ssr {
|
|||
u32 seq_num;
|
||||
struct completion completion;
|
||||
struct work_struct unreg_work;
|
||||
struct kref refcount;
|
||||
};
|
||||
|
||||
static void glink_ssr_release(struct kref *ref)
|
||||
{
|
||||
struct glink_ssr *ssr = container_of(ref, struct glink_ssr,
|
||||
refcount);
|
||||
struct glink_ssr_nb *nb, *tmp;
|
||||
|
||||
list_for_each_entry_safe(nb, tmp, &ssr->notify_list, list)
|
||||
kfree(nb);
|
||||
|
||||
kfree(ssr);
|
||||
}
|
||||
|
||||
static void glink_ssr_ssr_unreg_work(struct work_struct *work)
|
||||
{
|
||||
struct glink_ssr *ssr = container_of(work, struct glink_ssr,
|
||||
|
|
@ -75,9 +89,8 @@ static void glink_ssr_ssr_unreg_work(struct work_struct *work)
|
|||
list_for_each_entry_safe(nb, tmp, &ssr->notify_list, list) {
|
||||
subsys_notif_unregister_notifier(nb->ssr_register_handle,
|
||||
&nb->nb);
|
||||
kfree(nb);
|
||||
}
|
||||
kfree(ssr);
|
||||
kref_put(&ssr->refcount, glink_ssr_release);
|
||||
}
|
||||
|
||||
static int glink_ssr_ssr_cb(struct notifier_block *this,
|
||||
|
|
@ -85,12 +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;
|
||||
|
||||
kref_get(&ssr->refcount);
|
||||
mutex_lock(&ssr_lock);
|
||||
dev = ssr->dev;
|
||||
if (!dev || !ssr->ept)
|
||||
return NOTIFY_DONE;
|
||||
goto out;
|
||||
|
||||
if (code == SUBSYS_AFTER_SHUTDOWN || code == SUBSYS_POWERUP_FAILURE) {
|
||||
ssr->seq_num++;
|
||||
|
|
@ -110,13 +126,16 @@ 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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -217,6 +236,7 @@ static int glink_ssr_probe(struct rpmsg_device *rpdev)
|
|||
INIT_LIST_HEAD(&ssr->notify_list);
|
||||
init_completion(&ssr->completion);
|
||||
INIT_WORK(&ssr->unreg_work, glink_ssr_ssr_unreg_work);
|
||||
kref_init(&ssr->refcount);
|
||||
|
||||
ssr->dev = &rpdev->dev;
|
||||
ssr->ept = rpdev->ept;
|
||||
|
|
@ -235,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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue