diff options
-rw-r--r-- | drivers/core/device.c | 5 | ||||
-rw-r--r-- | drivers/core/lists.c | 20 | ||||
-rw-r--r-- | include/dm/device.h | 11 |
3 files changed, 30 insertions, 6 deletions
diff --git a/drivers/core/device.c b/drivers/core/device.c index 576a4f2..81ddeca 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -380,3 +380,8 @@ int device_find_next_child(struct udevice **devp) return 0; } + +ulong dev_get_of_data(struct udevice *dev) +{ + return dev->of_id->data; +} diff --git a/drivers/core/lists.c b/drivers/core/lists.c index 3a1ea85..24d2864 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -83,28 +83,33 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only) * * @param blob: Device tree pointer * @param offset: Offset of node in device tree - * @param of_matchL List of compatible strings to match + * @param of_match: List of compatible strings to match + * @param of_idp: Returns the match that was found * @return 0 if there is a match, -ENOENT if no match, -ENODEV if the node * does not have a compatible string, other error <0 if there is a device * tree error */ static int driver_check_compatible(const void *blob, int offset, - const struct udevice_id *of_match) + const struct udevice_id *of_match, + const struct udevice_id **of_idp) { int ret; + *of_idp = NULL; if (!of_match) return -ENOENT; while (of_match->compatible) { ret = fdt_node_check_compatible(blob, offset, of_match->compatible); - if (!ret) + if (!ret) { + *of_idp = of_match; return 0; - else if (ret == -FDT_ERR_NOTFOUND) + } else if (ret == -FDT_ERR_NOTFOUND) { return -ENODEV; - else if (ret < 0) + } else if (ret < 0) { return -EINVAL; + } of_match++; } @@ -116,6 +121,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, { struct driver *driver = ll_entry_start(struct driver, driver); const int n_ents = ll_entry_count(struct driver, driver); + const struct udevice_id *id; struct driver *entry; struct udevice *dev; bool found = false; @@ -127,7 +133,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, if (devp) *devp = NULL; for (entry = driver; entry != driver + n_ents; entry++) { - ret = driver_check_compatible(blob, offset, entry->of_match); + ret = driver_check_compatible(blob, offset, entry->of_match, + &id); name = fdt_get_name(blob, offset, NULL); if (ret == -ENOENT) { continue; @@ -147,6 +154,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, dm_warn("Error binding driver '%s'\n", entry->name); return ret; } else { + dev->of_id = id; found = true; if (devp) *devp = dev; diff --git a/include/dm/device.h b/include/dm/device.h index 9ce95a8..287504c 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -47,6 +47,7 @@ struct driver_info; * @name: Name of device, typically the FDT node name * @platdata: Configuration data for this device * @of_offset: Device tree node offset for this device (- for none) + * @of_id: Pointer to the udevice_id structure which created the device * @parent: Parent of this device, or NULL for the top level device * @priv: Private data for this device * @uclass: Pointer to uclass for this device @@ -65,6 +66,7 @@ struct udevice { const char *name; void *platdata; int of_offset; + const struct udevice_id *of_id; struct udevice *parent; void *priv; struct uclass *uclass; @@ -206,6 +208,15 @@ void *dev_get_parentdata(struct udevice *dev); void *dev_get_priv(struct udevice *dev); /** + * dev_get_of_data() - get the device tree data used to bind a device + * + * When a device is bound using a device tree node, it matches a + * particular compatible string as in struct udevice_id. This function + * returns the associated data value for that compatible string + */ +ulong dev_get_of_data(struct udevice *dev); + +/** * device_get_child() - Get the child of a device by index * * Returns the numbered child, 0 being the first. This does not use |