From e7c865620e569df493e67d3772673108fce62064 Mon Sep 17 00:00:00 2001 From: Jean-Jacques Hiblot Date: Thu, 9 Aug 2018 16:17:42 +0200 Subject: uclass: Add dev_get_uclass_index() to get the uclass/index of a device This function is the reciprocal of uclass_find_device(). It will be used to print the index information in dm tree dump. Signed-off-by: Jean-Jacques Hiblot --- include/dm/uclass-internal.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h index 7ba064bd53f..30d5a4fb9bf 100644 --- a/include/dm/uclass-internal.h +++ b/include/dm/uclass-internal.h @@ -23,6 +23,17 @@ */ int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp); +/** + * dev_get_uclass_index() - Get uclass and index of device + * @dev: - in - Device that we want the uclass/index of + * @ucp: - out - A pointer to the uclass the device belongs to + * + * The device is not prepared for use - this is an internal function. + * + * @return the index of the device in the uclass list or -ENODEV if not found. + */ +int dev_get_uclass_index(struct udevice *dev, struct uclass **ucp); + /** * uclass_find_device() - Return n-th child of uclass * @id: Id number of the uclass -- cgit v1.3.1 From 7ec9181d6a2b68480a289c36e5729487f2a4add1 Mon Sep 17 00:00:00 2001 From: Jean-Jacques Hiblot Date: Thu, 9 Aug 2018 16:17:44 +0200 Subject: dm: convert device_get_global_by_of_offset() to device_get_global_by_ofnode() Also add device_find_global_by_ofnode() that also find a device based on the OF node, but doesn't probe the device. Signed-off-by: Jean-Jacques Hiblot --- arch/arm/mach-rockchip/rk3188-board-spl.c | 2 +- arch/arm/mach-rockchip/rk3288-board-spl.c | 2 +- drivers/core/device.c | 19 +++++++++++++------ include/dm/device.h | 23 +++++++++++++++++++---- 4 files changed, 34 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/arch/arm/mach-rockchip/rk3188-board-spl.c b/arch/arm/mach-rockchip/rk3188-board-spl.c index 59c7e4d4db6..98ca971b88a 100644 --- a/arch/arm/mach-rockchip/rk3188-board-spl.c +++ b/arch/arm/mach-rockchip/rk3188-board-spl.c @@ -49,7 +49,7 @@ u32 spl_boot_device(void) debug("node=%d\n", node); goto fallback; } - ret = device_get_global_by_of_offset(node, &dev); + ret = device_get_global_by_ofnode(offset_to_ofnode(node), &dev); if (ret) { debug("device at node %s/%d not found: %d\n", bootdev, node, ret); diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c index ea6a14af4f0..abd62e520fa 100644 --- a/arch/arm/mach-rockchip/rk3288-board-spl.c +++ b/arch/arm/mach-rockchip/rk3288-board-spl.c @@ -51,7 +51,7 @@ u32 spl_boot_device(void) debug("node=%d\n", node); goto fallback; } - ret = device_get_global_by_of_offset(node, &dev); + ret = device_get_global_by_ofnode(offset_to_ofnode(node), &dev); if (ret) { debug("device at node %s/%d not found: %d\n", bootdev, node, ret); diff --git a/drivers/core/device.c b/drivers/core/device.c index 207d566b71d..fd59fe1e0f5 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -594,16 +594,16 @@ int device_get_child_by_of_offset(struct udevice *parent, int node, return device_get_device_tail(dev, ret, devp); } -static struct udevice *_device_find_global_by_of_offset(struct udevice *parent, - int of_offset) +static struct udevice *_device_find_global_by_ofnode(struct udevice *parent, + ofnode ofnode) { struct udevice *dev, *found; - if (dev_of_offset(parent) == of_offset) + if (ofnode_equal(dev_ofnode(parent), ofnode)) return parent; list_for_each_entry(dev, &parent->child_head, sibling_node) { - found = _device_find_global_by_of_offset(dev, of_offset); + found = _device_find_global_by_ofnode(dev, ofnode); if (found) return found; } @@ -611,11 +611,18 @@ static struct udevice *_device_find_global_by_of_offset(struct udevice *parent, return NULL; } -int device_get_global_by_of_offset(int of_offset, struct udevice **devp) +int device_find_global_by_ofnode(ofnode ofnode, struct udevice **devp) +{ + *devp = _device_find_global_by_ofnode(gd->dm_root, ofnode); + + return *devp ? 0 : -ENOENT; +} + +int device_get_global_by_ofnode(ofnode ofnode, struct udevice **devp) { struct udevice *dev; - dev = _device_find_global_by_of_offset(gd->dm_root, of_offset); + dev = _device_find_global_by_ofnode(gd->dm_root, ofnode); return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp); } diff --git a/include/dm/device.h b/include/dm/device.h index 49078bc6b36..3120b68fcc6 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -473,18 +473,33 @@ int device_get_child_by_of_offset(struct udevice *parent, int of_offset, struct udevice **devp); /** - * device_get_global_by_of_offset() - Get a device based on FDT offset + * device_find_global_by_ofnode() - Get a device based on ofnode * - * Locates a device by its device tree offset, searching globally throughout + * Locates a device by its device tree ofnode, searching globally throughout + * the all driver model devices. + * + * The device is NOT probed + * + * @node: Device tree ofnode to find + * @devp: Returns pointer to device if found, otherwise this is set to NULL + * @return 0 if OK, -ve on error + */ + +int device_find_global_by_ofnode(ofnode node, struct udevice **devp); + +/** + * device_get_global_by_ofnode() - Get a device based on ofnode + * + * Locates a device by its device tree ofnode, searching globally throughout * the all driver model devices. * * The device is probed to activate it ready for use. * - * @of_offset: Device tree offset to find + * @node: Device tree ofnode to find * @devp: Returns pointer to device if found, otherwise this is set to NULL * @return 0 if OK, -ve on error */ -int device_get_global_by_of_offset(int of_offset, struct udevice **devp); +int device_get_global_by_ofnode(ofnode node, struct udevice **devp); /** * device_find_first_child() - Find the first child of a device -- cgit v1.3.1 From 3be9bcb04883497b422f3f2e4a468657056dd48d Mon Sep 17 00:00:00 2001 From: Jean-Jacques Hiblot Date: Thu, 9 Aug 2018 16:17:45 +0200 Subject: device: expose the functions used to remove and unbind children of a device Also add a 'drv' parameter to filter the children to remove/unbind. Exporting those functions is a preparatory work for the addition of the bind/unbind commands. Signed-off-by: Jean-Jacques Hiblot --- drivers/core/device-remove.c | 30 +++++++++++------------------- include/dm/device-internal.h | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 1cf2278e9ef..586fadee0a8 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -17,16 +17,7 @@ #include #include -/** - * device_chld_unbind() - Unbind all device's children from the device - * - * On error, the function continues to unbind all children, and reports the - * first error. - * - * @dev: The device that is to be stripped of its children - * @return 0 on success, -ve on error - */ -static int device_chld_unbind(struct udevice *dev) +int device_chld_unbind(struct udevice *dev, struct driver *drv) { struct udevice *pos, *n; int ret, saved_ret = 0; @@ -34,6 +25,9 @@ static int device_chld_unbind(struct udevice *dev) assert(dev); list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) { + if (drv && (pos->driver != drv)) + continue; + ret = device_unbind(pos); if (ret && !saved_ret) saved_ret = ret; @@ -42,13 +36,8 @@ static int device_chld_unbind(struct udevice *dev) return saved_ret; } -/** - * device_chld_remove() - Stop all device's children - * @dev: The device whose children are to be removed - * @pre_os_remove: Flag, if this functions is called in the pre-OS stage - * @return 0 on success, -ve on error - */ -static int device_chld_remove(struct udevice *dev, uint flags) +int device_chld_remove(struct udevice *dev, struct driver *drv, + uint flags) { struct udevice *pos, *n; int ret; @@ -56,6 +45,9 @@ static int device_chld_remove(struct udevice *dev, uint flags) assert(dev); list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) { + if (drv && (pos->driver != drv)) + continue; + ret = device_remove(pos, flags); if (ret) return ret; @@ -87,7 +79,7 @@ int device_unbind(struct udevice *dev) return ret; } - ret = device_chld_unbind(dev); + ret = device_chld_unbind(dev, NULL); if (ret) return ret; @@ -178,7 +170,7 @@ int device_remove(struct udevice *dev, uint flags) if (ret) return ret; - ret = device_chld_remove(dev, flags); + ret = device_chld_remove(dev, NULL, flags); if (ret) goto err; diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index f4af15448fa..02ac4c79528 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -130,6 +130,44 @@ void device_free(struct udevice *dev); static inline void device_free(struct udevice *dev) {} #endif +/** + * device_chld_unbind() - Unbind all device's children from the device if bound + * to drv + * + * On error, the function continues to unbind all children, and reports the + * first error. + * + * @dev: The device that is to be stripped of its children + * @drv: The targeted driver + * @return 0 on success, -ve on error + */ +#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) +int device_chld_unbind(struct udevice *dev, struct driver *drv); +#else +static inline int device_chld_unbind(struct udevice *dev, struct driver *drv) +{ + return 0; +} +#endif + +/** + * device_chld_remove() - Stop all device's children + * @dev: The device whose children are to be removed + * @drv: The targeted driver + * @flags: Flag, if this functions is called in the pre-OS stage + * @return 0 on success, -ve on error + */ +#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) +int device_chld_remove(struct udevice *dev, struct driver *drv, + uint flags); +#else +static inline int device_chld_remove(struct udevice *dev, struct driver *drv, + uint flags) +{ + return 0; +} +#endif + /** * simple_bus_translate() - translate a bus address to a system address * -- cgit v1.3.1