Re: [PATCH v3 3/8] wifi: ath10k: snoc: support powering on the device via pwrseq
"Luca Weiss" <[email protected]> Thu, 16 Apr 2026 12:06:09 +0200
| Newsgroups | org.infradead.lists.ath10k,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-bluetooth,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm,org.kernel.vger.linux-wireless |
|---|---|
| Message-ID | <[email protected]> |
Hi Dmitry, On Mon Jan 19, 2026 at 6:07 PM CET, Dmitry Baryshkov wrote: > The WCN39xx family of WiFi/BT chips incorporates a simple PMU, spreading > voltages over internal rails. Implement support for using powersequencer > for this family of ATH10k devices in addition to using regulators. > > Reviewed-by: Bartosz Golaszewski <[email protected]> > Signed-off-by: Dmitry Baryshkov <[email protected]> > --- > drivers/net/wireless/ath/ath10k/snoc.c | 53 ++++++++++++++++++++++++++++++++-- > drivers/net/wireless/ath/ath10k/snoc.h | 3 ++ > 2 files changed, 53 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c > index b3f6424c17d3..f72f236fb9eb 100644 > --- a/drivers/net/wireless/ath/ath10k/snoc.c > +++ b/drivers/net/wireless/ath/ath10k/snoc.c > @@ -1,6 +1,7 @@ > // SPDX-License-Identifier: ISC > /* > * Copyright (c) 2018 The Linux Foundation. All rights reserved. > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. > */ > > #include <linux/bits.h> > @@ -11,6 +12,7 @@ > #include <linux/of_device.h> > #include <linux/platform_device.h> > #include <linux/property.h> > +#include <linux/pwrseq/consumer.h> > #include <linux/regulator/consumer.h> > #include <linux/remoteproc/qcom_rproc.h> > #include <linux/of_reserved_mem.h> > @@ -1023,10 +1025,14 @@ static int ath10k_hw_power_on(struct ath10k *ar) > > ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power on\n"); > > - ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs); > + ret = pwrseq_power_on(ar_snoc->pwrseq); > if (ret) > return ret; > > + ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs); > + if (ret) > + goto pwrseq_off; > + > ret = clk_bulk_prepare_enable(ar_snoc->num_clks, ar_snoc->clks); > if (ret) > goto vreg_off; > @@ -1035,18 +1041,28 @@ static int ath10k_hw_power_on(struct ath10k *ar) > > vreg_off: > regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); > +pwrseq_off: > + pwrseq_power_off(ar_snoc->pwrseq); > + > return ret; > } > > static int ath10k_hw_power_off(struct ath10k *ar) > { > struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); > + int ret_seq = 0; > + int ret_vreg; > > ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power off\n"); > > clk_bulk_disable_unprepare(ar_snoc->num_clks, ar_snoc->clks); > > - return regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); > + ret_vreg = regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); > + > + if (ar_snoc->pwrseq) > + ret_seq = pwrseq_power_off(ar_snoc->pwrseq); > + > + return ret_vreg ? : ret_seq; > } > > static void ath10k_snoc_wlan_disable(struct ath10k *ar) > @@ -1762,7 +1778,38 @@ static int ath10k_snoc_probe(struct platform_device *pdev) > goto err_release_resource; > } > > - ar_snoc->num_vregs = ARRAY_SIZE(ath10k_regulators); > + /* > + * devm_pwrseq_get() can return -EPROBE_DEFER in two cases: > + * - it is not supposed to be used > + * - it is supposed to be used, but the driver hasn't probed yet. > + * > + * There is no simple way to distinguish between these two cases, but: > + * - if it is not supposed to be used, then regulator_bulk_get() will > + * return all regulators as expected, continuing the probe > + * - if it is supposed to be used, but wasn't probed yet, we will get > + * -EPROBE_DEFER from regulator_bulk_get() too. > + * > + * For backwards compatibility with DTs specifying regulators directly > + * rather than using the PMU device, ignore the defer error from > + * pwrseq. > + */ > + ar_snoc->pwrseq = devm_pwrseq_get(&pdev->dev, "wlan"); > + if (IS_ERR(ar_snoc->pwrseq)) { > + ret = PTR_ERR(ar_snoc->pwrseq); > + ar_snoc->pwrseq = NULL; > + if (ret != -EPROBE_DEFER) > + goto err_free_irq; I'm fairly sure this is now broken with CONFIG_POWER_SEQUENCING=n since then pwrseq_get() is returning ERR_PTR(-ENOSYS) which is not handled here. I'm observing my ath10k_snoc is now failing to probe "with error -38" which definitely seems to be related, but I haven't debugged it further yet. Regards Luca