Loading include/soc/swr-wcd.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2015, 2017-2019 The Linux Foundation. All rights reserved. */ #ifndef _LINUX_SWR_WCD_H Loading @@ -21,6 +21,7 @@ enum { SWR_DEVICE_SSR_UP, SWR_REGISTER_WAKE_IRQ, SWR_SET_PORT_MAP, SWR_REQ_CLK_SWITCH, }; struct swr_mstr_port { Loading soc/swr-mstr-ctrl.c +59 −23 Original line number Diff line number Diff line Loading @@ -1547,13 +1547,15 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) } if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { ret = IRQ_NONE; goto exit; goto err_audio_hw_vote; } swrm_clk_request(swrm, true); mutex_unlock(&swrm->reslock); intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); intr_sts_masked = intr_sts & swrm->intr_mask; dev_dbg(swrm->dev, "%s: status: 0x%x \n", __func__, intr_sts_masked); handle_irq: for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { value = intr_sts_masked & (1 << i); Loading Loading @@ -1724,6 +1726,8 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); err_audio_hw_vote: swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); exit: mutex_unlock(&swrm->reslock); Loading Loading @@ -2230,6 +2234,28 @@ static int swrm_probe(struct platform_device *pdev) for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); /* Register LPASS core hw vote */ lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); if (IS_ERR(lpass_core_hw_vote)) { ret = PTR_ERR(lpass_core_hw_vote); dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", __func__, "lpass_core_hw_vote", ret); lpass_core_hw_vote = NULL; ret = 0; } swrm->lpass_core_hw_vote = lpass_core_hw_vote; /* Register LPASS audio core vote */ lpass_core_audio = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); if (IS_ERR(lpass_core_audio)) { ret = PTR_ERR(lpass_core_audio); dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", __func__, "lpass_core_audio", ret); lpass_core_audio = NULL; ret = 0; } swrm->lpass_core_audio = lpass_core_audio; if (swrm->reg_irq) { ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_REGISTER); Loading Loading @@ -2294,28 +2320,6 @@ static int swrm_probe(struct platform_device *pdev) if (pdev->dev.of_node) of_register_swr_devices(&swrm->master); /* Register LPASS core hw vote */ lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); if (IS_ERR(lpass_core_hw_vote)) { ret = PTR_ERR(lpass_core_hw_vote); dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", __func__, "lpass_core_hw_vote", ret); lpass_core_hw_vote = NULL; ret = 0; } swrm->lpass_core_hw_vote = lpass_core_hw_vote; /* Register LPASS audio core vote */ lpass_core_audio = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); if (IS_ERR(lpass_core_audio)) { ret = PTR_ERR(lpass_core_audio); dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", __func__, "lpass_core_audio", ret); lpass_core_audio = NULL; ret = 0; } swrm->lpass_core_audio = lpass_core_audio; dbgswrm = swrm; debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); if (!IS_ERR(debugfs_swrm_dent)) { Loading Loading @@ -2534,7 +2538,9 @@ static int swrm_runtime_suspend(struct device *dev) goto exit; } if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { mutex_unlock(&swrm->reslock); enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL); mutex_lock(&swrm->reslock); swrm_clk_pause(swrm); swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00); list_for_each_entry(swr_dev, &mstr->devices, dev_list) { Loading Loading @@ -2585,6 +2591,25 @@ static int swrm_runtime_suspend(struct device *dev) } #endif /* CONFIG_PM */ static int swrm_device_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { ret = swrm_runtime_suspend(dev); if (!ret) { pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_enable(dev); } } return 0; } static int swrm_device_down(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); Loading Loading @@ -2721,6 +2746,17 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mstr = &swrm->master; switch (id) { case SWR_REQ_CLK_SWITCH: /* This will put soundwire in clock stop mode and disable the * clocks, if there is no active usecase running, so that the * next activity on soundwire will request clock from new clock * source. */ mutex_lock(&swrm->mlock); if (swrm->state == SWR_MSTR_UP) swrm_device_suspend(&pdev->dev); mutex_unlock(&swrm->mlock); break; case SWR_CLK_FREQ: if (!data) { dev_err(swrm->dev, "%s: data is NULL\n", __func__); Loading Loading
include/soc/swr-wcd.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2015, 2017-2019 The Linux Foundation. All rights reserved. */ #ifndef _LINUX_SWR_WCD_H Loading @@ -21,6 +21,7 @@ enum { SWR_DEVICE_SSR_UP, SWR_REGISTER_WAKE_IRQ, SWR_SET_PORT_MAP, SWR_REQ_CLK_SWITCH, }; struct swr_mstr_port { Loading
soc/swr-mstr-ctrl.c +59 −23 Original line number Diff line number Diff line Loading @@ -1547,13 +1547,15 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) } if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { ret = IRQ_NONE; goto exit; goto err_audio_hw_vote; } swrm_clk_request(swrm, true); mutex_unlock(&swrm->reslock); intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); intr_sts_masked = intr_sts & swrm->intr_mask; dev_dbg(swrm->dev, "%s: status: 0x%x \n", __func__, intr_sts_masked); handle_irq: for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { value = intr_sts_masked & (1 << i); Loading Loading @@ -1724,6 +1726,8 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); err_audio_hw_vote: swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); exit: mutex_unlock(&swrm->reslock); Loading Loading @@ -2230,6 +2234,28 @@ static int swrm_probe(struct platform_device *pdev) for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); /* Register LPASS core hw vote */ lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); if (IS_ERR(lpass_core_hw_vote)) { ret = PTR_ERR(lpass_core_hw_vote); dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", __func__, "lpass_core_hw_vote", ret); lpass_core_hw_vote = NULL; ret = 0; } swrm->lpass_core_hw_vote = lpass_core_hw_vote; /* Register LPASS audio core vote */ lpass_core_audio = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); if (IS_ERR(lpass_core_audio)) { ret = PTR_ERR(lpass_core_audio); dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", __func__, "lpass_core_audio", ret); lpass_core_audio = NULL; ret = 0; } swrm->lpass_core_audio = lpass_core_audio; if (swrm->reg_irq) { ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_REGISTER); Loading Loading @@ -2294,28 +2320,6 @@ static int swrm_probe(struct platform_device *pdev) if (pdev->dev.of_node) of_register_swr_devices(&swrm->master); /* Register LPASS core hw vote */ lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); if (IS_ERR(lpass_core_hw_vote)) { ret = PTR_ERR(lpass_core_hw_vote); dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", __func__, "lpass_core_hw_vote", ret); lpass_core_hw_vote = NULL; ret = 0; } swrm->lpass_core_hw_vote = lpass_core_hw_vote; /* Register LPASS audio core vote */ lpass_core_audio = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); if (IS_ERR(lpass_core_audio)) { ret = PTR_ERR(lpass_core_audio); dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", __func__, "lpass_core_audio", ret); lpass_core_audio = NULL; ret = 0; } swrm->lpass_core_audio = lpass_core_audio; dbgswrm = swrm; debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); if (!IS_ERR(debugfs_swrm_dent)) { Loading Loading @@ -2534,7 +2538,9 @@ static int swrm_runtime_suspend(struct device *dev) goto exit; } if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { mutex_unlock(&swrm->reslock); enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL); mutex_lock(&swrm->reslock); swrm_clk_pause(swrm); swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00); list_for_each_entry(swr_dev, &mstr->devices, dev_list) { Loading Loading @@ -2585,6 +2591,25 @@ static int swrm_runtime_suspend(struct device *dev) } #endif /* CONFIG_PM */ static int swrm_device_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { ret = swrm_runtime_suspend(dev); if (!ret) { pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_enable(dev); } } return 0; } static int swrm_device_down(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); Loading Loading @@ -2721,6 +2746,17 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mstr = &swrm->master; switch (id) { case SWR_REQ_CLK_SWITCH: /* This will put soundwire in clock stop mode and disable the * clocks, if there is no active usecase running, so that the * next activity on soundwire will request clock from new clock * source. */ mutex_lock(&swrm->mlock); if (swrm->state == SWR_MSTR_UP) swrm_device_suspend(&pdev->dev); mutex_unlock(&swrm->mlock); break; case SWR_CLK_FREQ: if (!data) { dev_err(swrm->dev, "%s: data is NULL\n", __func__); Loading