diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 0952eb14370c..e041cb1bb5a7 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -484,6 +484,7 @@ struct fastrpc_file { int debug_buf_alloced_attempted; /* Flag to indicate dynamic process creation status*/ bool in_process_create; + struct completion shutdown; }; static struct fastrpc_apps gfa; @@ -2972,8 +2973,10 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl) if (err) goto bail; VERIFY(err, fl->apps->channel[fl->cid].issubsystemup == 1); - if (err) + if (err) { + wait_for_completion(&fl->shutdown); goto bail; + } tgid = fl->tgid; ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); @@ -4130,6 +4133,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) hlist_add_head(&fl->hn, &me->drivers); spin_unlock(&me->hlock); mutex_init(&fl->perf_mutex); + init_completion(&fl->shutdown); return 0; } @@ -4615,6 +4619,8 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, { struct fastrpc_apps *me = &gfa; struct fastrpc_channel_ctx *ctx; + struct fastrpc_file *fl; + struct hlist_node *n; struct notif_data *notifdata = (struct notif_data *)data; int cid = -1; @@ -4627,6 +4633,16 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, ctx->ssrcount++; ctx->issubsystemup = 0; mutex_unlock(&me->channel[cid].smd_mutex); + } else if (code == SUBSYS_AFTER_SHUTDOWN) { + pr_info("adsprpc: %s: %s subsystem is down\n", + __func__, gcinfo[cid].subsys); + spin_lock(&me->hlock); + hlist_for_each_entry_safe(fl, n, &me->drivers, hn) { + if (fl->cid != cid) + continue; + complete(&fl->shutdown); + } + spin_unlock(&me->hlock); } else if (code == SUBSYS_RAMDUMP_NOTIFICATION) { if (cid == RH_CID) { if (me->ramdump_handle)