Skip to content
Closed
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
37 changes: 36 additions & 1 deletion drivers/soundwire/qcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,41 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "bus.h"
#include <linux/delay.h>

/*
* Local helper: bounded retry for deferred clock providers.
* Clock-provider registration does not trigger deferred-probe retries,
* so a consumer that loses the probe-order race stays deferred forever.
* Wait up to 30s for providers that are registered milliseconds later.
*/
static struct clk *clk_get_retry(struct device *dev, const char *id)
{
struct clk *c;
int i;

for (i = 0; i < 60; i++) {
c = devm_clk_get(dev, id);
if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
return c;
msleep(500);
}
return c;
}

static struct clk *clk_get_retry_optional(struct device *dev, const char *id)
{
struct clk *c;
int i;

for (i = 0; i < 60; i++) {
c = devm_clk_get_optional(dev, id);
if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
return c;
msleep(500);
}
return c;
}

#define SWRM_COMP_SW_RESET 0x008
#define SWRM_COMP_STATUS 0x014
Expand Down Expand Up @@ -1669,7 +1704,7 @@ static int qcom_swrm_probe(struct platform_device *pdev)
goto err_init;
}

ctrl->hclk = devm_clk_get(dev, "iface");
ctrl->hclk = clk_get_retry(dev, "iface");
if (IS_ERR(ctrl->hclk)) {
ret = dev_err_probe(dev, PTR_ERR(ctrl->hclk), "unable to get iface clock\n");
goto err_init;
Expand Down
45 changes: 40 additions & 5 deletions sound/soc/codecs/lpass-rx-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,41 @@
#include <linux/clk-provider.h>

#include "lpass-macro-common.h"
#include <linux/delay.h>

/*
* Local helper: bounded retry for deferred clock providers.
* Clock-provider registration does not trigger deferred-probe retries,
* so a consumer that loses the probe-order race stays deferred forever.
* Wait up to 30s for providers that are registered milliseconds later.
*/
static struct clk *clk_get_retry(struct device *dev, const char *id)
{
struct clk *c;
int i;

for (i = 0; i < 60; i++) {
c = devm_clk_get(dev, id);
if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
return c;
msleep(500);
}
return c;
}

static struct clk *clk_get_retry_optional(struct device *dev, const char *id)
{
struct clk *c;
int i;

for (i = 0; i < 60; i++) {
c = devm_clk_get_optional(dev, id);
if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
return c;
msleep(500);
}
return c;
}

#define CDC_RX_TOP_TOP_CFG0 (0x0000)
#define CDC_RX_TOP_SWR_CTRL (0x0008)
Expand Down Expand Up @@ -3780,25 +3815,25 @@ static int rx_macro_probe(struct platform_device *pdev)
if (!rx)
return -ENOMEM;

rx->macro = devm_clk_get_optional(dev, "macro");
rx->macro = clk_get_retry_optional(dev, "macro");
if (IS_ERR(rx->macro))
return dev_err_probe(dev, PTR_ERR(rx->macro), "unable to get macro clock\n");

rx->dcodec = devm_clk_get_optional(dev, "dcodec");
rx->dcodec = clk_get_retry_optional(dev, "dcodec");
if (IS_ERR(rx->dcodec))
return dev_err_probe(dev, PTR_ERR(rx->dcodec), "unable to get dcodec clock\n");

rx->mclk = devm_clk_get(dev, "mclk");
rx->mclk = clk_get_retry(dev, "mclk");
if (IS_ERR(rx->mclk))
return dev_err_probe(dev, PTR_ERR(rx->mclk), "unable to get mclk clock\n");

if (flags & LPASS_MACRO_FLAG_HAS_NPL_CLOCK) {
rx->npl = devm_clk_get(dev, "npl");
rx->npl = clk_get_retry(dev, "npl");
if (IS_ERR(rx->npl))
return dev_err_probe(dev, PTR_ERR(rx->npl), "unable to get npl clock\n");
}

rx->fsgen = devm_clk_get(dev, "fsgen");
rx->fsgen = clk_get_retry(dev, "fsgen");
if (IS_ERR(rx->fsgen))
return dev_err_probe(dev, PTR_ERR(rx->fsgen), "unable to get fsgen clock\n");

Expand Down
45 changes: 40 additions & 5 deletions sound/soc/codecs/lpass-tx-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,41 @@
#include <linux/clk-provider.h>

#include "lpass-macro-common.h"
#include <linux/delay.h>

/*
* Local helper: bounded retry for deferred clock providers.
* Clock-provider registration does not trigger deferred-probe retries,
* so a consumer that loses the probe-order race stays deferred forever.
* Wait up to 30s for providers that are registered milliseconds later.
*/
static struct clk *clk_get_retry(struct device *dev, const char *id)
{
struct clk *c;
int i;

for (i = 0; i < 60; i++) {
c = devm_clk_get(dev, id);
if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
return c;
msleep(500);
}
return c;
}

static struct clk *clk_get_retry_optional(struct device *dev, const char *id)
{
struct clk *c;
int i;

for (i = 0; i < 60; i++) {
c = devm_clk_get_optional(dev, id);
if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
return c;
msleep(500);
}
return c;
}

#define CDC_TX_CLK_RST_CTRL_MCLK_CONTROL (0x0000)
#define CDC_TX_MCLK_EN_MASK BIT(0)
Expand Down Expand Up @@ -2258,25 +2293,25 @@ static int tx_macro_probe(struct platform_device *pdev)

tx->data = device_get_match_data(dev);

tx->macro = devm_clk_get_optional(dev, "macro");
tx->macro = clk_get_retry_optional(dev, "macro");
if (IS_ERR(tx->macro))
return dev_err_probe(dev, PTR_ERR(tx->macro), "unable to get macro clock\n");

tx->dcodec = devm_clk_get_optional(dev, "dcodec");
tx->dcodec = clk_get_retry_optional(dev, "dcodec");
if (IS_ERR(tx->dcodec))
return dev_err_probe(dev, PTR_ERR(tx->dcodec), "unable to get dcodec clock\n");

tx->mclk = devm_clk_get(dev, "mclk");
tx->mclk = clk_get_retry(dev, "mclk");
if (IS_ERR(tx->mclk))
return dev_err_probe(dev, PTR_ERR(tx->mclk), "unable to get mclk clock\n");

if (tx->data->flags & LPASS_MACRO_FLAG_HAS_NPL_CLOCK) {
tx->npl = devm_clk_get(dev, "npl");
tx->npl = clk_get_retry(dev, "npl");
if (IS_ERR(tx->npl))
return dev_err_probe(dev, PTR_ERR(tx->npl), "unable to get npl clock\n");
}

tx->fsgen = devm_clk_get(dev, "fsgen");
tx->fsgen = clk_get_retry(dev, "fsgen");
if (IS_ERR(tx->fsgen))
return dev_err_probe(dev, PTR_ERR(tx->fsgen), "unable to get fsgen clock\n");

Expand Down
43 changes: 39 additions & 4 deletions sound/soc/codecs/lpass-va-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,41 @@
#include <sound/tlv.h>

#include "lpass-macro-common.h"
#include <linux/delay.h>

/*
* Local helper: bounded retry for deferred clock providers.
* Clock-provider registration does not trigger deferred-probe retries,
* so a consumer that loses the probe-order race stays deferred forever.
* Wait up to 30s for providers that are registered milliseconds later.
*/
static struct clk *clk_get_retry(struct device *dev, const char *id)
{
struct clk *c;
int i;

for (i = 0; i < 60; i++) {
c = devm_clk_get(dev, id);
if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
return c;
msleep(500);
}
return c;
}

static struct clk *clk_get_retry_optional(struct device *dev, const char *id)
{
struct clk *c;
int i;

for (i = 0; i < 60; i++) {
c = devm_clk_get_optional(dev, id);
if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
return c;
msleep(500);
}
return c;
}

/* VA macro registers */
#define CDC_VA_CLK_RST_CTRL_MCLK_CONTROL (0x0000)
Expand Down Expand Up @@ -1557,15 +1592,15 @@ static int va_macro_probe(struct platform_device *pdev)

va->dev = dev;

va->macro = devm_clk_get_optional(dev, "macro");
va->macro = clk_get_retry_optional(dev, "macro");
if (IS_ERR(va->macro))
return dev_err_probe(dev, PTR_ERR(va->macro), "unable to get macro clock\n");

va->dcodec = devm_clk_get_optional(dev, "dcodec");
va->dcodec = clk_get_retry_optional(dev, "dcodec");
if (IS_ERR(va->dcodec))
return dev_err_probe(dev, PTR_ERR(va->dcodec), "unable to get dcodec clock\n");

va->mclk = devm_clk_get(dev, "mclk");
va->mclk = clk_get_retry(dev, "mclk");
if (IS_ERR(va->mclk))
return dev_err_probe(dev, PTR_ERR(va->mclk), "unable to get mclk clock\n");

Expand Down Expand Up @@ -1610,7 +1645,7 @@ static int va_macro_probe(struct platform_device *pdev)
goto err;

if (va->has_npl_clk) {
va->npl = devm_clk_get(dev, "npl");
va->npl = clk_get_retry(dev, "npl");
if (IS_ERR(va->npl)) {
ret = PTR_ERR(va->npl);
goto err;
Expand Down
45 changes: 40 additions & 5 deletions sound/soc/codecs/lpass-wsa-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,41 @@

#include "lpass-macro-common.h"
#include "lpass-wsa-macro.h"
#include <linux/delay.h>

/*
* Local helper: bounded retry for deferred clock providers.
* Clock-provider registration does not trigger deferred-probe retries,
* so a consumer that loses the probe-order race stays deferred forever.
* Wait up to 30s for providers that are registered milliseconds later.
*/
static struct clk *clk_get_retry(struct device *dev, const char *id)
{
struct clk *c;
int i;

for (i = 0; i < 60; i++) {
c = devm_clk_get(dev, id);
if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
return c;
msleep(500);
}
return c;
}

static struct clk *clk_get_retry_optional(struct device *dev, const char *id)
{
struct clk *c;
int i;

for (i = 0; i < 60; i++) {
c = devm_clk_get_optional(dev, id);
if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
return c;
msleep(500);
}
return c;
}

#define CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL (0x0000)
#define CDC_WSA_MCLK_EN_MASK BIT(0)
Expand Down Expand Up @@ -2701,25 +2736,25 @@ static int wsa_macro_probe(struct platform_device *pdev)
if (!wsa)
return -ENOMEM;

wsa->macro = devm_clk_get_optional(dev, "macro");
wsa->macro = clk_get_retry_optional(dev, "macro");
if (IS_ERR(wsa->macro))
return dev_err_probe(dev, PTR_ERR(wsa->macro), "unable to get macro clock\n");

wsa->dcodec = devm_clk_get_optional(dev, "dcodec");
wsa->dcodec = clk_get_retry_optional(dev, "dcodec");
if (IS_ERR(wsa->dcodec))
return dev_err_probe(dev, PTR_ERR(wsa->dcodec), "unable to get dcodec clock\n");

wsa->mclk = devm_clk_get(dev, "mclk");
wsa->mclk = clk_get_retry(dev, "mclk");
if (IS_ERR(wsa->mclk))
return dev_err_probe(dev, PTR_ERR(wsa->mclk), "unable to get mclk clock\n");

if (flags & LPASS_MACRO_FLAG_HAS_NPL_CLOCK) {
wsa->npl = devm_clk_get(dev, "npl");
wsa->npl = clk_get_retry(dev, "npl");
if (IS_ERR(wsa->npl))
return dev_err_probe(dev, PTR_ERR(wsa->npl), "unable to get npl clock\n");
}

wsa->fsgen = devm_clk_get(dev, "fsgen");
wsa->fsgen = clk_get_retry(dev, "fsgen");
if (IS_ERR(wsa->fsgen))
return dev_err_probe(dev, PTR_ERR(wsa->fsgen), "unable to get fsgen clock\n");

Expand Down