2 * driver.c - barebox driver model
4 * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
6 * See file CREDITS for list of people who contributed to this
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2
11 * as published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * @brief barebox's driver model, and devinfo command
32 #include <linux/ctype.h>
35 #include <linux/list.h>
37 LIST_HEAD(device_list
);
38 EXPORT_SYMBOL(device_list
);
40 LIST_HEAD(driver_list
);
41 EXPORT_SYMBOL(driver_list
);
43 static LIST_HEAD(active
);
45 struct device_d
*get_device_by_name(const char *name
)
48 char devname
[MAX_DRIVER_NAME
+ 3];
50 for_each_device(dev
) {
51 sprintf(devname
, "%s%d", dev
->name
, dev
->id
);
52 if(!strcmp(name
, devname
))
59 int get_free_deviceid(const char *name_template
)
62 char name
[MAX_DRIVER_NAME
+ 3];
65 sprintf(name
, "%s%d", name_template
, i
);
66 if (!get_device_by_name(name
))
72 static int match(struct driver_d
*drv
, struct device_d
*dev
)
79 if (dev
->bus
!= drv
->bus
)
81 if (dev
->bus
->match(dev
, drv
))
83 if (dev
->bus
->probe(dev
))
86 list_add(&dev
->active
, &active
);
94 int register_device(struct device_d
*new_device
)
98 new_device
->id
= get_free_deviceid(new_device
->name
);
100 debug ("register_device: %s\n",new_device
->name
);
102 if (!new_device
->bus
) {
103 // dev_err(new_device, "no bus type associated. Needs fixup\n");
104 new_device
->bus
= &platform_bus
;
107 list_add_tail(&new_device
->list
, &device_list
);
108 INIT_LIST_HEAD(&new_device
->children
);
109 INIT_LIST_HEAD(&new_device
->cdevs
);
110 INIT_LIST_HEAD(&new_device
->parameters
);
112 for_each_driver(drv
) {
113 if (!match(drv
, new_device
))
119 EXPORT_SYMBOL(register_device
);
121 int unregister_device(struct device_d
*old_dev
)
123 debug("unregister_device: %s:%s\n",old_dev
->name
, old_dev
->id
);
125 if (!list_empty(&old_dev
->children
)) {
131 old_dev
->bus
->remove(old_dev
);
133 list_del(&old_dev
->list
);
135 /* remove device from parents child list */
137 list_del(&old_dev
->sibling
);
141 EXPORT_SYMBOL(unregister_device
);
143 int dev_add_child(struct device_d
*dev
, struct device_d
*child
)
147 list_add_tail(&child
->sibling
, &dev
->children
);
151 EXPORT_SYMBOL(dev_add_child
);
153 struct driver_d
*get_driver_by_name(const char *name
)
155 struct driver_d
*drv
;
157 for_each_driver(drv
) {
158 if(!strcmp(name
, drv
->name
))
165 static void noinfo(struct device_d
*dev
)
167 printf("no info available for %s\n", dev
->name
);
170 static void noshortinfo(struct device_d
*dev
)
174 int register_driver(struct driver_d
*drv
)
176 struct device_d
*dev
= NULL
;
178 debug("register_driver: %s\n", drv
->name
);
181 // pr_err("driver %s has no bus type associated. Needs fixup\n", drv->name);
182 drv
->bus
= &platform_bus
;
185 list_add_tail(&drv
->list
, &driver_list
);
190 drv
->shortinfo
= noshortinfo
;
197 EXPORT_SYMBOL(register_driver
);
199 int dev_protect(struct device_d
*dev
, size_t count
, unsigned long offset
, int prot
)
201 printf("%s: currently broken\n", __func__
);
205 int generic_memmap_ro(struct cdev
*cdev
, void **map
, int flags
)
210 if (flags
& PROT_WRITE
)
212 *map
= (void *)cdev
->dev
->map_base
;
216 int generic_memmap_rw(struct cdev
*cdev
, void **map
, int flags
)
221 *map
= (void *)cdev
->dev
->map_base
;
225 int dummy_probe(struct device_d
*dev
)
229 EXPORT_SYMBOL(dummy_probe
);
231 static int do_devinfo_subtree(struct device_d
*dev
, int depth
, char edge
)
233 struct device_d
*child
;
237 for (i
= 0; i
< depth
; i
++)
240 printf("%c----%s%d", edge
, dev
->name
, dev
->id
);
241 if (!list_empty(&dev
->cdevs
)) {
243 list_for_each_entry(cdev
, &dev
->cdevs
, devices_list
) {
244 printf("%s", cdev
->name
);
245 if (!list_is_last(&cdev
->devices_list
, &dev
->cdevs
))
252 if (!list_empty(&dev
->children
)) {
253 device_for_each_child(dev
, child
) {
254 do_devinfo_subtree(child
, depth
+ 1,
255 list_is_last(&child
->sibling
,
256 &dev
->children
) ? '`' : '|');
263 const char *dev_id(const struct device_d
*dev
)
265 static char buf
[sizeof(unsigned long) * 2];
267 sprintf(buf
, "%s%d", dev
->name
, dev
->id
);
272 void devices_shutdown(void)
274 struct device_d
*dev
;
276 list_for_each_entry(dev
, &active
, active
) {
277 if (dev
->driver
->remove
)
278 dev
->driver
->remove(dev
);
282 #ifdef CONFIG_CMD_DEVINFO
284 static int do_devinfo(struct command
*cmdtp
, int argc
, char *argv
[])
286 struct device_d
*dev
;
287 struct driver_d
*drv
;
288 struct param_d
*param
;
291 printf("devices:\n");
293 for_each_device(dev
) {
295 do_devinfo_subtree(dev
, 0, '|');
298 printf("\ndrivers:\n");
300 printf("%10s\n",drv
->name
);
302 struct device_d
*dev
= get_device_by_name(argv
[1]);
305 printf("no such device: %s\n",argv
[1]);
309 printf("base : 0x%08x\nsize : 0x%08x\ndriver: %s\n\n",
310 dev
->map_base
, dev
->size
,
312 dev
->driver
->name
: "none");
315 dev
->driver
->info(dev
);
317 printf("%s\n", list_empty(&dev
->parameters
) ?
318 "no parameters available" : "Parameters:");
320 list_for_each_entry(param
, &dev
->parameters
, list
)
321 printf("%16s = %s\n", param
->name
, param
->value
);
327 static const __maybe_unused
char cmd_devinfo_help
[] =
328 "Usage: devinfo [DEVICE]\n"
329 "If called without arguments devinfo shows a summary about known devices and\n"
330 "drivers. If called with a device path as argument devinfo shows more detailed\n"
331 "information about this device and its parameters.\n";
333 BAREBOX_CMD_START(devinfo
)
335 .usage
= "display info about devices and drivers",
336 BAREBOX_CMD_HELP(cmd_devinfo_help
)
342 * @page devinfo_command devinfo
344 * Usage is: devinfo /dev/\<device>
346 * If called without arguments devinfo shows a summary about known devices and
347 * drivers. If called with a device path as argument devinfo shows more
348 * detailed information about this device and its parameters.
350 * Example from an MPC5200 based system:
352 barebox:/ devinfo /dev/eth0
357 no info available for eth0
359 ipaddr = 192.168.23.197
360 ethaddr = 80:81:82:83:84:86
361 gateway = 192.168.23.1
362 netmask = 255.255.255.0
363 serverip = 192.168.23.2