Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/pinctrl/qcom/pinctrl-sm8650-lpass-lpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ static const struct of_device_id lpi_pinctrl_of_match[] = {
MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match);

static const struct dev_pm_ops lpi_pinctrl_pm_ops = {
SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
};

Expand Down
50 changes: 46 additions & 4 deletions drivers/soundwire/qcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -1929,10 +1929,12 @@ static int qcom_swrm_setup_lane_provider(struct qcom_swrm_ctrl *ctrl)
/*
* Hold a link to the provider: this controller dereferences it on every
* bank switch and on every DPn access for a borrowed lane, so it must
* not be unbound first.
* not be unbound first. Keep its hclk active while the consumer is,
* and resume it now before probe programs the provider's registers.
*/
ret = device_link_add(ctrl->dev, &pdev->dev,
DL_FLAG_AUTOREMOVE_CONSUMER) ? 0 : -EINVAL;
DL_FLAG_AUTOREMOVE_CONSUMER | DL_FLAG_PM_RUNTIME |
DL_FLAG_RPM_ACTIVE) ? 0 : -EINVAL;
put_device(&pdev->dev);
if (ret)
return dev_err_probe(ctrl->dev, ret,
Expand Down Expand Up @@ -2093,6 +2095,9 @@ static int qcom_swrm_probe(struct platform_device *pdev)
* touch the uninitialised sdw_bus. The consumer starts the
* frame generator once MM_SYNC ties the two together.
*/
/* runtime PM is driven by the consumer through the device link */
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
ctrl->lane_provider_ready = true;

dev_dbg(dev, "Qualcomm SoundWire lane provider v%x.%x.%x registered\n",
Expand Down Expand Up @@ -2220,8 +2225,31 @@ static void qcom_swrm_remove(struct platform_device *pdev)
{
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(&pdev->dev);

if (!ctrl->is_lane_provider)
sdw_bus_master_delete(&ctrl->bus);
if (ctrl->is_lane_provider) {
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
clk_disable_unprepare(ctrl->hclk);
return;
}

/* delete bus before dropping lane_provider; in-flight ops deref it */
sdw_bus_master_delete(&ctrl->bus);

if (ctrl->lane_provider) {
struct qcom_swrm_ctrl *provider = ctrl->lane_provider;

/* provider hclk may be gated by runtime PM */
if (pm_runtime_resume_and_get(provider->dev) >= 0) {
provider->reg_write(provider,
provider->reg_layout[SWRM_REG_INTERRUPT_CPU_EN], 0);
/* disable provider SWRM; releases shared SWR_CLK */
provider->reg_write(provider, SWRM_COMP_CFG_ADDR, 0);
pm_runtime_put(provider->dev);
}
provider->lane_consumer = NULL;
ctrl->lane_provider = NULL;
}

clk_disable_unprepare(ctrl->hclk);
}

Expand All @@ -2230,6 +2258,10 @@ static int __maybe_unused swrm_runtime_resume(struct device *dev)
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dev);
int ret;

/* no bus of its own; the consumer restarts the link */
if (ctrl->is_lane_provider)
return clk_prepare_enable(ctrl->hclk);

if (ctrl->wake_irq > 0) {
if (!irqd_irq_disabled(irq_get_irq_data(ctrl->wake_irq)))
disable_irq_nosync(ctrl->wake_irq);
Expand Down Expand Up @@ -2257,6 +2289,9 @@ static int __maybe_unused swrm_runtime_resume(struct device *dev)
reset_control_reset(ctrl->audio_cgcr);

qcom_swrm_program_mm_sync(ctrl);
/* provider was resumed first via the device link */
if (ctrl->lane_provider)
qcom_swrm_program_mm_sync(ctrl->lane_provider);

if (ctrl->version == SWRM_VERSION_1_7_0) {
ctrl->reg_write(ctrl, SWRM_LINK_MANAGER_EE, ctrl->ee);
Expand Down Expand Up @@ -2300,6 +2335,12 @@ static int __maybe_unused swrm_runtime_suspend(struct device *dev)
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dev);
int ret;

/* the consumer has already stopped the bus clock */
if (ctrl->is_lane_provider) {
clk_disable_unprepare(ctrl->hclk);
return 0;
}

swrm_wait_for_wr_fifo_done(ctrl);
if (!ctrl->clock_stop_not_supported) {
/* Mask bus clash interrupt */
Expand Down Expand Up @@ -2337,6 +2378,7 @@ static int __maybe_unused swrm_runtime_suspend(struct device *dev)
}

static const struct dev_pm_ops swrm_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
SET_RUNTIME_PM_OPS(swrm_runtime_suspend, swrm_runtime_resume, NULL)
};

Expand Down
18 changes: 11 additions & 7 deletions sound/soc/codecs/lpass-rx-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -3797,7 +3797,6 @@ static int rx_macro_register_mclk_output(struct rx_macro *rx)
const char *clk_name = "lpass-rx-mclk";
struct clk_hw *hw;
struct clk_init_data init;
int ret;

if (rx->npl)
parent_clk_name = __clk_get_name(rx->npl);
Expand All @@ -3811,11 +3810,7 @@ static int rx_macro_register_mclk_output(struct rx_macro *rx)
init.num_parents = 1;
rx->hw.init = &init;
hw = &rx->hw;
ret = devm_clk_hw_register(rx->dev, hw);
if (ret)
return ret;

return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
return devm_clk_hw_register(dev, hw);
}

static const struct snd_soc_component_driver rx_macro_component_drv = {
Expand Down Expand Up @@ -3946,6 +3941,15 @@ static int rx_macro_probe(struct platform_device *pdev)
if (ret)
return ret;

/*
* Register before enabling runtime PM so the clk core doesn't wake
* the macro on every clk_summary read. The gate takes runtime PM in
* prepare and is_enabled reads a cached register.
*/
ret = rx_macro_register_mclk_output(rx);
if (ret)
return ret;

pm_runtime_set_autosuspend_delay(dev, 100);
pm_runtime_use_autosuspend(dev);
ret = devm_pm_runtime_enable(dev);
Expand Down Expand Up @@ -3973,7 +3977,7 @@ static int rx_macro_probe(struct platform_device *pdev)
if (ret)
goto err_rpm_put;

ret = rx_macro_register_mclk_output(rx);
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &rx->hw);
if (ret)
goto err_rpm_put;

Expand Down
18 changes: 11 additions & 7 deletions sound/soc/codecs/lpass-tx-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -2685,7 +2685,6 @@ static int tx_macro_register_mclk_output(struct tx_macro *tx)
const char *clk_name = "lpass-tx-mclk";
struct clk_hw *hw;
struct clk_init_data init;
int ret;

if (tx->npl)
parent_clk_name = __clk_get_name(tx->npl);
Expand All @@ -2699,11 +2698,7 @@ static int tx_macro_register_mclk_output(struct tx_macro *tx)
init.num_parents = 1;
tx->hw.init = &init;
hw = &tx->hw;
ret = devm_clk_hw_register(dev, hw);
if (ret)
return ret;

return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
return devm_clk_hw_register(dev, hw);
}

static const struct snd_soc_component_driver tx_macro_component_drv = {
Expand Down Expand Up @@ -2801,6 +2796,15 @@ static int tx_macro_probe(struct platform_device *pdev)
if (ret)
goto err;

/*
* Register before enabling runtime PM so the clk core doesn't wake
* the macro on every clk_summary read. The gate takes runtime PM in
* prepare and is_enabled reads a cached register.
*/
ret = tx_macro_register_mclk_output(tx);
if (ret)
goto err;

pm_runtime_set_autosuspend_delay(dev, 100);
pm_runtime_use_autosuspend(dev);
ret = devm_pm_runtime_enable(dev);
Expand Down Expand Up @@ -2830,7 +2834,7 @@ static int tx_macro_probe(struct platform_device *pdev)
if (ret)
goto err_rpm_put;

ret = tx_macro_register_mclk_output(tx);
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &tx->hw);
if (ret)
goto err_rpm_put;

Expand Down
18 changes: 11 additions & 7 deletions sound/soc/codecs/lpass-va-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -1759,7 +1759,6 @@ static int va_macro_register_fsgen_output(struct va_macro *va)
const char *parent_clk_name;
const char *clk_name = "fsgen";
struct clk_init_data init;
int ret;

if (va->has_npl_clk)
parent = va->npl;
Expand All @@ -1774,11 +1773,7 @@ static int va_macro_register_fsgen_output(struct va_macro *va)
init.parent_names = &parent_clk_name;
init.num_parents = 1;
va->hw.init = &init;
ret = devm_clk_hw_register(va->dev, &va->hw);
if (ret)
return ret;

return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &va->hw);
return devm_clk_hw_register(dev, &va->hw);
}

static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
Expand Down Expand Up @@ -1977,6 +1972,15 @@ static int va_macro_probe(struct platform_device *pdev)
goto err;
}

/*
* Register before enabling runtime PM so the clk core doesn't wake
* the macro on every clk_summary read. The gate takes runtime PM in
* prepare and is_enabled reads a cached register.
*/
ret = va_macro_register_fsgen_output(va);
if (ret)
goto err;

pm_runtime_set_autosuspend_delay(dev, 100);
pm_runtime_use_autosuspend(dev);
ret = devm_pm_runtime_enable(dev);
Expand Down Expand Up @@ -2031,7 +2035,7 @@ static int va_macro_probe(struct platform_device *pdev)
if (ret)
goto err_rpm_put;

ret = va_macro_register_fsgen_output(va);
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &va->hw);
if (ret)
goto err_rpm_put;

Expand Down
18 changes: 11 additions & 7 deletions sound/soc/codecs/lpass-wsa-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -2691,7 +2691,6 @@ static int wsa_macro_register_mclk_output(struct wsa_macro *wsa)
const char *parent_clk_name;
struct clk_hw *hw;
struct clk_init_data init;
int ret;

if (wsa->npl)
parent_clk_name = __clk_get_name(wsa->npl);
Expand All @@ -2707,11 +2706,7 @@ static int wsa_macro_register_mclk_output(struct wsa_macro *wsa)
init.num_parents = 1;
wsa->hw.init = &init;
hw = &wsa->hw;
ret = devm_clk_hw_register(wsa->dev, hw);
if (ret)
return ret;

return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
return devm_clk_hw_register(dev, hw);
}

static const struct snd_soc_component_driver wsa_macro_component_drv = {
Expand Down Expand Up @@ -2832,6 +2827,15 @@ static int wsa_macro_probe(struct platform_device *pdev)
if (ret)
return ret;

/*
* Register before enabling runtime PM so the clk core doesn't wake
* the macro on every clk_summary read. The gate takes runtime PM in
* prepare and is_enabled reads a cached register.
*/
ret = wsa_macro_register_mclk_output(wsa);
if (ret)
return ret;

pm_runtime_set_autosuspend_delay(dev, 100);
pm_runtime_use_autosuspend(dev);
ret = devm_pm_runtime_enable(dev);
Expand Down Expand Up @@ -2859,7 +2863,7 @@ static int wsa_macro_probe(struct platform_device *pdev)
if (ret)
goto err_rpm_put;

ret = wsa_macro_register_mclk_output(wsa);
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &wsa->hw);
if (ret)
goto err_rpm_put;

Expand Down