Skip to content

Commit 1a50d94

Browse files
geerturobherring
authored andcommitted
treewide: Fix probing of devices in DT overlays
When loading a DT overlay that creates a device, the device is not probed, unless the DT overlay is unloaded and reloaded again. After the recent refactoring to improve fw_devlink, it no longer depends on the "compatible" property to identify which device tree nodes will become struct devices. fw_devlink now picks up dangling consumers (consumers pointing to descendent device tree nodes of a device that aren't converted to child devices) when a device is successfully bound to a driver. See __fw_devlink_pickup_dangling_consumers(). However, during DT overlay, a device's device tree node can have sub-nodes added/removed without unbinding/rebinding the driver. This difference in behavior between the normal device instantiation and probing flow vs. the DT overlay flow has a bunch of implications that are pointed out elsewhere[1]. One of them is that the fw_devlink logic to pick up dangling consumers is never exercised. This patch solves the fw_devlink issue by marking all DT nodes added by DT overlays with FWNODE_FLAG_NOT_DEVICE (fwnode that won't become device), and by clearing the flag when a struct device is actually created for the DT node. This way, fw_devlink knows not to have consumers waiting on these newly added DT nodes, and to propagate the dependency to an ancestor DT node that has the corresponding struct device. Based on a patch by Saravana Kannan, which covered only platform and spi devices. [1] https://lore.kernel.org/r/CAGETcx_bkuFaLCiPrAWCPQz+w79ccDp6=9e881qmK=vx3hBMyg@mail.gmail.com Fixes: 4a03282 ("of: property: Simplify of_link_to_phandle()") Link: https://lore.kernel.org/r/CAGETcx_+rhHvaC_HJXGrr5_WAd2+k5f=rWYnkCZ6z5bGX-wj4w@mail.gmail.com Signed-off-by: Geert Uytterhoeven <[email protected]> Acked-by: Mark Brown <[email protected]> Acked-by: Wolfram Sang <[email protected]> # for I2C Acked-by: Shawn Guo <[email protected]> Acked-by: Saravana Kannan <[email protected]> Tested-by: Ivan Bornyakov <[email protected]> Link: https://lore.kernel.org/r/e1fa546682ea4c8474ff997ab6244c5e11b6f8bc.1680182615.git.geert+renesas@glider.be Signed-off-by: Rob Herring <[email protected]>
1 parent e872450 commit 1a50d94

File tree

5 files changed

+22
-0
lines changed

5 files changed

+22
-0
lines changed

drivers/bus/imx-weim.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,12 @@ static int of_weim_notify(struct notifier_block *nb, unsigned long action,
331331
"Failed to setup timing for '%pOF'\n", rd->dn);
332332

333333
if (!of_node_check_flag(rd->dn, OF_POPULATED)) {
334+
/*
335+
* Clear the flag before adding the device so that
336+
* fw_devlink doesn't skip adding consumers to this
337+
* device.
338+
*/
339+
rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
334340
if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) {
335341
dev_err(&pdev->dev,
336342
"Failed to create child device '%pOF'\n",

drivers/i2c/i2c-core-of.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,11 @@ static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
244244
return NOTIFY_OK;
245245
}
246246

247+
/*
248+
* Clear the flag before adding the device so that fw_devlink
249+
* doesn't skip adding consumers to this device.
250+
*/
251+
rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
247252
client = of_i2c_register_device(adap, rd->dn);
248253
if (IS_ERR(client)) {
249254
dev_err(&adap->dev, "failed to create client for '%pOF'\n",

drivers/of/dynamic.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ static void __of_attach_node(struct device_node *np)
226226
np->sibling = np->parent->child;
227227
np->parent->child = np;
228228
of_node_clear_flag(np, OF_DETACHED);
229+
np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE;
229230
}
230231

231232
/**

drivers/of/platform.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,11 @@ static int of_platform_notify(struct notifier_block *nb,
740740
if (of_node_check_flag(rd->dn, OF_POPULATED))
741741
return NOTIFY_OK;
742742

743+
/*
744+
* Clear the flag before adding the device so that fw_devlink
745+
* doesn't skip adding consumers to this device.
746+
*/
747+
rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
743748
/* pdev_parent may be NULL when no bus platform device */
744749
pdev_parent = of_find_device_by_node(rd->dn->parent);
745750
pdev = of_platform_device_create(rd->dn, NULL,

drivers/spi/spi.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4436,6 +4436,11 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action,
44364436
return NOTIFY_OK;
44374437
}
44384438

4439+
/*
4440+
* Clear the flag before adding the device so that fw_devlink
4441+
* doesn't skip adding consumers to this device.
4442+
*/
4443+
rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE;
44394444
spi = of_register_spi_device(ctlr, rd->dn);
44404445
put_device(&ctlr->dev);
44414446

0 commit comments

Comments
 (0)