dm: core: Allow access to the device's driver_id data

When the device is created from a device tree node, it matches a compatible
string. Allow access to that string and the associated data.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@ti.com>
Acked-by: Heiko Schocher <hs@denx.de>
This commit is contained in:
Simon Glass 2014-11-11 10:46:18 -07:00
parent c1a6f371ae
commit 2ef249b442
3 changed files with 30 additions and 6 deletions

View file

@ -380,3 +380,8 @@ int device_find_next_child(struct udevice **devp)
return 0; return 0;
} }
ulong dev_get_of_data(struct udevice *dev)
{
return dev->of_id->data;
}

View file

@ -83,28 +83,33 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
* *
* @param blob: Device tree pointer * @param blob: Device tree pointer
* @param offset: Offset of node in device tree * @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 * @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 * does not have a compatible string, other error <0 if there is a device
* tree error * tree error
*/ */
static int driver_check_compatible(const void *blob, int offset, 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; int ret;
*of_idp = NULL;
if (!of_match) if (!of_match)
return -ENOENT; return -ENOENT;
while (of_match->compatible) { while (of_match->compatible) {
ret = fdt_node_check_compatible(blob, offset, ret = fdt_node_check_compatible(blob, offset,
of_match->compatible); of_match->compatible);
if (!ret) if (!ret) {
*of_idp = of_match;
return 0; return 0;
else if (ret == -FDT_ERR_NOTFOUND) } else if (ret == -FDT_ERR_NOTFOUND) {
return -ENODEV; return -ENODEV;
else if (ret < 0) } else if (ret < 0) {
return -EINVAL; return -EINVAL;
}
of_match++; 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); struct driver *driver = ll_entry_start(struct driver, driver);
const int n_ents = ll_entry_count(struct driver, driver); const int n_ents = ll_entry_count(struct driver, driver);
const struct udevice_id *id;
struct driver *entry; struct driver *entry;
struct udevice *dev; struct udevice *dev;
bool found = false; bool found = false;
@ -127,7 +133,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
if (devp) if (devp)
*devp = NULL; *devp = NULL;
for (entry = driver; entry != driver + n_ents; entry++) { 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); name = fdt_get_name(blob, offset, NULL);
if (ret == -ENOENT) { if (ret == -ENOENT) {
continue; 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); dm_warn("Error binding driver '%s'\n", entry->name);
return ret; return ret;
} else { } else {
dev->of_id = id;
found = true; found = true;
if (devp) if (devp)
*devp = dev; *devp = dev;

View file

@ -47,6 +47,7 @@ struct driver_info;
* @name: Name of device, typically the FDT node name * @name: Name of device, typically the FDT node name
* @platdata: Configuration data for this device * @platdata: Configuration data for this device
* @of_offset: Device tree node offset for this device (- for none) * @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 * @parent: Parent of this device, or NULL for the top level device
* @priv: Private data for this device * @priv: Private data for this device
* @uclass: Pointer to uclass for this device * @uclass: Pointer to uclass for this device
@ -65,6 +66,7 @@ struct udevice {
const char *name; const char *name;
void *platdata; void *platdata;
int of_offset; int of_offset;
const struct udevice_id *of_id;
struct udevice *parent; struct udevice *parent;
void *priv; void *priv;
struct uclass *uclass; struct uclass *uclass;
@ -205,6 +207,15 @@ void *dev_get_parentdata(struct udevice *dev);
*/ */
void *dev_get_priv(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 * device_get_child() - Get the child of a device by index
* *