Skip to content

Commit 98e96cf

Browse files
Saravana Kannangregkh
authored andcommitted
drivers: bus: simple-pm-bus: Add support for probing simple bus only devices
fw_devlink could end up creating device links for bus only devices. However, bus only devices don't get probed and can block probe() or sync_state() [1] call backs of other devices. To avoid this, probe these devices using the simple-pm-bus driver. However, there are instances of devices that are not simple buses (they get probed by their specific drivers) that also list the "simple-bus" (or other bus only compatible strings) in their compatible property to automatically populate their child devices. We still want these devices to get probed by their specific drivers. So, we make sure this driver only probes devices that are only buses. [1] - https://lore.kernel.org/lkml/CAPDyKFo9Bxremkb1dDrr4OcXSpE0keVze94Cm=zrkOVxHHxBmQ@mail.gmail.com/ Fixes: c442a0d ("driver core: Set fw_devlink to "permissive" behavior by default") Cc: stable <stable@vger.kernel.org> Cc: Rob Herring <robh+dt@kernel.org> Tested-by: Saravana Kannan <saravanak@google.com> Tested-by: Ulf Hansson <ulf.hansson@linaro.org> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Tested-by: Damien Le Moal <damien.lemoal@wdc.com> Signed-off-by: Saravana Kannan <saravanak@google.com> Link: https://lore.kernel.org/r/20210929000735.585237-2-saravanak@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent f729a59 commit 98e96cf

1 file changed

Lines changed: 39 additions & 3 deletions

File tree

drivers/bus/simple-pm-bus.c

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,36 @@
1313
#include <linux/platform_device.h>
1414
#include <linux/pm_runtime.h>
1515

16-
1716
static int simple_pm_bus_probe(struct platform_device *pdev)
1817
{
19-
const struct of_dev_auxdata *lookup = dev_get_platdata(&pdev->dev);
20-
struct device_node *np = pdev->dev.of_node;
18+
const struct device *dev = &pdev->dev;
19+
const struct of_dev_auxdata *lookup = dev_get_platdata(dev);
20+
struct device_node *np = dev->of_node;
21+
const struct of_device_id *match;
22+
23+
/*
24+
* Allow user to use driver_override to bind this driver to a
25+
* transparent bus device which has a different compatible string
26+
* that's not listed in simple_pm_bus_of_match. We don't want to do any
27+
* of the simple-pm-bus tasks for these devices, so return early.
28+
*/
29+
if (pdev->driver_override)
30+
return 0;
31+
32+
match = of_match_device(dev->driver->of_match_table, dev);
33+
/*
34+
* These are transparent bus devices (not simple-pm-bus matches) that
35+
* have their child nodes populated automatically. So, don't need to
36+
* do anything more. We only match with the device if this driver is
37+
* the most specific match because we don't want to incorrectly bind to
38+
* a device that has a more specific driver.
39+
*/
40+
if (match && match->data) {
41+
if (of_property_match_string(np, "compatible", match->compatible) == 0)
42+
return 0;
43+
else
44+
return -ENODEV;
45+
}
2146

2247
dev_dbg(&pdev->dev, "%s\n", __func__);
2348

@@ -31,14 +56,25 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
3156

3257
static int simple_pm_bus_remove(struct platform_device *pdev)
3358
{
59+
const void *data = of_device_get_match_data(&pdev->dev);
60+
61+
if (pdev->driver_override || data)
62+
return 0;
63+
3464
dev_dbg(&pdev->dev, "%s\n", __func__);
3565

3666
pm_runtime_disable(&pdev->dev);
3767
return 0;
3868
}
3969

70+
#define ONLY_BUS ((void *) 1) /* Match if the device is only a bus. */
71+
4072
static const struct of_device_id simple_pm_bus_of_match[] = {
4173
{ .compatible = "simple-pm-bus", },
74+
{ .compatible = "simple-bus", .data = ONLY_BUS },
75+
{ .compatible = "simple-mfd", .data = ONLY_BUS },
76+
{ .compatible = "isa", .data = ONLY_BUS },
77+
{ .compatible = "arm,amba-bus", .data = ONLY_BUS },
4278
{ /* sentinel */ }
4379
};
4480
MODULE_DEVICE_TABLE(of, simple_pm_bus_of_match);

0 commit comments

Comments
 (0)