Loading soc/swr-wcd-ctrl.c +23 −22 Original line number Diff line number Diff line Loading @@ -1481,6 +1481,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->mlock); INIT_LIST_HEAD(&swrm->mport_list); mutex_init(&swrm->reslock); mutex_init(&swrm->force_down_lock); ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev", &swrm->num_dev); Loading Loading @@ -1557,6 +1558,9 @@ static int swrm_probe(struct platform_device *pdev) swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_FREE); err_irq_fail: mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); err_pdata_fail: kfree(swrm); err_memory_fail: Loading @@ -1581,6 +1585,7 @@ static int swrm_remove(struct platform_device *pdev) swr_unregister_master(&swrm->master); mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); kfree(swrm); return 0; } Loading Loading @@ -1644,13 +1649,20 @@ static int swrm_runtime_suspend(struct device *dev) int ret = 0; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; int current_state = 0; dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n", __func__, swrm->state); mutex_lock(&swrm->reslock); if ((swrm->state == SWR_MSTR_RESUME) || (swrm->state == SWR_MSTR_UP)) { if (swrm_is_port_en(&swrm->master)) { mutex_lock(&swrm->force_down_lock); current_state = swrm->state; mutex_unlock(&swrm->force_down_lock); if ((current_state == SWR_MSTR_RESUME) || (current_state == SWR_MSTR_UP) || (current_state == SWR_MSTR_SSR)) { if ((current_state != SWR_MSTR_SSR) && swrm_is_port_en(&swrm->master)) { dev_dbg(dev, "%s ports are enabled\n", __func__); ret = -EBUSY; goto exit; Loading Loading @@ -1679,27 +1691,16 @@ static int swrm_device_down(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); mutex_lock(&swrm->reslock); if ((swrm->state == SWR_MSTR_RESUME) || (swrm->state == SWR_MSTR_UP)) { list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_device_down(swr_dev); if (ret) dev_err(dev, "%s: failed to shutdown swr dev %d\n", __func__, swr_dev->dev_num); } dev_dbg(dev, "%s: Shutting down SWRM\n", __func__); pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_enable(dev); swrm_clk_request(swrm, false); } mutex_unlock(&swrm->reslock); mutex_lock(&swrm->force_down_lock); swrm->state = SWR_MSTR_SSR; mutex_unlock(&swrm->force_down_lock); /* Use pm runtime function to tear down */ ret = pm_runtime_put_sync_suspend(dev); pm_runtime_get_noresume(dev); return ret; } Loading soc/swr-wcd-ctrl.h +3 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ enum { SWR_MSTR_RESUME, SWR_MSTR_UP, SWR_MSTR_DOWN, SWR_MSTR_SSR, }; enum { Loading Loading @@ -105,6 +106,8 @@ struct swr_mstr_ctrl { struct platform_device *pdev; int num_rx_chs; u8 num_cfg_devs; struct mutex force_down_lock; int force_down_state; }; #endif /* _SWR_WCD_CTRL_H */ Loading
soc/swr-wcd-ctrl.c +23 −22 Original line number Diff line number Diff line Loading @@ -1481,6 +1481,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->mlock); INIT_LIST_HEAD(&swrm->mport_list); mutex_init(&swrm->reslock); mutex_init(&swrm->force_down_lock); ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev", &swrm->num_dev); Loading Loading @@ -1557,6 +1558,9 @@ static int swrm_probe(struct platform_device *pdev) swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_FREE); err_irq_fail: mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); err_pdata_fail: kfree(swrm); err_memory_fail: Loading @@ -1581,6 +1585,7 @@ static int swrm_remove(struct platform_device *pdev) swr_unregister_master(&swrm->master); mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); kfree(swrm); return 0; } Loading Loading @@ -1644,13 +1649,20 @@ static int swrm_runtime_suspend(struct device *dev) int ret = 0; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; int current_state = 0; dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n", __func__, swrm->state); mutex_lock(&swrm->reslock); if ((swrm->state == SWR_MSTR_RESUME) || (swrm->state == SWR_MSTR_UP)) { if (swrm_is_port_en(&swrm->master)) { mutex_lock(&swrm->force_down_lock); current_state = swrm->state; mutex_unlock(&swrm->force_down_lock); if ((current_state == SWR_MSTR_RESUME) || (current_state == SWR_MSTR_UP) || (current_state == SWR_MSTR_SSR)) { if ((current_state != SWR_MSTR_SSR) && swrm_is_port_en(&swrm->master)) { dev_dbg(dev, "%s ports are enabled\n", __func__); ret = -EBUSY; goto exit; Loading Loading @@ -1679,27 +1691,16 @@ static int swrm_device_down(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); mutex_lock(&swrm->reslock); if ((swrm->state == SWR_MSTR_RESUME) || (swrm->state == SWR_MSTR_UP)) { list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_device_down(swr_dev); if (ret) dev_err(dev, "%s: failed to shutdown swr dev %d\n", __func__, swr_dev->dev_num); } dev_dbg(dev, "%s: Shutting down SWRM\n", __func__); pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_enable(dev); swrm_clk_request(swrm, false); } mutex_unlock(&swrm->reslock); mutex_lock(&swrm->force_down_lock); swrm->state = SWR_MSTR_SSR; mutex_unlock(&swrm->force_down_lock); /* Use pm runtime function to tear down */ ret = pm_runtime_put_sync_suspend(dev); pm_runtime_get_noresume(dev); return ret; } Loading
soc/swr-wcd-ctrl.h +3 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ enum { SWR_MSTR_RESUME, SWR_MSTR_UP, SWR_MSTR_DOWN, SWR_MSTR_SSR, }; enum { Loading Loading @@ -105,6 +106,8 @@ struct swr_mstr_ctrl { struct platform_device *pdev; int num_rx_chs; u8 num_cfg_devs; struct mutex force_down_lock; int force_down_state; }; #endif /* _SWR_WCD_CTRL_H */