From c57f806bf2e745c4273dc33c9827781cff46427c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 17 Jul 2016 15:23:15 -0600 Subject: [PATCH] dm: core: Add a way to find a device by its driver Some SoCs have a single clock device. Provide a way to find it given its driver name. This is handled by the linker so will fail if the name is not found, avoiding strange errors when names change and do not match. It is also faster than a string comparison. Signed-off-by: Simon Glass --- drivers/core/uclass.c | 20 ++++++++++++++++++++ include/dm/device.h | 4 ++++ include/dm/uclass.h | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 1141ce1ba3..de602ae52d 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -311,6 +311,26 @@ static int uclass_find_device_by_phandle(enum uclass_id id, } #endif +int uclass_get_device_by_driver(enum uclass_id id, + const struct driver *find_drv, + struct udevice **devp) +{ + struct udevice *dev; + struct uclass *uc; + int ret; + + ret = uclass_get(id, &uc); + if (ret) + return ret; + + list_for_each_entry(dev, &uc->dev_head, uclass_node) { + if (dev->driver == find_drv) + return uclass_get_device_tail(dev, 0, devp); + } + + return -ENODEV; +} + int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp) { diff --git a/include/dm/device.h b/include/dm/device.h index c825d47236..705849b228 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -207,6 +207,10 @@ struct driver { #define U_BOOT_DRIVER(__name) \ ll_entry_declare(struct driver, __name, driver) +/* Get a pointer to a given driver */ +#define DM_GET_DRIVER(__name) \ + ll_entry_get(struct driver, __name, driver) + /** * dev_get_platdata() - Get the platform data for a device * diff --git a/include/dm/uclass.h b/include/dm/uclass.h index fd368b6bd0..84f05bcfce 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -38,6 +38,7 @@ struct uclass { struct list_head sibling_node; }; +struct driver; struct udevice; /* Members of this uclass sequence themselves with aliases */ @@ -193,6 +194,23 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node, int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent, const char *name, struct udevice **devp); +/** + * uclass_get_device_by_driver() - Get a uclass device for a driver + * + * This searches the devices in the uclass for one that uses the given + * driver. Use DM_GET_DRIVER(name) for the @drv argument, where 'name' is + * the driver name - as used in U_BOOT_DRIVER(name). + * + * The device is probed to activate it ready for use. + * + * @id: ID to look up + * @drv: Driver to look for + * @devp: Returns pointer to the first device with that driver + * @return 0 if OK, -ve on error + */ +int uclass_get_device_by_driver(enum uclass_id id, const struct driver *drv, + struct udevice **devp); + /** * uclass_first_device() - Get the first device in a uclass * -- 2.25.1