diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2007-10-11 20:20:36 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2007-10-11 20:20:36 +0200 |
commit | eadf71abc77bf97cf5aa7dbe206f4778c4b2480d (patch) | |
tree | b777f0f97d094c836300b11cc390ce10678dd417 | |
parent | 29fc9471f5b0f18df699f8e47c5a1fbeb5398e9e (diff) | |
download | barebox-eadf71abc77bf97cf5aa7dbe206f4778c4b2480d.tar.gz barebox-eadf71abc77bf97cf5aa7dbe206f4778c4b2480d.tar.xz |
Use Linux kernel list for drivers and devices instead of handmade
list.
-rw-r--r-- | arch/arm/lib/armlinux.c | 19 | ||||
-rw-r--r-- | board/phycore_pcm038/lowlevel_init.S | 16 | ||||
-rw-r--r-- | fs/devfs.c | 20 | ||||
-rw-r--r-- | include/driver.h | 12 | ||||
-rw-r--r-- | lib/driver.c | 194 |
5 files changed, 100 insertions, 161 deletions
diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c index c80a6832df..f4bb814a60 100644 --- a/arch/arm/lib/armlinux.c +++ b/arch/arm/lib/armlinux.c @@ -163,19 +163,16 @@ static void setup_memory_tags (void) { struct device_d *dev = NULL; - while (1) { - dev = get_device_by_type(DEVICE_TYPE_DRAM, dev); + list_for_each_entry(dev, &device_list, list) { + if (dev->type == DEVICE_TYPE_DRAM) { + params->hdr.tag = ATAG_MEM; + params->hdr.size = tag_size (tag_mem32); - if (!dev) - return; + params->u.mem.start = dev->map_base; + params->u.mem.size = dev->size; - params->hdr.tag = ATAG_MEM; - params->hdr.size = tag_size (tag_mem32); - - params->u.mem.start = dev->map_base; - params->u.mem.size = dev->size; - - params = tag_next (params); + params = tag_next (params); + } } } #endif /* CONFIG_SETUP_MEMORY_TAGS */ diff --git a/board/phycore_pcm038/lowlevel_init.S b/board/phycore_pcm038/lowlevel_init.S index 17f3ad3bd8..d12e4db451 100644 --- a/board/phycore_pcm038/lowlevel_init.S +++ b/board/phycore_pcm038/lowlevel_init.S @@ -30,8 +30,9 @@ lowlevel_init: writel(0x04082008, SPCTL0) writel(0x33f00304, CSCR) - writel(0x33f00304 | CSCR_MPEN | CSCR_SPEN | CSCR_MCU_SEL | - CSCR_SP_SEL | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART, + writel(0x33f00300 | CSCR_FPM_EN | CSCR_MPEN | CSCR_SPEN | CSCR_MCU_SEL | + CSCR_SP_SEL | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART | + 0 , CSCR) /* add some delay here */ @@ -39,6 +40,11 @@ lowlevel_init: 1: subs r1, r1, #0x1 bne 1b + writel(0x33f00300 | CSCR_FPM_EN | CSCR_MPEN | CSCR_SPEN | CSCR_MCU_SEL | + CSCR_SP_SEL | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART | + CSCR_ARM_SRC_MPLL, + CSCR) + writel(0x00070f08, GPCR) writel(0x130410c3, PCDR0) @@ -50,6 +56,9 @@ lowlevel_init: cmp pc, #0xc0000000 bhi 1f + mov pc,r10 + +1: /* * DDR on CSD0 */ @@ -81,5 +90,6 @@ lowlevel_init: mov r1, #0x0 strb r1, [r0] writel(0x82126080, 0xD8001000) -1: + mov pc,r10 + diff --git a/fs/devfs.c b/fs/devfs.c index cc8a9d0542..10c2dfeab6 100644 --- a/fs/devfs.c +++ b/fs/devfs.c @@ -27,6 +27,7 @@ #include <fs.h> #include <command.h> #include <errno.h> +#include <xfuncs.h> #include <linux/stat.h> static int devfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size) @@ -92,11 +93,10 @@ static DIR* devfs_opendir(struct device_d *dev, const char *pathname) { DIR *dir; - dir = malloc(sizeof(DIR)); - if (!dir) - return NULL; + dir = xzalloc(sizeof(DIR)); - dir->priv = get_first_device(); + if (!list_empty(&device_list)) + dir->priv = list_first_entry(&device_list, struct device_d, list); return dir; } @@ -105,12 +105,16 @@ static struct dirent* devfs_readdir(struct device_d *_dev, DIR *dir) { struct device_d *dev = dir->priv; - while (dev && (!strlen(dev->id) || !dev->driver)) - dev = dev->next; + if (!dev) + return NULL; - if (dev) { + list_for_each_entry_from(dev, &device_list, list) { + if (!*dev->id) + continue; + if (!dev->driver) + continue; strcpy(dir->d.d_name, dev->id); - dir->priv = dev->next; + dir->priv = list_entry(dev->list.next, struct device_d, list); return &dir->d; } return NULL; diff --git a/include/driver.h b/include/driver.h index 293a265045..e1b344cfe3 100644 --- a/include/driver.h +++ b/include/driver.h @@ -1,6 +1,8 @@ #ifndef DRIVER_H #define DRIVER_H +#include <list.h> + #define MAX_DRIVER_NAME 16 #define DEVICE_TYPE_UNKNOWN 0 @@ -35,7 +37,7 @@ struct device_d { struct driver_d *driver; /* The driver for this device */ - struct device_d *next; + struct list_head list; unsigned long type; @@ -46,7 +48,7 @@ struct driver_d { char name[MAX_DRIVER_NAME]; /* The name of this driver. Used to match to * the corresponding device. */ - struct driver_d *next; + struct list_head list; int (*probe) (struct device_d *); int (*remove)(struct device_d *); @@ -93,6 +95,12 @@ int get_free_deviceid(char *id, char *id_template); struct device_d *device_from_spec_str(const char *str, char **endp); char *deviceid_from_spec_str(const char *str, char **endp); +extern struct list_head device_list; +#define for_each_device(dev) list_for_each_entry(dev, &device_list, list) + +extern struct list_head driver_list; +#define for_each_driver(drv) list_for_each_entry(drv, &driver_list, list) + /* Find a driver with the given name. Currently the filesystem implementation * uses this to get the driver from the name the user specifies with the * mount command diff --git a/lib/driver.c b/lib/driver.c index 75ee912a34..f801007406 100644 --- a/lib/driver.c +++ b/lib/driver.c @@ -27,35 +27,24 @@ #include <linux/ctype.h> #include <errno.h> #include <fs.h> +#include <list.h> -static struct device_d *first_device = NULL; -static struct driver_d *first_driver = NULL; +LIST_HEAD(device_list); +EXPORT_SYMBOL(device_list); -struct device_d *get_first_device(void) -{ - return first_device; -} +LIST_HEAD(driver_list); +EXPORT_SYMBOL(driver_list); -struct device_d *get_device_by_id(const char *_id) +struct device_d *get_device_by_id(const char *id) { - struct device_d *d; - char *id, *colon; - - /* FIXME: is this still needed? */ - id = strdup(_id); - if ((colon = strchr(id, ':'))) - *colon = 0; - - d = first_device; + struct device_d *dev; - while(d) { - if(!strcmp(id, d->id)) - break; - d = d->next; + for_each_device(dev) { + if(!strcmp(id, dev->id)) + return dev; } - free(id); - return d; + return NULL; } int get_free_deviceid(char *id, char *id_template) @@ -89,9 +78,6 @@ static int match(struct driver_d *drv, struct device_d *dev) int register_device(struct device_d *new_device) { struct driver_d *drv; - struct device_d *dev; - - dev = first_device; if(*new_device->id && get_device_by_id(new_device->id)) { printf("device %s already exists\n", new_device->id); @@ -99,23 +85,11 @@ int register_device(struct device_d *new_device) } debug ("register_device: %s\n",new_device->name); - if(!dev) { - first_device = new_device; - dev = first_device; - } else { - while(dev->next) - dev = dev->next; - } - - dev->next = new_device; - new_device->next = 0; + list_add_tail(&new_device->list, &device_list); - drv = first_driver; - - while(drv) { + for_each_driver(drv) { if (!match(drv, new_device)) break; - drv = drv->next; } return 0; @@ -124,37 +98,25 @@ EXPORT_SYMBOL(register_device); void unregister_device(struct device_d *old_dev) { - struct device_d *dev; - debug("unregister_device: %s:%s\n",old_dev->name, old_dev->id); - dev = first_device; + if (old_dev->driver) + old_dev->driver->remove(old_dev); - while (dev) { - if (dev->next == old_dev) { - if (old_dev->driver) - old_dev->driver->remove(old_dev); - dev->next = old_dev->next; - return; - } - dev = dev->next; - } + list_del(&old_dev->list); } EXPORT_SYMBOL(unregister_device); struct driver_d *get_driver_by_name(const char *name) { - struct driver_d *d; - - d = first_driver; + struct driver_d *drv; - while(d) { - if(!strcmp(name, d->name)) - break; - d = d->next; + for_each_driver(drv) { + if(!strcmp(name, drv->name)) + return drv; } - return d; + return NULL; } static void noinfo(struct device_d *dev) @@ -166,36 +128,21 @@ static void noshortinfo(struct device_d *dev) { } -int register_driver(struct driver_d *new_driver) +int register_driver(struct driver_d *drv) { - struct driver_d *drv; struct device_d *dev = NULL; - drv = first_driver; - debug("register_driver: %s\n",new_driver->name); - if(!drv) { - first_driver = new_driver; - drv = first_driver; - } else { - while(drv->next) - drv = drv->next; - } + list_add_tail(&drv->list, &driver_list); - drv->next = new_driver; - new_driver->next = 0; + if (!drv->info) + drv->info = noinfo; + if (!drv->shortinfo) + drv->shortinfo = noshortinfo; - if (!new_driver->info) - new_driver->info = noinfo; - if (!new_driver->shortinfo) - new_driver->shortinfo = noshortinfo; - - dev = first_device; - while (dev) { - match(new_driver, dev); - dev = dev->next; - } + for_each_device(dev) + match(drv, dev); return 0; } @@ -248,30 +195,6 @@ struct device_d *device_from_spec_str(const char *str, char **endp) return get_device_by_id(name); } -/* Get devices from their type. - * If last is NULL the first device of this type is given. - * If last is not NULL, the next device of this type starting - * from last is given. - */ -struct device_d *get_device_by_type(ulong type, struct device_d *last) -{ - struct device_d *dev; - - if (!last) - dev = first_device; - else - dev = last->next; - - while (dev) { - if (dev->type == type) - return dev; - dev = dev->next; - } - - return NULL; -} -EXPORT_SYMBOL(get_device_by_type); - ssize_t dev_read(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags) { if (dev->driver->read) @@ -333,50 +256,47 @@ int dummy_probe(struct device_d *dev) static int do_devinfo ( cmd_tbl_t *cmdtp, int argc, char *argv[]) { - struct device_d *dev = first_device; - struct driver_d *drv = first_driver; - struct param_d *param; + struct device_d *dev; + struct driver_d *drv; + struct param_d *param; - if (argc == 1) { - printf("devices:\n"); + if (argc == 1) { + printf("devices:\n"); - while(dev) { - printf("%10s: base=0x%08x size=0x%08x (driver %s)\n", - dev->id, dev->map_base, dev->size, + for_each_device(dev) { + printf("%10s: base=0x%08x size=0x%08x (driver %s)\n", + dev->id, dev->map_base, dev->size, dev->driver ? dev->driver->name : "none"); - dev = dev->next; - } - - printf("drivers:\n"); - while(drv) { - printf("%10s\n",drv->name); - drv = drv->next; - } - } else { - struct device_d *dev = get_device_by_id(argv[1]); + } + + printf("\ndrivers:\n"); + for_each_driver(drv) + printf("%10s\n",drv->name); + } else { + struct device_d *dev = get_device_by_id(argv[1]); - if (!dev) { - printf("no such device: %s\n",argv[1]); - return -1; - } + if (!dev) { + printf("no such device: %s\n",argv[1]); + return -1; + } - if (dev->driver) - dev->driver->info(dev); + if (dev->driver) + dev->driver->info(dev); - param = dev->param; + param = dev->param; - printf("%s\n", param ? + printf("%s\n", param ? "Parameters:" : "no parameters available"); - while (param) { + while (param) { printf("%16s = %s\n", param->name, param->value); - param = param->next; - } + param = param->next; + } - } + } - return 0; + return 0; } static __maybe_unused char cmd_devinfo_help[] = |