From: Pavel Herrmann <morpheus.i...@gmail.com> Signed-off-by: Pavel Herrmann <morpheus.i...@gmail.com> --- Makefile | 1 + drivers/demo/Makefile | 42 ++++++++ drivers/demo/core.c | 236 +++++++++++++++++++++++++++++++++++++++++++ drivers/demo/demo.c | 67 ++++++++++++ include/dm/core_numbering.h | 1 + include/dm/demo.h | 37 +++++++ 6 files changed, 384 insertions(+) create mode 100644 drivers/demo/Makefile create mode 100644 drivers/demo/core.c create mode 100644 drivers/demo/demo.c create mode 100644 include/dm/demo.h
diff --git a/Makefile b/Makefile index 0e008b1..ba74696 100644 --- a/Makefile +++ b/Makefile @@ -302,6 +302,7 @@ LIBS-y += post/libpost.o LIBS-y += test/libtest.o LIBS-$(CONFIG_DM) += common/dm/libdm.o +LIBS-$(CONFIG_DM) += drivers/demo/libdemo.o ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) LIBS-y += $(CPUDIR)/omap-common/libomap-common.o diff --git a/drivers/demo/Makefile b/drivers/demo/Makefile new file mode 100644 index 0000000..192bd7d --- /dev/null +++ b/drivers/demo/Makefile @@ -0,0 +1,42 @@ +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libdemo.o + +COBJS-y += demo.o core.o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/drivers/demo/core.c b/drivers/demo/core.c new file mode 100644 index 0000000..1e6684b --- /dev/null +++ b/drivers/demo/core.c @@ -0,0 +1,236 @@ +/* + * (C) Copyright 2012 + * Pavel Herrmann <morpheus.i...@gmail.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <malloc.h> +#include <dm/manager.h> +#include <dm/demo.h> +#include <linux/list.h> + +struct demo_core_entry { + struct list_head list; + struct instance *instance; + struct demo_ops *ops; +}; + +static struct demo_ops *get_ops(struct instance *inst) +{ + struct core_instance *core = NULL; + struct demo_core_entry *tmp; + + if (!inst) + return NULL; + + core = get_core_instance(CORE_DEMO); + if (!core) + /* something has gone terribly wrong here...*/ + return NULL; + + list_for_each_entry(tmp, &core->succ, list) { + if (tmp->instance == inst) + return tmp->ops; + } + + return NULL; +} + +static int demo_core_get_count(struct core_instance *core) +{ + struct demo_core_entry *tmp; + int i = 0; + + list_for_each_entry(tmp, &core->succ, list) + i++; + + return i; +} + +static struct instance *demo_core_get_child(struct core_instance *core, int idx) +{ + struct demo_core_entry *tmp; + int i = 0; + + list_for_each_entry(tmp, &core->succ, list) { + if (i == idx) + return tmp->instance; + i++; + } + + return NULL; +} + +static int demo_core_bind(struct core_instance *core, struct instance *dev, + void *ops, void *data) +{ + struct demo_core_entry *entry; + + if (data || !ops) + return -EINVAL; + + entry = malloc(sizeof(*entry)); + if (!entry) + return -ENOMEM; + + INIT_LIST_HEAD(&entry->list); + entry->instance = dev; + entry->ops = ops; + + list_add_tail(&entry->list, &core->succ); + return 0; +} + +static int demo_core_unbind(struct core_instance *core, struct instance *dev) +{ + struct demo_core_entry *tmp, *n; + + if (!dev) + return -EINVAL; + + list_for_each_entry_safe(tmp, n, &core->succ, list) { + if (tmp->instance == dev) { + list_del(&tmp->list); + free(tmp); + } + } + + return 0; +} + +static int demo_core_replace(struct core_instance *core, struct instance *new, + struct instance *old) +{ + struct demo_core_entry *tmp, *n; + + if (!new || !old) + return -EINVAL; + + list_for_each_entry_safe(tmp, n, &core->succ, list) + if (tmp->instance == old) + tmp->instance = new; + + return 0; +} + +static int demo_core_init(struct core_instance *core) +{ + core->private_data = NULL; + INIT_LIST_HEAD(&core->succ); + return 0; +} + +static int demo_core_reloc(struct core_instance *new, struct core_instance *old) +{ + /* no relocation at this point */ + return 0; +} + +static int demo_core_destroy(struct core_instance *core) +{ + /* no destruction at this point */ + return 0; +} + +U_BOOT_CORE(CORE_DEMO, + demo_core_init, + demo_core_reloc, + demo_core_destroy, + demo_core_get_count, + demo_core_get_child, + demo_core_bind, + demo_core_unbind, + demo_core_replace); + + +/* Driver API */ + +int demo_hello(struct instance *i) +{ + struct demo_ops *device_ops = NULL; + int status; + + device_ops = get_ops(i); + if (!device_ops) + return -ENOENT; + + status = driver_activate(i); + if (status != 0) + return status; + + if (device_ops->hello) + return device_ops->hello(i); + else + return 0; +} + + +/* Command API */ + +int demo_list(void) +{ + struct core_instance *core = NULL; + struct demo_core_entry *tmp = NULL; + int i = 0; + + core = get_core_instance(CORE_DEMO); + if (!core) + return -ENOMEM; + + puts("Demo core entries:\n"); + + list_for_each_entry(tmp, &core->succ, list) + printf("entry %d - instance 0x%p with ops 0x%p\n", + i++, tmp->instance, tmp->ops); + + return 0; +} + +static int do_demo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct instance *dev; + int devnum = 0; + + switch (argc) { + case 2: + if (!strncmp(argv[1], "list", 4)) + return demo_list(); + break; + case 3: + if (!strncmp(argv[1], "call", 4)) + devnum = simple_strtoul(argv[2], NULL, 10); + dev = core_get_child(CORE_DEMO, devnum); + if (!dev) { + puts("device not found"); + return -EINVAL; + } else + return demo_hello(dev); + break; + } + + return -EINVAL; +} + +U_BOOT_CMD( + demo, 3, 1, do_demo, + "dm demo core ops\n", + "list\n" + "call <num>\n" +); diff --git a/drivers/demo/demo.c b/drivers/demo/demo.c new file mode 100644 index 0000000..d8610bd --- /dev/null +++ b/drivers/demo/demo.c @@ -0,0 +1,67 @@ +/* + * (C) Copyright 2012 + * Pavel Herrmann <morpheus.i...@gmail.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <dm/demo.h> +#include <dm/manager.h> + +static int hello(struct instance *dev) +{ + printf("hello from %p\n", dev); + return 0; +} + +static struct demo_ops ops = { + .hello = hello, +}; + +static int bind(struct instance *dev) +{ + printf("bind from %p\n", dev); + return core_bind(CORE_DEMO, dev, &ops, NULL); +} + +static int probe(struct instance *dev) +{ + printf("probe from %p\n", dev); + return 0; +} + +static int reloc(struct instance *new, struct instance *old) +{ + printf("reloc from %p to %p\n", old, new); + return 0; +} + +static int remove(struct instance *dev) +{ + printf("remove from %p\n", dev); + return 0; +} + +static int unbind(struct instance *dev) +{ + printf("unbind from %p\n", dev); + return core_unbind(CORE_DEMO, dev); +} + +U_BOOT_DRIVER(demo_drv, bind, probe, reloc, remove, unbind); diff --git a/include/dm/core_numbering.h b/include/dm/core_numbering.h index b543b48..8dd6067 100644 --- a/include/dm/core_numbering.h +++ b/include/dm/core_numbering.h @@ -29,6 +29,7 @@ enum core_id { CORE_INVALID = 0, CORE_GPIO, + CORE_DEMO, }; #endif diff --git a/include/dm/demo.h b/include/dm/demo.h new file mode 100644 index 0000000..9fca7b8 --- /dev/null +++ b/include/dm/demo.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2012 + * Pavel Herrmann <morpheus.i...@gmail.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _DM_DEMO_H_ +#define _DM_DEMO_H_ 1 + +#include <dm/options.h> +#include <dm/structures.h> + +struct demo_ops { + int (*hello)(struct instance *i); +}; + +int demo_hello(struct instance *i); +int demo_list(void); + +#endif -- 1.7.10.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot