Re: [Tinyx-devel] [PATCH] Device subsystem improvements.
Status: Planning
Brought to you by:
davidcohen
From: Felipe B. <me...@fe...> - 2007-12-11 23:22:44
|
On Tue, 11 Dec 2007 19:08:23 -0400, David Cohen <da...@gm...> wrote: > This patch updates the device subsystem: > - implements the register_* on device.c > - code cleanups on device.h > - adding ioctl on bus > > Signed-off-by: David Cohen <da...@gm...> Acked-by: Felipe Balbi <me...@fe...> > --- > include/tinyx/device.h | 27 ++++++++++----- > kernel/device.c | 89 > ++++++++++++++++++++++++++++++++++++++++++++++-- > 2 files changed, 104 insertions(+), 12 deletions(-) > > diff --git a/include/tinyx/device.h b/include/tinyx/device.h > index b5de65a..2916925 100644 > --- a/include/tinyx/device.h > +++ b/include/tinyx/device.h > @@ -1,6 +1,8 @@ > #ifndef __TINYX_DEVICE_H > #define __TINYX_DEVICE_H > > +#include <tinyx/list.h> > + > struct bus_type; > struct device_driver; > struct device; > @@ -22,26 +24,33 @@ struct resource { > }; > > struct bus_type { > - struct list_head *head; > - const char *name; > - int id; > + struct list_head queue; > + unsigned int type; > void *private_data; > > int (*probe) (struct bus_type *bus); > int (*remove) (struct bus_type *bus); > - int (*match) (struct device *dev, struct device_driver *drv); > + int (*match) (struct bus_type *bus, > + struct device *dev, struct device_driver *drv); > > - void (*writeb) (struct device *dev, unsigned char val, unsigned long addr); > - void (*writew) (struct device *dev, unsigned int val, unsigned long addr); > - void (*writel) (struct device *dev, unsigned long val, unsigned long addr); > + /* These write* and read* exists in order to avoid if's > + * inside critial buses. */ > + void (*writeb) (struct device *dev, > + unsigned char val, unsigned long addr); > + void (*writew) (struct device *dev, > + unsigned int val, unsigned long addr); > + void (*writel) (struct device *dev, > + unsigned long val, unsigned long addr); > > unsigned char (*readb) (struct device *dev, unsigned long addr); > unsigned int (*readw) (struct device *dev, unsigned long addr); > unsigned long (*readl) (struct device *dev, unsigned long addr); > + > + void (*ioctl) (struct device *dev, void *data, int type); > }; > > struct device_driver { > - struct list_head *head; > + struct list_head queue; > const char *name; > > int (*probe) (struct device *dev); > @@ -49,7 +58,7 @@ struct device_driver { > }; > > struct device { > - struct list_head *head; > + struct list_head queue; > const char *name; > int id; > struct device_driver *drv; > diff --git a/kernel/device.c b/kernel/device.c > index 0b11433..a7baeb1 100644 > --- a/kernel/device.c > +++ b/kernel/device.c > @@ -1,16 +1,99 @@ > #include <tinyx/device.h> > +#include <tinyx/list.h> > +#include <tinyx/libc/string.h> > + > +DECLARE_LIST_HEAD(bus_list); > +DECLARE_LIST_HEAD(driver_list); > +DECLARE_LIST_HEAD(device_list); > + > +static void *match_device_driver(struct device *dev, struct device_driver > *drv) > +{ > + struct list_head *list; > + struct list_head *entry; > + void *item; > + int ret; > + > + if (!dev) > + list = &device_list; > + else > + list = &driver_list; > + > + list_for_each(list, entry) { > + if (!dev) { > + item = list_entry(entry, struct device, queue); > + ret = strcmp(((struct device *)item)->name, drv->name); > + } else { > + item = list_entry(entry, struct device_driver, queue); > + ret = strcmp(dev->name, > + ((struct device_driver *)item)->name); > + } > + if (!ret) > + break; > + else > + item = NULL; > + } > + > + return item; > +} > > int register_bus_type(struct bus_type *bus) > { > - return 0; > + int ret = 0; > + > + if (bus == NULL) > + return -ENODEV; > + > + if (bus->probe) > + ret = bus->probe(bus); > + if (!ret) > + list_add_tail(&bus_list, &bus->queue); > + > + return ret; > } > > int register_device_driver(struct device_driver *drv) > { > - return 0; > + int ret = 0; > + struct device *dev; > + > + if (drv == NULL) > + return -ENODEV; > + > + dev = match_device_driver(NULL, drv); > + if (dev) { > + if (dev->bus->match) > + ret = dev->bus->match(dev->bus, dev, drv); > + if (!ret && drv->probe) > + ret = drv->probe(dev); > + } > + > + if (!ret) > + list_add_tail(&driver_list, &drv->queue); > + > + return ret; > } > > int register_device(struct device *dev, struct bus_type *bus) > { > - return 0; > + int ret = 0; > + struct device_driver *drv; > + > + if (dev == NULL) > + return -ENODEV; > + > + dev->bus = bus; > + drv = match_device_driver(dev, NULL); > + if (drv) { > + if (bus->match) > + ret = bus->match(bus, dev, drv); > + if (!ret && drv->probe) > + ret = drv->probe(dev); > + } > + > + if (!ret) > + list_add_tail(&device_list, &dev->queue); > + else > + dev->bus = NULL; > + > + return ret; > } > -- > 1.5.3.5 > > > ------------------------------------------------------------------------- > SF.Net email is sponsored by: > Check out the new SourceForge.net Marketplace. > It's the best place to buy or sell services for > just about anything Open Source. > http://sourceforge.net/services/buy/index.php > _______________________________________________ > Tinyx-devel mailing list > Tin...@li... > https://lists.sourceforge.net/lists/listinfo/tinyx-devel -- Best Regards, Felipe Balbi http://felipebalbi.com me...@fe... |