Patchwork [U-Boot,6/7] dm: add dummy demo driver and core

login
register
mail settings
Submitter Marek Vasut
Date Aug. 21, 2012, 4 p.m.
Message ID <1345564853-24500-7-git-send-email-marex@denx.de>
Download mbox | patch
Permalink /patch/179093/
State Deferred
Headers show

Comments

Marek Vasut - Aug. 21, 2012, 4 p.m.
From: Pavel Herrmann <morpheus.ibis@gmail.com>

Signed-off-by: Pavel Herrmann <morpheus.ibis@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

Patch

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.ibis@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.ibis@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.ibis@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