Commit 79725ca4f6d583e4c677f694b89c839ed7b07b8f

Authored by Simon Glass
1 parent ba94e83911

Revert "dm: Export device_remove_children / device_unbind_children"

This reverts commit bb52b367f6ca4a3a918e77737f4ff6a1089912d9.

Signed-off-by: Simon Glass <sjg@chromium.org>

Showing 2 changed files with 18 additions and 30 deletions Inline Diff

drivers/core/device-remove.c
1 /* 1 /*
2 * Device manager 2 * Device manager
3 * 3 *
4 * Copyright (c) 2014 Google, Inc 4 * Copyright (c) 2014 Google, Inc
5 * 5 *
6 * (C) Copyright 2012 6 * (C) Copyright 2012
7 * Pavel Herrmann <morpheus.ibis@gmail.com> 7 * Pavel Herrmann <morpheus.ibis@gmail.com>
8 * 8 *
9 * SPDX-License-Identifier: GPL-2.0+ 9 * SPDX-License-Identifier: GPL-2.0+
10 */ 10 */
11 11
12 #include <common.h> 12 #include <common.h>
13 #include <errno.h> 13 #include <errno.h>
14 #include <malloc.h> 14 #include <malloc.h>
15 #include <dm/device.h> 15 #include <dm/device.h>
16 #include <dm/device-internal.h> 16 #include <dm/device-internal.h>
17 #include <dm/uclass.h> 17 #include <dm/uclass.h>
18 #include <dm/uclass-internal.h> 18 #include <dm/uclass-internal.h>
19 #include <dm/util.h> 19 #include <dm/util.h>
20 20
21 int device_unbind_children(struct udevice *dev) 21 /**
22 * device_chld_unbind() - Unbind all device's children from the device
23 *
24 * On error, the function continues to unbind all children, and reports the
25 * first error.
26 *
27 * @dev: The device that is to be stripped of its children
28 * @return 0 on success, -ve on error
29 */
30 static int device_chld_unbind(struct udevice *dev)
22 { 31 {
23 struct udevice *pos, *n; 32 struct udevice *pos, *n;
24 int ret, saved_ret = 0; 33 int ret, saved_ret = 0;
25 34
26 assert(dev); 35 assert(dev);
27 36
28 list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) { 37 list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
29 ret = device_unbind(pos); 38 ret = device_unbind(pos);
30 if (ret && !saved_ret) 39 if (ret && !saved_ret)
31 saved_ret = ret; 40 saved_ret = ret;
32 } 41 }
33 42
34 return saved_ret; 43 return saved_ret;
35 } 44 }
36 45
37 int device_remove_children(struct udevice *dev) 46 /**
47 * device_chld_remove() - Stop all device's children
48 * @dev: The device whose children are to be removed
49 * @return 0 on success, -ve on error
50 */
51 static int device_chld_remove(struct udevice *dev)
38 { 52 {
39 struct udevice *pos, *n; 53 struct udevice *pos, *n;
40 int ret; 54 int ret;
41 55
42 assert(dev); 56 assert(dev);
43 57
44 list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) { 58 list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
45 ret = device_remove(pos); 59 ret = device_remove(pos);
46 if (ret) 60 if (ret)
47 return ret; 61 return ret;
48 } 62 }
49 63
50 return 0; 64 return 0;
51 } 65 }
52 66
53 int device_unbind(struct udevice *dev) 67 int device_unbind(struct udevice *dev)
54 { 68 {
55 const struct driver *drv; 69 const struct driver *drv;
56 int ret; 70 int ret;
57 71
58 if (!dev) 72 if (!dev)
59 return -EINVAL; 73 return -EINVAL;
60 74
61 if (dev->flags & DM_FLAG_ACTIVATED) 75 if (dev->flags & DM_FLAG_ACTIVATED)
62 return -EINVAL; 76 return -EINVAL;
63 77
64 if (!(dev->flags & DM_FLAG_BOUND)) 78 if (!(dev->flags & DM_FLAG_BOUND))
65 return -EINVAL; 79 return -EINVAL;
66 80
67 drv = dev->driver; 81 drv = dev->driver;
68 assert(drv); 82 assert(drv);
69 83
70 if (drv->unbind) { 84 if (drv->unbind) {
71 ret = drv->unbind(dev); 85 ret = drv->unbind(dev);
72 if (ret) 86 if (ret)
73 return ret; 87 return ret;
74 } 88 }
75 89
76 ret = device_unbind_children(dev); 90 ret = device_chld_unbind(dev);
77 if (ret) 91 if (ret)
78 return ret; 92 return ret;
79 93
80 if (dev->flags & DM_FLAG_ALLOC_PDATA) { 94 if (dev->flags & DM_FLAG_ALLOC_PDATA) {
81 free(dev->platdata); 95 free(dev->platdata);
82 dev->platdata = NULL; 96 dev->platdata = NULL;
83 } 97 }
84 if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) { 98 if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) {
85 free(dev->uclass_platdata); 99 free(dev->uclass_platdata);
86 dev->uclass_platdata = NULL; 100 dev->uclass_platdata = NULL;
87 } 101 }
88 if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { 102 if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
89 free(dev->parent_platdata); 103 free(dev->parent_platdata);
90 dev->parent_platdata = NULL; 104 dev->parent_platdata = NULL;
91 } 105 }
92 ret = uclass_unbind_device(dev); 106 ret = uclass_unbind_device(dev);
93 if (ret) 107 if (ret)
94 return ret; 108 return ret;
95 109
96 if (dev->parent) 110 if (dev->parent)
97 list_del(&dev->sibling_node); 111 list_del(&dev->sibling_node);
98 112
99 devres_release_all(dev); 113 devres_release_all(dev);
100 114
101 free(dev); 115 free(dev);
102 116
103 return 0; 117 return 0;
104 } 118 }
105 119
106 /** 120 /**
107 * device_free() - Free memory buffers allocated by a device 121 * device_free() - Free memory buffers allocated by a device
108 * @dev: Device that is to be started 122 * @dev: Device that is to be started
109 */ 123 */
110 void device_free(struct udevice *dev) 124 void device_free(struct udevice *dev)
111 { 125 {
112 int size; 126 int size;
113 127
114 if (dev->driver->priv_auto_alloc_size) { 128 if (dev->driver->priv_auto_alloc_size) {
115 free(dev->priv); 129 free(dev->priv);
116 dev->priv = NULL; 130 dev->priv = NULL;
117 } 131 }
118 size = dev->uclass->uc_drv->per_device_auto_alloc_size; 132 size = dev->uclass->uc_drv->per_device_auto_alloc_size;
119 if (size) { 133 if (size) {
120 free(dev->uclass_priv); 134 free(dev->uclass_priv);
121 dev->uclass_priv = NULL; 135 dev->uclass_priv = NULL;
122 } 136 }
123 if (dev->parent) { 137 if (dev->parent) {
124 size = dev->parent->driver->per_child_auto_alloc_size; 138 size = dev->parent->driver->per_child_auto_alloc_size;
125 if (!size) { 139 if (!size) {
126 size = dev->parent->uclass->uc_drv-> 140 size = dev->parent->uclass->uc_drv->
127 per_child_auto_alloc_size; 141 per_child_auto_alloc_size;
128 } 142 }
129 if (size) { 143 if (size) {
130 free(dev->parent_priv); 144 free(dev->parent_priv);
131 dev->parent_priv = NULL; 145 dev->parent_priv = NULL;
132 } 146 }
133 } 147 }
134 148
135 devres_release_probe(dev); 149 devres_release_probe(dev);
136 } 150 }
137 151
138 int device_remove(struct udevice *dev) 152 int device_remove(struct udevice *dev)
139 { 153 {
140 const struct driver *drv; 154 const struct driver *drv;
141 int ret; 155 int ret;
142 156
143 if (!dev) 157 if (!dev)
144 return -EINVAL; 158 return -EINVAL;
145 159
146 if (!(dev->flags & DM_FLAG_ACTIVATED)) 160 if (!(dev->flags & DM_FLAG_ACTIVATED))
147 return 0; 161 return 0;
148 162
149 drv = dev->driver; 163 drv = dev->driver;
150 assert(drv); 164 assert(drv);
151 165
152 ret = uclass_pre_remove_device(dev); 166 ret = uclass_pre_remove_device(dev);
153 if (ret) 167 if (ret)
154 return ret; 168 return ret;
155 169
156 ret = device_remove_children(dev); 170 ret = device_chld_remove(dev);
157 if (ret) 171 if (ret)
158 goto err; 172 goto err;
159 173
160 if (drv->remove) { 174 if (drv->remove) {
161 ret = drv->remove(dev); 175 ret = drv->remove(dev);
162 if (ret) 176 if (ret)
163 goto err_remove; 177 goto err_remove;
164 } 178 }
165 179
166 if (dev->parent && dev->parent->driver->child_post_remove) { 180 if (dev->parent && dev->parent->driver->child_post_remove) {
167 ret = dev->parent->driver->child_post_remove(dev); 181 ret = dev->parent->driver->child_post_remove(dev);
168 if (ret) { 182 if (ret) {
169 dm_warn("%s: Device '%s' failed child_post_remove()", 183 dm_warn("%s: Device '%s' failed child_post_remove()",
170 __func__, dev->name); 184 __func__, dev->name);
171 } 185 }
172 } 186 }
173 187
174 device_free(dev); 188 device_free(dev);
175 189
176 dev->seq = -1; 190 dev->seq = -1;
177 dev->flags &= ~DM_FLAG_ACTIVATED; 191 dev->flags &= ~DM_FLAG_ACTIVATED;
178 192
179 return ret; 193 return ret;
180 194
181 err_remove: 195 err_remove:
182 /* We can't put the children back */ 196 /* We can't put the children back */
183 dm_warn("%s: Device '%s' failed to remove, but children are gone\n", 197 dm_warn("%s: Device '%s' failed to remove, but children are gone\n",
184 __func__, dev->name); 198 __func__, dev->name);
185 err: 199 err:
186 ret = uclass_post_probe_device(dev); 200 ret = uclass_post_probe_device(dev);
187 if (ret) { 201 if (ret) {
188 dm_warn("%s: Device '%s' failed to post_probe on error path\n", 202 dm_warn("%s: Device '%s' failed to post_probe on error path\n",
189 __func__, dev->name); 203 __func__, dev->name);
190 } 204 }
191 205
192 return ret; 206 return ret;
193 } 207 }
194 208
include/dm/device-internal.h
1 /* 1 /*
2 * Copyright (C) 2013 Google, Inc 2 * Copyright (C) 2013 Google, Inc
3 * 3 *
4 * (C) Copyright 2012 4 * (C) Copyright 2012
5 * Pavel Herrmann <morpheus.ibis@gmail.com> 5 * Pavel Herrmann <morpheus.ibis@gmail.com>
6 * Marek Vasut <marex@denx.de> 6 * Marek Vasut <marex@denx.de>
7 * 7 *
8 * SPDX-License-Identifier: GPL-2.0+ 8 * SPDX-License-Identifier: GPL-2.0+
9 */ 9 */
10 10
11 #ifndef _DM_DEVICE_INTERNAL_H 11 #ifndef _DM_DEVICE_INTERNAL_H
12 #define _DM_DEVICE_INTERNAL_H 12 #define _DM_DEVICE_INTERNAL_H
13 13
14 struct udevice; 14 struct udevice;
15 15
16 /** 16 /**
17 * device_bind() - Create a device and bind it to a driver 17 * device_bind() - Create a device and bind it to a driver
18 * 18 *
19 * Called to set up a new device attached to a driver. The device will either 19 * Called to set up a new device attached to a driver. The device will either
20 * have platdata, or a device tree node which can be used to create the 20 * have platdata, or a device tree node which can be used to create the
21 * platdata. 21 * platdata.
22 * 22 *
23 * Once bound a device exists but is not yet active until device_probe() is 23 * Once bound a device exists but is not yet active until device_probe() is
24 * called. 24 * called.
25 * 25 *
26 * @parent: Pointer to device's parent, under which this driver will exist 26 * @parent: Pointer to device's parent, under which this driver will exist
27 * @drv: Device's driver 27 * @drv: Device's driver
28 * @name: Name of device (e.g. device tree node name) 28 * @name: Name of device (e.g. device tree node name)
29 * @platdata: Pointer to data for this device - the structure is device- 29 * @platdata: Pointer to data for this device - the structure is device-
30 * specific but may include the device's I/O address, etc.. This is NULL for 30 * specific but may include the device's I/O address, etc.. This is NULL for
31 * devices which use device tree. 31 * devices which use device tree.
32 * @of_offset: Offset of device tree node for this device. This is -1 for 32 * @of_offset: Offset of device tree node for this device. This is -1 for
33 * devices which don't use device tree. 33 * devices which don't use device tree.
34 * @devp: if non-NULL, returns a pointer to the bound device 34 * @devp: if non-NULL, returns a pointer to the bound device
35 * @return 0 if OK, -ve on error 35 * @return 0 if OK, -ve on error
36 */ 36 */
37 int device_bind(struct udevice *parent, const struct driver *drv, 37 int device_bind(struct udevice *parent, const struct driver *drv,
38 const char *name, void *platdata, int of_offset, 38 const char *name, void *platdata, int of_offset,
39 struct udevice **devp); 39 struct udevice **devp);
40 40
41 /** 41 /**
42 * device_bind_by_name: Create a device and bind it to a driver 42 * device_bind_by_name: Create a device and bind it to a driver
43 * 43 *
44 * This is a helper function used to bind devices which do not use device 44 * This is a helper function used to bind devices which do not use device
45 * tree. 45 * tree.
46 * 46 *
47 * @parent: Pointer to device's parent 47 * @parent: Pointer to device's parent
48 * @pre_reloc_only: If true, bind the driver only if its DM_INIT_F flag is set. 48 * @pre_reloc_only: If true, bind the driver only if its DM_INIT_F flag is set.
49 * If false bind the driver always. 49 * If false bind the driver always.
50 * @info: Name and platdata for this device 50 * @info: Name and platdata for this device
51 * @devp: if non-NULL, returns a pointer to the bound device 51 * @devp: if non-NULL, returns a pointer to the bound device
52 * @return 0 if OK, -ve on error 52 * @return 0 if OK, -ve on error
53 */ 53 */
54 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only, 54 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
55 const struct driver_info *info, struct udevice **devp); 55 const struct driver_info *info, struct udevice **devp);
56 56
57 /** 57 /**
58 * device_probe() - Probe a device, activating it 58 * device_probe() - Probe a device, activating it
59 * 59 *
60 * Activate a device so that it is ready for use. All its parents are probed 60 * Activate a device so that it is ready for use. All its parents are probed
61 * first. 61 * first.
62 * 62 *
63 * @dev: Pointer to device to probe 63 * @dev: Pointer to device to probe
64 * @return 0 if OK, -ve on error 64 * @return 0 if OK, -ve on error
65 */ 65 */
66 int device_probe(struct udevice *dev); 66 int device_probe(struct udevice *dev);
67 67
68 /** 68 /**
69 * device_probe() - Probe a child device, activating it 69 * device_probe() - Probe a child device, activating it
70 * 70 *
71 * Activate a device so that it is ready for use. All its parents are probed 71 * Activate a device so that it is ready for use. All its parents are probed
72 * first. The child is provided with parent data if parent_priv is not NULL. 72 * first. The child is provided with parent data if parent_priv is not NULL.
73 * 73 *
74 * @dev: Pointer to device to probe 74 * @dev: Pointer to device to probe
75 * @parent_priv: Pointer to parent data. If non-NULL then this is provided to 75 * @parent_priv: Pointer to parent data. If non-NULL then this is provided to
76 * the child. 76 * the child.
77 * @return 0 if OK, -ve on error 77 * @return 0 if OK, -ve on error
78 */ 78 */
79 int device_probe_child(struct udevice *dev, void *parent_priv); 79 int device_probe_child(struct udevice *dev, void *parent_priv);
80 80
81 /** 81 /**
82 * device_remove() - Remove a device, de-activating it 82 * device_remove() - Remove a device, de-activating it
83 * 83 *
84 * De-activate a device so that it is no longer ready for use. All its 84 * De-activate a device so that it is no longer ready for use. All its
85 * children are deactivated first. 85 * children are deactivated first.
86 * 86 *
87 * @dev: Pointer to device to remove 87 * @dev: Pointer to device to remove
88 * @return 0 if OK, -ve on error (an error here is normally a very bad thing) 88 * @return 0 if OK, -ve on error (an error here is normally a very bad thing)
89 */ 89 */
90 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) 90 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
91 int device_remove(struct udevice *dev); 91 int device_remove(struct udevice *dev);
92 #else 92 #else
93 static inline int device_remove(struct udevice *dev) { return 0; } 93 static inline int device_remove(struct udevice *dev) { return 0; }
94 #endif 94 #endif
95 95
96 /** 96 /**
97 * device_unbind() - Unbind a device, destroying it 97 * device_unbind() - Unbind a device, destroying it
98 * 98 *
99 * Unbind a device and remove all memory used by it 99 * Unbind a device and remove all memory used by it
100 * 100 *
101 * @dev: Pointer to device to unbind 101 * @dev: Pointer to device to unbind
102 * @return 0 if OK, -ve on error 102 * @return 0 if OK, -ve on error
103 */ 103 */
104 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) 104 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
105 int device_unbind(struct udevice *dev); 105 int device_unbind(struct udevice *dev);
106 #else 106 #else
107 static inline int device_unbind(struct udevice *dev) { return 0; } 107 static inline int device_unbind(struct udevice *dev) { return 0; }
108 #endif 108 #endif
109 109
110 /**
111 * device_remove_children() - Stop all device's children
112 * @dev: The device whose children are to be removed
113 * @return 0 on success, -ve on error
114 */
115 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
116 int device_remove_children(struct udevice *dev);
117 #else
118 static inline int device_remove_children(struct udevice *dev) { return 0; }
119 #endif
120
121 /**
122 * device_unbind_children() - Unbind all device's children from the device
123 *
124 * On error, the function continues to unbind all children, and reports the
125 * first error.
126 *
127 * @dev: The device that is to be stripped of its children
128 * @return 0 on success, -ve on error
129 */
130 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
131 int device_unbind_children(struct udevice *dev);
132 #else
133 static inline int device_unbind_children(struct udevice *dev) { return 0; }
134 #endif
135
136 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) 110 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
137 void device_free(struct udevice *dev); 111 void device_free(struct udevice *dev);
138 #else 112 #else
139 static inline void device_free(struct udevice *dev) {} 113 static inline void device_free(struct udevice *dev) {}
140 #endif 114 #endif
141 115
142 /** 116 /**
143 * simple_bus_translate() - translate a bus address to a system address 117 * simple_bus_translate() - translate a bus address to a system address
144 * 118 *
145 * This handles the 'ranges' property in a simple bus. It translates the 119 * This handles the 'ranges' property in a simple bus. It translates the
146 * device address @addr to a system address using this property. 120 * device address @addr to a system address using this property.
147 * 121 *
148 * @dev: Simple bus device (parent of target device) 122 * @dev: Simple bus device (parent of target device)
149 * @addr: Address to translate 123 * @addr: Address to translate
150 * @return new address 124 * @return new address
151 */ 125 */
152 fdt_addr_t simple_bus_translate(struct udevice *dev, fdt_addr_t addr); 126 fdt_addr_t simple_bus_translate(struct udevice *dev, fdt_addr_t addr);
153 127
154 /* Cast away any volatile pointer */ 128 /* Cast away any volatile pointer */
155 #define DM_ROOT_NON_CONST (((gd_t *)gd)->dm_root) 129 #define DM_ROOT_NON_CONST (((gd_t *)gd)->dm_root)
156 #define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root) 130 #define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root)
157 131
158 /* device resource management */ 132 /* device resource management */
159 #ifdef CONFIG_DEVRES 133 #ifdef CONFIG_DEVRES
160 134
161 /** 135 /**
162 * devres_release_probe - Release managed resources allocated after probing 136 * devres_release_probe - Release managed resources allocated after probing
163 * @dev: Device to release resources for 137 * @dev: Device to release resources for
164 * 138 *
165 * Release all resources allocated for @dev when it was probed or later. 139 * Release all resources allocated for @dev when it was probed or later.
166 * This function is called on driver removal. 140 * This function is called on driver removal.
167 */ 141 */
168 void devres_release_probe(struct udevice *dev); 142 void devres_release_probe(struct udevice *dev);
169 143
170 /** 144 /**
171 * devres_release_all - Release all managed resources 145 * devres_release_all - Release all managed resources
172 * @dev: Device to release resources for 146 * @dev: Device to release resources for
173 * 147 *
174 * Release all resources associated with @dev. This function is 148 * Release all resources associated with @dev. This function is
175 * called on driver unbinding. 149 * called on driver unbinding.
176 */ 150 */
177 void devres_release_all(struct udevice *dev); 151 void devres_release_all(struct udevice *dev);
178 152
179 #else /* ! CONFIG_DEVRES */ 153 #else /* ! CONFIG_DEVRES */
180 154
181 static inline void devres_release_probe(struct udevice *dev) 155 static inline void devres_release_probe(struct udevice *dev)
182 { 156 {
183 } 157 }
184 158
185 static inline void devres_release_all(struct udevice *dev) 159 static inline void devres_release_all(struct udevice *dev)
186 { 160 {
187 } 161 }
188 162
189 #endif /* ! CONFIG_DEVRES */ 163 #endif /* ! CONFIG_DEVRES */
190 #endif 164 #endif
191 165