Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 186f5c0e authored by Sagar Dharia's avatar Sagar Dharia Committed by Naveen Kaje
Browse files

slim_ngd: notify slaves in some MDM restart scenarios



If MDM restarts when it had active framer, bus may lose sync.
Send device-down notification if that happens, and corresponding
reset-device and device-up notifications to slaves so that they
can act to restore their devices' communication over slimbus

CRs-Fixed: 612775
Change-Id: I83f22b9bcf18912c7c9507ea099691ed71d86a9f
Signed-off-by: default avatarSagar Dharia <sdharia@codeaurora.org>
Signed-off-by: default avatarNaveen Kaje <nkaje@codeaurora.org>
parent 72bd72cf
Loading
Loading
Loading
Loading
+50 −34
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ enum ngd_status {
};

static int ngd_slim_runtime_resume(struct device *device);
static int ngd_slim_power_up(struct msm_slim_ctrl *dev);
static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart);

static irqreturn_t ngd_slim_interrupt(int irq, void *d)
{
@@ -183,32 +183,45 @@ static int ngd_qmi_available(struct notifier_block *n, unsigned long code,
static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code,
				void *_cmd)
{
	void __iomem *ngd;
	struct msm_slim_mdm *mdm = container_of(n, struct msm_slim_mdm, nb);
	struct msm_slim_ctrl *dev = container_of(mdm, struct msm_slim_ctrl,
						mdm);
	int ret;
	struct slim_controller *ctrl = &dev->ctrl;
	u32 laddr;
	struct slim_device *sbdev;

	switch (code) {
	case SUBSYS_BEFORE_SHUTDOWN:
		/* make sure runtime-pm doesn't suspend during modem SSR */
		pm_runtime_get_noresume(dev->dev);
		break;
	case SUBSYS_AFTER_POWERUP:
		ret = msm_slim_qmi_check_framer_request(dev);
		dev_err(dev->dev,
			"%s:SLIM %lu external_modem SSR notify cb, ret %d",
			__func__, code, ret);
			"SLIM %lu external_modem SSR notify cb", code);
		/* vote for runtime-pm so that ADSP doesn't go down */
		pm_runtime_get_sync(dev->dev);
		/*
		 * Next codec transaction will reinit the HW
		 * if it was suspended
		 * checking framer here will wake-up ADSP and may avoid framer
		 * handover later
		 */
		if (pm_runtime_suspended(dev->dev) ||
			dev->state >= MSM_CTRL_ASLEEP) {
		msm_slim_qmi_check_framer_request(dev);
		dev->mdm.state = MSM_CTRL_DOWN;
		break;
		} else {
			ngd_slim_power_up(dev);
			msm_slim_put_ctrl(dev);
	case SUBSYS_AFTER_POWERUP:
		if (dev->mdm.state != MSM_CTRL_DOWN)
			return NOTIFY_DONE;
		dev_err(dev->dev,
			"SLIM %lu external_modem SSR notify cb", code);
		msm_slim_qmi_check_framer_request(dev);
		/* If NGD enumeration is lost, we will need to power us up */
		ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
		laddr = readl_relaxed(ngd + NGD_STATUS);
		if (!(laddr & NGD_LADDR)) {
			pr_err("SLIM MDM SSR (active framer on MDM) dev-down");
			list_for_each_entry(sbdev, &ctrl->devs, dev_list)
				slim_report_absent(sbdev);
		}
		ngd_slim_power_up(dev, true);
		msm_slim_put_ctrl(dev);
		dev->mdm.state = MSM_CTRL_AWAKE;
		break;
	default:
		break;
	}
@@ -916,7 +929,7 @@ capability_retry:
	}
}

static int ngd_slim_power_up(struct msm_slim_ctrl *dev)
static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart)
{
	void __iomem *ngd;
	int timeout, ret = 0;
@@ -927,7 +940,7 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev)
			NGD_INT_IE_VE_CHG | NGD_INT_DEV_ERR |
			NGD_INT_TX_MSG_SENT | NGD_INT_RX_MSG_RCVD);

	if (cur_state == MSM_CTRL_DOWN) {
	if (!mdm_restart && cur_state == MSM_CTRL_DOWN) {
		int timeout = wait_for_completion_timeout(&dev->qmi.qmi_comp,
						HZ);
		if (!timeout)
@@ -935,7 +948,8 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev)
	}

	/* No need to vote if contorller is not in low power mode */
	if (cur_state == MSM_CTRL_DOWN || cur_state == MSM_CTRL_ASLEEP) {
	if (!mdm_restart &&
		(cur_state == MSM_CTRL_DOWN || cur_state == MSM_CTRL_ASLEEP)) {
		ret = msm_slim_qmi_power_request(dev, true);
		if (ret) {
			pr_err("SLIM QMI power request failed:%d", ret);
@@ -955,7 +969,7 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev)
		 * For example, modem restarted when playback was active
		 */
		if (cur_state == MSM_CTRL_AWAKE) {
			pr_err("SLIM MDM restart: ADSP active framer:NO OP");
			pr_err("Subsys restart: ADSP active framer");
			return 0;
		}
		/*
@@ -964,24 +978,26 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev)
		 */
		ngd_slim_setup_msg_path(dev);
		return 0;
	} else if (cur_state == MSM_CTRL_ASLEEP) {
		pr_debug("ADSP P.C. CTRL state:%d NGD not enumerated:0x%x",
					dev->state, laddr);
	} else if (cur_state == MSM_CTRL_IDLE || cur_state == MSM_CTRL_AWAKE) {
	}

	if (mdm_restart) {
		/*
		 * external MDM SSR when only voice call is in progress.
		 * external MDM SSR when MDM is active framer
		 * ADSP will reset slimbus HW. disconnect BAM pipes so that
		 * they can be connected after capability message is received.
		 * Set device state to ASLEEP to be synchronous with the HW
		 */
		/* make current state as DOWN */
		cur_state = MSM_CTRL_DOWN;
		pr_err("SLIM MDM restart: MDM active framer: reinit HW");
		dev->state = MSM_CTRL_ASLEEP;
		msm_slim_disconnect_endp(dev, &dev->rx_msgq,
					&dev->use_rx_msgqs);
		msm_slim_disconnect_endp(dev, &dev->tx_msgq,
					&dev->use_tx_msgqs);
		/* disconnect BAM pipes */
		if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
			dev->use_rx_msgqs = MSM_MSGQ_DOWN;
		if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
			dev->use_tx_msgqs = MSM_MSGQ_DOWN;
		dev->state = MSM_CTRL_DOWN;
	}
	/* ADSP SSR scenario, need to disconnect pipe before connecting */
	/* SSR scenario, need to disconnect pipe before connecting */
	if (dev->use_rx_msgqs == MSM_MSGQ_DOWN) {
		struct msm_slim_endp *endpoint = &dev->rx_msgq;
		sps_disconnect(endpoint->sps);
@@ -1038,7 +1054,7 @@ static int ngd_slim_enable(struct msm_slim_ctrl *dev, bool enable)
			 * framework state
			 */
			if (ret)
				ngd_slim_power_up(dev);
				ngd_slim_power_up(dev, false);
			if (!pm_runtime_enabled(dev->dev) ||
					!pm_runtime_suspended(dev->dev))
				ngd_slim_runtime_resume(dev->dev);
@@ -1059,7 +1075,7 @@ static int ngd_slim_enable(struct msm_slim_ctrl *dev, bool enable)
static int ngd_clk_pause_wakeup(struct slim_controller *ctrl)
{
	struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
	return ngd_slim_power_up(dev);
	return ngd_slim_power_up(dev, false);
}

static int ngd_slim_rx_msgq_thread(void *data)
+1 −0
Original line number Diff line number Diff line
@@ -216,6 +216,7 @@ struct msm_slim_qmi {
struct msm_slim_mdm {
	struct notifier_block nb;
	void *ssr;
	enum msm_ctrl_state state;
};

struct msm_slim_pdata {