soc: soundwire: use pm runtime function to tear down soundwire master
Use pm_runtime_put_sync_suspend to tear down soundwire master. It makes sure the process is synced with the autosuspend call flow. Change-Id: Ib4feccd905bcbf046e58bd5eaffde40ee391feda Signed-off-by: Xiaojun Sang <xsang@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
d6a2b8187f
commit
f7dd63a169
@@ -1481,6 +1481,7 @@ static int swrm_probe(struct platform_device *pdev)
|
|||||||
mutex_init(&swrm->mlock);
|
mutex_init(&swrm->mlock);
|
||||||
INIT_LIST_HEAD(&swrm->mport_list);
|
INIT_LIST_HEAD(&swrm->mport_list);
|
||||||
mutex_init(&swrm->reslock);
|
mutex_init(&swrm->reslock);
|
||||||
|
mutex_init(&swrm->force_down_lock);
|
||||||
|
|
||||||
ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev",
|
ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev",
|
||||||
&swrm->num_dev);
|
&swrm->num_dev);
|
||||||
@@ -1557,6 +1558,9 @@ err_mstr_fail:
|
|||||||
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
|
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
|
||||||
swrm, SWR_IRQ_FREE);
|
swrm, SWR_IRQ_FREE);
|
||||||
err_irq_fail:
|
err_irq_fail:
|
||||||
|
mutex_destroy(&swrm->mlock);
|
||||||
|
mutex_destroy(&swrm->reslock);
|
||||||
|
mutex_destroy(&swrm->force_down_lock);
|
||||||
err_pdata_fail:
|
err_pdata_fail:
|
||||||
kfree(swrm);
|
kfree(swrm);
|
||||||
err_memory_fail:
|
err_memory_fail:
|
||||||
@@ -1581,6 +1585,7 @@ static int swrm_remove(struct platform_device *pdev)
|
|||||||
swr_unregister_master(&swrm->master);
|
swr_unregister_master(&swrm->master);
|
||||||
mutex_destroy(&swrm->mlock);
|
mutex_destroy(&swrm->mlock);
|
||||||
mutex_destroy(&swrm->reslock);
|
mutex_destroy(&swrm->reslock);
|
||||||
|
mutex_destroy(&swrm->force_down_lock);
|
||||||
kfree(swrm);
|
kfree(swrm);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1644,13 +1649,20 @@ static int swrm_runtime_suspend(struct device *dev)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct swr_master *mstr = &swrm->master;
|
struct swr_master *mstr = &swrm->master;
|
||||||
struct swr_device *swr_dev;
|
struct swr_device *swr_dev;
|
||||||
|
int current_state = 0;
|
||||||
|
|
||||||
dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n",
|
dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n",
|
||||||
__func__, swrm->state);
|
__func__, swrm->state);
|
||||||
mutex_lock(&swrm->reslock);
|
mutex_lock(&swrm->reslock);
|
||||||
if ((swrm->state == SWR_MSTR_RESUME) ||
|
mutex_lock(&swrm->force_down_lock);
|
||||||
(swrm->state == SWR_MSTR_UP)) {
|
current_state = swrm->state;
|
||||||
if (swrm_is_port_en(&swrm->master)) {
|
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__);
|
dev_dbg(dev, "%s ports are enabled\n", __func__);
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto exit;
|
goto exit;
|
||||||
@@ -1679,27 +1691,16 @@ static int swrm_device_down(struct device *dev)
|
|||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
|
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
|
||||||
int ret = 0;
|
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);
|
dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state);
|
||||||
mutex_lock(&swrm->reslock);
|
|
||||||
if ((swrm->state == SWR_MSTR_RESUME) ||
|
mutex_lock(&swrm->force_down_lock);
|
||||||
(swrm->state == SWR_MSTR_UP)) {
|
swrm->state = SWR_MSTR_SSR;
|
||||||
list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
|
mutex_unlock(&swrm->force_down_lock);
|
||||||
ret = swr_device_down(swr_dev);
|
/* Use pm runtime function to tear down */
|
||||||
if (ret)
|
ret = pm_runtime_put_sync_suspend(dev);
|
||||||
dev_err(dev,
|
pm_runtime_get_noresume(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);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,6 +34,7 @@ enum {
|
|||||||
SWR_MSTR_RESUME,
|
SWR_MSTR_RESUME,
|
||||||
SWR_MSTR_UP,
|
SWR_MSTR_UP,
|
||||||
SWR_MSTR_DOWN,
|
SWR_MSTR_DOWN,
|
||||||
|
SWR_MSTR_SSR,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -105,6 +106,8 @@ struct swr_mstr_ctrl {
|
|||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
int num_rx_chs;
|
int num_rx_chs;
|
||||||
u8 num_cfg_devs;
|
u8 num_cfg_devs;
|
||||||
|
struct mutex force_down_lock;
|
||||||
|
int force_down_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _SWR_WCD_CTRL_H */
|
#endif /* _SWR_WCD_CTRL_H */
|
||||||
|
Reference in New Issue
Block a user