mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
of: property: add i2c-parent to fw_devlink supplier bindings
Platform-device i2c muxes (i2c-mux-reg, i2c-mux-gpio, ...) reference the bus they multiplex with an i2c-parent phandle and hold a reference on that adapter from probe until remove. Unlike muxes that are clients on the parent bus, they live outside the adapter's device hierarchy, so nothing orders their teardown against it: if the adapter's device is unbound first — e.g. while reverting a device-tree overlay whose changeset attached the mux nodes before the controller nodes — i2c_del_adapter() blocks forever in wait_for_completion(&adap->dev_released), waiting for a reference that is only dropped later in the same teardown sequence. Teach fw_devlink about i2c-parent so the core creates the corresponding device links: consumers are unbound before the parent adapter's device, and probe ordering no longer needs -EPROBE_DEFER. A plain DEFINE_SIMPLE_PROP() cannot be used because the property has two incompatible layouts: the i2c mux bindings hold a list of bare phandles (i2c-demux-pinctrl takes several), while toshiba,tc9563 holds a single phandle followed by an i2c slave-address cell. The two forms are indistinguishable in the flattened tree, and a 0-cell parse of the tc9563 form would read the slave address as a phandle, linking the consumer to whatever node happens to carry that phandle value. Use a custom parser that only takes entry 0 for toshiba,tc9563 nodes. Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai> Link: https://patch.msgid.link/20260815-b4-of-property-add-i2c-parent-v3-1-c22588b6482a@nexthop.ai Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
This commit is contained in:
parent
cfbc5d96e8
commit
218ffd1a2c
|
|
@ -1471,6 +1471,22 @@ static struct device_node *parse_gpio_compat(struct device_node *np,
|
|||
return sup_args.np;
|
||||
}
|
||||
|
||||
static struct device_node *parse_i2c_parent(struct device_node *np,
|
||||
const char *prop_name, int index)
|
||||
{
|
||||
if (strcmp(prop_name, "i2c-parent"))
|
||||
return NULL;
|
||||
|
||||
/* tc9563 (pci1179,0623) is <phandle addr>; every other user is bare phandles */
|
||||
if (of_device_is_compatible(np, "pci1179,0623")) {
|
||||
if (index)
|
||||
return NULL;
|
||||
return of_parse_phandle(np, prop_name, 0);
|
||||
}
|
||||
|
||||
return of_parse_phandle(np, prop_name, index);
|
||||
}
|
||||
|
||||
static struct device_node *parse_interrupts(struct device_node *np,
|
||||
const char *prop_name, int index)
|
||||
{
|
||||
|
|
@ -1562,6 +1578,7 @@ static const struct supplier_bindings of_supplier_bindings[] = {
|
|||
{ .parse_prop = parse_resets, },
|
||||
{ .parse_prop = parse_leds, },
|
||||
{ .parse_prop = parse_backlight, },
|
||||
{ .parse_prop = parse_i2c_parent, },
|
||||
{ .parse_prop = parse_panel, },
|
||||
{ .parse_prop = parse_msi_parent, },
|
||||
{ .parse_prop = parse_pses, },
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user