rpi4: boot: Update the firmwares for kernel v5.15.82 (fix booting issue)
[platform/kernel/linux-rpi.git] / drivers / bus / simple-pm-bus.c
index 01a3d0c..6b8d625 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
-
 static int simple_pm_bus_probe(struct platform_device *pdev)
 {
-       const struct of_dev_auxdata *lookup = dev_get_platdata(&pdev->dev);
-       struct device_node *np = pdev->dev.of_node;
+       const struct device *dev = &pdev->dev;
+       const struct of_dev_auxdata *lookup = dev_get_platdata(dev);
+       struct device_node *np = dev->of_node;
+       const struct of_device_id *match;
+
+       /*
+        * Allow user to use driver_override to bind this driver to a
+        * transparent bus device which has a different compatible string
+        * that's not listed in simple_pm_bus_of_match. We don't want to do any
+        * of the simple-pm-bus tasks for these devices, so return early.
+        */
+       if (pdev->driver_override)
+               return 0;
+
+       match = of_match_device(dev->driver->of_match_table, dev);
+       /*
+        * These are transparent bus devices (not simple-pm-bus matches) that
+        * have their child nodes populated automatically.  So, don't need to
+        * do anything more. We only match with the device if this driver is
+        * the most specific match because we don't want to incorrectly bind to
+        * a device that has a more specific driver.
+        */
+       if (match && match->data) {
+               if (of_property_match_string(np, "compatible", match->compatible) == 0)
+                       return 0;
+               else
+                       return -ENODEV;
+       }
 
        dev_dbg(&pdev->dev, "%s\n", __func__);
 
@@ -31,14 +56,25 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
 
 static int simple_pm_bus_remove(struct platform_device *pdev)
 {
+       const void *data = of_device_get_match_data(&pdev->dev);
+
+       if (pdev->driver_override || data)
+               return 0;
+
        dev_dbg(&pdev->dev, "%s\n", __func__);
 
        pm_runtime_disable(&pdev->dev);
        return 0;
 }
 
+#define ONLY_BUS       ((void *) 1) /* Match if the device is only a bus. */
+
 static const struct of_device_id simple_pm_bus_of_match[] = {
        { .compatible = "simple-pm-bus", },
+       { .compatible = "simple-bus",   .data = ONLY_BUS },
+       { .compatible = "simple-mfd",   .data = ONLY_BUS },
+       { .compatible = "isa",          .data = ONLY_BUS },
+       { .compatible = "arm,amba-bus", .data = ONLY_BUS },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, simple_pm_bus_of_match);