Loading drivers/slimbus/slim-msm-ngd.c +50 −34 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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) Loading @@ -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); Loading @@ -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; } /* Loading @@ -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); Loading Loading @@ -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); Loading @@ -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) Loading drivers/slimbus/slim-msm.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading
drivers/slimbus/slim-msm-ngd.c +50 −34 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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) Loading @@ -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); Loading @@ -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; } /* Loading @@ -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); Loading Loading @@ -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); Loading @@ -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) Loading
drivers/slimbus/slim-msm.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading