]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI/pwrctrl: Lock device when calling device_is_bound()
authorBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Mon, 18 May 2026 10:07:00 +0000 (12:07 +0200)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 18 May 2026 22:32:23 +0000 (17:32 -0500)
The kerneldoc for device_is_bound() states that it must be called with
the device lock taken. Synchronize the two calls in pwrctrl core.

Fixes: b35cf3b6aa1e ("PCI/pwrctrl: Add APIs to power on/off pwrctrl devices")
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Link: https://patch.msgid.link/20260518100700.47581-1-bartosz.golaszewski@oss.qualcomm.com
drivers/pci/pwrctrl/core.c

index b5a0a14d316e90f2521776fae200ad8394dbecb4..de3b78fa4b5b903d41b958daa10f95eaea53cf2c 100644 (file)
@@ -206,10 +206,12 @@ static void pci_pwrctrl_power_off_device(struct device_node *np)
        if (!pdev)
                return;
 
-       if (device_is_bound(&pdev->dev)) {
-               ret = __pci_pwrctrl_power_off_device(&pdev->dev);
-               if (ret)
-                       dev_err(&pdev->dev, "Failed to power off device: %d", ret);
+       scoped_guard(device, &pdev->dev) {
+               if (device_is_bound(&pdev->dev)) {
+                       ret = __pci_pwrctrl_power_off_device(&pdev->dev);
+                       if (ret)
+                               dev_err(&pdev->dev, "Failed to power off device: %d", ret);
+               }
        }
 
        platform_device_put(pdev);
@@ -250,7 +252,7 @@ static int __pci_pwrctrl_power_on_device(struct device *dev)
 static int pci_pwrctrl_power_on_device(struct device_node *np)
 {
        struct platform_device *pdev;
-       int ret;
+       int ret = 0;
 
        for_each_available_child_of_node_scoped(np, child) {
                ret = pci_pwrctrl_power_on_device(child);
@@ -265,12 +267,14 @@ static int pci_pwrctrl_power_on_device(struct device_node *np)
        if (!pdev)
                return 0;
 
-       if (device_is_bound(&pdev->dev)) {
-               ret = __pci_pwrctrl_power_on_device(&pdev->dev);
-       } else {
-               /* FIXME: Use blocking wait instead of probe deferral */
-               dev_dbg(&pdev->dev, "driver is not bound\n");
-               ret = -EPROBE_DEFER;
+       scoped_guard(device, &pdev->dev) {
+               if (device_is_bound(&pdev->dev)) {
+                       ret = __pci_pwrctrl_power_on_device(&pdev->dev);
+               } else {
+                       /* FIXME: Use blocking wait instead of probe deferral */
+                       dev_dbg(&pdev->dev, "driver is not bound\n");
+                       ret = -EPROBE_DEFER;
+               }
        }
 
        platform_device_put(pdev);