From 390e7c950eec4e486ad36284399af808212196df Mon Sep 17 00:00:00 2001 From: Prudhvi Yarlagadda Date: Thu, 23 Jan 2020 17:17:18 +0530 Subject: [PATCH] slim-msm-ngd: Depend on PIL driver notification instead of qmi Depend on PIL driver subsys up notification instead of qmi notifications for SSR/PDR to avoid race conditions between qmi and PIL notifications. This race condition can happen when qmi connections got killed without an actual SSR/PDR. Change-Id: I3472999057f43bb5eec7b51c114ccf471be35a79 Signed-off-by: Prudhvi Yarlagadda --- drivers/slimbus/slim-msm-ngd.c | 30 +++++++++++++++++++++--------- drivers/slimbus/slim-msm.h | 3 ++- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c index 7eb4bcd68308..e6982560dfb8 100644 --- a/drivers/slimbus/slim-msm-ngd.c +++ b/drivers/slimbus/slim-msm-ngd.c @@ -166,17 +166,10 @@ static int ngd_slim_qmi_new_server(struct qmi_handle *hdl, container_of(qmi, struct msm_slim_ctrl, qmi); SLIM_INFO(dev, "Slimbus QMI new server event received\n"); - /* Hold wake lock until notify slaves thread is done */ - pm_stay_awake(dev->dev); qmi->svc_info.sq_family = AF_QIPCRTR; qmi->svc_info.sq_node = service->node; qmi->svc_info.sq_port = service->port; - if (dev->lpass_mem_usage) { - dev->lpass_mem->start = dev->lpass_phy_base; - dev->lpass.base = dev->lpass_virt_base; - } - atomic_set(&dev->ssr_in_progress, 0); - schedule_work(&dev->dsp.dom_up); + complete(&dev->qmi_up); return 0; } @@ -186,7 +179,10 @@ static void ngd_slim_qmi_del_server(struct qmi_handle *hdl, { struct msm_slim_qmi *qmi = container_of(hdl, struct msm_slim_qmi, svc_event_hdl); + struct msm_slim_ctrl *dev = + container_of(qmi, struct msm_slim_ctrl, qmi); + reinit_completion(&dev->qmi_up); qmi->svc_info.sq_node = 0; qmi->svc_info.sq_port = 0; } @@ -274,6 +270,18 @@ static int dsp_domr_notify_cb(struct notifier_block *n, unsigned long code, ngd_dom_down(dev); mutex_unlock(&dev->tx_lock); break; + case SUBSYS_AFTER_POWERUP: + case SERVREG_NOTIF_SERVICE_STATE_UP_V01: + SLIM_INFO(dev, "SLIM DSP SSR notify cb:%lu\n", code); + /* Hold wake lock until notify slaves thread is done */ + pm_stay_awake(dev->dev); + if (dev->lpass_mem_usage) { + dev->lpass_mem->start = dev->lpass_phy_base; + dev->lpass.base = dev->lpass_virt_base; + } + atomic_set(&dev->ssr_in_progress, 0); + schedule_work(&dev->dsp.dom_up); + break; case LOCATOR_UP: reg = _cmd; if (!reg || reg->total_domains != 1) { @@ -1627,6 +1635,7 @@ static int ngd_notify_slaves(void *data) pm_relax(dev->dev); return ret; } + ngd_dom_init(dev); while (!kthread_should_stop()) { wait_for_completion_interruptible(&dev->qmi.slave_notify); @@ -1642,7 +1651,6 @@ static int ngd_notify_slaves(void *data) * controller is up */ slim_ctrl_add_boarddevs(&dev->ctrl); - ngd_dom_init(dev); } else { slim_framer_booted(ctrl); } @@ -1690,6 +1698,9 @@ static void ngd_dom_up(struct work_struct *work) struct msm_slim_ctrl *dev = container_of(dsp, struct msm_slim_ctrl, dsp); + /* Make sure qmi service is up before continuing */ + wait_for_completion_interruptible(&dev->qmi_up); + mutex_lock(&dev->ssr_lock); ngd_slim_enable(dev, true); mutex_unlock(&dev->ssr_lock); @@ -1959,6 +1970,7 @@ static int ngd_slim_probe(struct platform_device *pdev) init_completion(&dev->reconf); init_completion(&dev->ctrl_up); + init_completion(&dev->qmi_up); mutex_init(&dev->tx_lock); mutex_init(&dev->ssr_lock); spin_lock_init(&dev->tx_buf_lock); diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h index 724dcf40a622..4c17696b74ed 100644 --- a/drivers/slimbus/slim-msm.h +++ b/drivers/slimbus/slim-msm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef _SLIM_MSM_H @@ -326,6 +326,7 @@ struct msm_slim_ctrl { u32 current_rx_buf[10]; int current_count; atomic_t ssr_in_progress; + struct completion qmi_up; }; struct msm_sat_chan {