Skip to content

Commit 48005a5

Browse files
committed
Merge tag 'pci-v6.12-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
Pull pci fixes from Bjorn Helgaas: - Hold the rescan lock while adding devices to avoid race with concurrent pwrctl rescan that can lead to a crash (Bartosz Golaszewski) - Avoid binding pwrctl driver to QCom WCN wifi if the DT lacks the necessary PMU regulator descriptions (Bartosz Golaszewski) * tag 'pci-v6.12-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: PCI/pwrctl: Abandon QCom WCN probe on pre-pwrseq device-trees PCI: Hold rescan lock while adding devices during host probe
2 parents 86d6688 + ad783b9 commit 48005a5

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

drivers/pci/probe.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,7 +3105,9 @@ int pci_host_probe(struct pci_host_bridge *bridge)
31053105
list_for_each_entry(child, &bus->children, node)
31063106
pcie_bus_configure_settings(child);
31073107

3108+
pci_lock_rescan_remove();
31083109
pci_bus_add_devices(bus);
3110+
pci_unlock_rescan_remove();
31093111
return 0;
31103112
}
31113113
EXPORT_SYMBOL_GPL(pci_host_probe);

drivers/pci/pwrctl/pci-pwrctl-pwrseq.c

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
#include <linux/device.h>
77
#include <linux/mod_devicetable.h>
88
#include <linux/module.h>
9-
#include <linux/of.h>
109
#include <linux/pci-pwrctl.h>
1110
#include <linux/platform_device.h>
11+
#include <linux/property.h>
1212
#include <linux/pwrseq/consumer.h>
1313
#include <linux/slab.h>
1414
#include <linux/types.h>
@@ -18,6 +18,40 @@ struct pci_pwrctl_pwrseq_data {
1818
struct pwrseq_desc *pwrseq;
1919
};
2020

21+
struct pci_pwrctl_pwrseq_pdata {
22+
const char *target;
23+
/*
24+
* Called before doing anything else to perform device-specific
25+
* verification between requesting the power sequencing handle.
26+
*/
27+
int (*validate_device)(struct device *dev);
28+
};
29+
30+
static int pci_pwrctl_pwrseq_qcm_wcn_validate_device(struct device *dev)
31+
{
32+
/*
33+
* Old device trees for some platforms already define wifi nodes for
34+
* the WCN family of chips since before power sequencing was added
35+
* upstream.
36+
*
37+
* These nodes don't consume the regulator outputs from the PMU, and
38+
* if we allow this driver to bind to one of such "incomplete" nodes,
39+
* we'll see a kernel log error about the indefinite probe deferral.
40+
*
41+
* Check the existence of the regulator supply that exists on all
42+
* WCN models before moving forward.
43+
*/
44+
if (!device_property_present(dev, "vddaon-supply"))
45+
return -ENODEV;
46+
47+
return 0;
48+
}
49+
50+
static const struct pci_pwrctl_pwrseq_pdata pci_pwrctl_pwrseq_qcom_wcn_pdata = {
51+
.target = "wlan",
52+
.validate_device = pci_pwrctl_pwrseq_qcm_wcn_validate_device,
53+
};
54+
2155
static void devm_pci_pwrctl_pwrseq_power_off(void *data)
2256
{
2357
struct pwrseq_desc *pwrseq = data;
@@ -27,15 +61,26 @@ static void devm_pci_pwrctl_pwrseq_power_off(void *data)
2761

2862
static int pci_pwrctl_pwrseq_probe(struct platform_device *pdev)
2963
{
64+
const struct pci_pwrctl_pwrseq_pdata *pdata;
3065
struct pci_pwrctl_pwrseq_data *data;
3166
struct device *dev = &pdev->dev;
3267
int ret;
3368

69+
pdata = device_get_match_data(dev);
70+
if (!pdata || !pdata->target)
71+
return -EINVAL;
72+
73+
if (pdata->validate_device) {
74+
ret = pdata->validate_device(dev);
75+
if (ret)
76+
return ret;
77+
}
78+
3479
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
3580
if (!data)
3681
return -ENOMEM;
3782

38-
data->pwrseq = devm_pwrseq_get(dev, of_device_get_match_data(dev));
83+
data->pwrseq = devm_pwrseq_get(dev, pdata->target);
3984
if (IS_ERR(data->pwrseq))
4085
return dev_err_probe(dev, PTR_ERR(data->pwrseq),
4186
"Failed to get the power sequencer\n");
@@ -64,17 +109,17 @@ static const struct of_device_id pci_pwrctl_pwrseq_of_match[] = {
64109
{
65110
/* ATH11K in QCA6390 package. */
66111
.compatible = "pci17cb,1101",
67-
.data = "wlan",
112+
.data = &pci_pwrctl_pwrseq_qcom_wcn_pdata,
68113
},
69114
{
70115
/* ATH11K in WCN6855 package. */
71116
.compatible = "pci17cb,1103",
72-
.data = "wlan",
117+
.data = &pci_pwrctl_pwrseq_qcom_wcn_pdata,
73118
},
74119
{
75120
/* ATH12K in WCN7850 package. */
76121
.compatible = "pci17cb,1107",
77-
.data = "wlan",
122+
.data = &pci_pwrctl_pwrseq_qcom_wcn_pdata,
78123
},
79124
{ }
80125
};

0 commit comments

Comments
 (0)