From 34164b74a60db76ac5f7e07036e810fbdc78c52b Mon Sep 17 00:00:00 2001 From: Mohit Aggarwal Date: Mon, 1 May 2017 15:31:32 +0530 Subject: [PATCH] diag: Open glink channels in workqueue context Currently, on loading WDSP, diag is trying to close socket transport and opening glink channels. Due to this, deadlock is happening and wdsp channels are not getting opened properly which leads to WDSP log stall. This patch fixes the issue by moving opening of channels in workqueue context. CRs-Fixed: 2030858 Change-Id: Ib6153b04cdda80275a94b16842032a19b2a5bb75 Signed-off-by: Mohit Aggarwal --- drivers/char/diag/diagfwd_glink.c | 15 ++++++++++++++- drivers/char/diag/diagfwd_glink.h | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/char/diag/diagfwd_glink.c b/drivers/char/diag/diagfwd_glink.c index 2784cf71cc2b..03d496c2dd91 100644 --- a/drivers/char/diag/diagfwd_glink.c +++ b/drivers/char/diag/diagfwd_glink.c @@ -487,6 +487,18 @@ static void diag_glink_remote_disconnect_work_fn(struct work_struct *work) atomic_set(&glink_info->tx_intent_ready, 0); } +static void diag_glink_late_init_work_fn(struct work_struct *work) +{ + struct diag_glink_info *glink_info = container_of(work, + struct diag_glink_info, + late_init_work); + if (!glink_info || !glink_info->hdl) + return; + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "p: %d t: %d\n", + glink_info->peripheral, glink_info->type); + diagfwd_channel_open(glink_info->fwd_ctxt); +} + static void diag_glink_transport_notify_state(void *handle, const void *priv, unsigned event) { @@ -617,7 +629,7 @@ static void glink_late_init(struct diag_glink_info *glink_info) glink_info->inited = 1; if (atomic_read(&glink_info->opened)) - diagfwd_channel_open(glink_info->fwd_ctxt); + queue_work(glink_info->wq, &(glink_info->late_init_work)); DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s exiting\n", glink_info->name); @@ -665,6 +677,7 @@ static void __diag_glink_init(struct diag_glink_info *glink_info) INIT_WORK(&(glink_info->connect_work), diag_glink_connect_work_fn); INIT_WORK(&(glink_info->remote_disconnect_work), diag_glink_remote_disconnect_work_fn); + INIT_WORK(&(glink_info->late_init_work), diag_glink_late_init_work_fn); link_info.glink_link_state_notif_cb = diag_glink_notify_cb; link_info.transport = NULL; link_info.edge = glink_info->edge; diff --git a/drivers/char/diag/diagfwd_glink.h b/drivers/char/diag/diagfwd_glink.h index 5c1abeffd498..a84fa4edfca0 100644 --- a/drivers/char/diag/diagfwd_glink.h +++ b/drivers/char/diag/diagfwd_glink.h @@ -37,6 +37,7 @@ struct diag_glink_info { struct work_struct read_work; struct work_struct connect_work; struct work_struct remote_disconnect_work; + struct work_struct late_init_work; struct diagfwd_info *fwd_ctxt; };