aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Grall <julien.grall@linaro.org>2013-04-26 20:14:50 +0100
committerIan Campbell <ian.campbell@citrix.com>2013-05-13 11:59:59 +0100
commit23045cfe5099a0ff211b31b69073d907f2f221fd (patch)
treeb8f638ffe7b43e56c2d9885709e1c4d1a80f3676
parent95edff23232dbc94761d7e956669723ffb5c69bc (diff)
downloadxen-23045cfe5099a0ff211b31b69073d907f2f221fd.tar.gz
xen-23045cfe5099a0ff211b31b69073d907f2f221fd.tar.bz2
xen-23045cfe5099a0ff211b31b69073d907f2f221fd.zip
xen/arm: Introduce a generic way to use a device from the device tree
Signed-off-by: Julien Grall <julien.grall@linaro.org> Acked-by: Ian Campbell <ian.campbell@citrix.com>
-rw-r--r--xen/arch/arm/Makefile1
-rw-r--r--xen/arch/arm/device.c74
-rw-r--r--xen/arch/arm/xen.lds.S7
-rw-r--r--xen/include/asm-arm/device.h52
4 files changed, 134 insertions, 0 deletions
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 8f75044c9d..4955a2123c 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -28,6 +28,7 @@ obj-y += vgic.o
obj-y += vtimer.o
obj-y += vpl011.o
obj-y += hvm.o
+obj-y += device.o
#obj-bin-y += ....o
diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
new file mode 100644
index 0000000000..dc751a979a
--- /dev/null
+++ b/xen/arch/arm/device.c
@@ -0,0 +1,74 @@
+/*
+ * xen/arch/arm/device.c
+ *
+ * Helpers to use a device retrieved via the device tree.
+ *
+ * Julien Grall <julien.grall@linaro.org>
+ * Copyright (C) 2013 Linaro Limited.
+ *
+ * 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.
+ */
+
+#include <asm/device.h>
+#include <xen/errno.h>
+#include <xen/lib.h>
+
+extern const struct device_desc _sdevice[], _edevice[];
+
+static bool_t __init device_is_compatible(const struct device_desc *desc,
+ const struct dt_device_node *dev)
+{
+ const char *const *compat;
+
+ if ( !desc->compatible )
+ return 0;
+
+ for ( compat = desc->compatible; *compat; compat++ )
+ {
+ if ( dt_device_is_compatible(dev, *compat) )
+ return 1;
+ }
+
+ return 0;
+}
+
+int __init device_init(struct dt_device_node *dev, enum device_type type,
+ const void *data)
+{
+ const struct device_desc *desc;
+
+ ASSERT(dev != NULL);
+
+ for ( desc = _sdevice; desc != _edevice; desc++ )
+ {
+ if ( desc->type != type )
+ continue;
+
+ if ( device_is_compatible(desc, dev) )
+ {
+ ASSERT(desc->init != NULL);
+
+ return desc->init(dev, data);
+ }
+
+ }
+
+ return -EBADF;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S
index fd755d7437..deab040972 100644
--- a/xen/arch/arm/xen.lds.S
+++ b/xen/arch/arm/xen.lds.S
@@ -76,6 +76,13 @@ SECTIONS
__lock_profile_end = .;
#endif
+ . = ALIGN(8);
+ .dev.info : {
+ _sdevice = .;
+ *(.dev.info)
+ _edevice = .;
+ } :text
+
. = ALIGN(PAGE_SIZE); /* Init code and data */
__init_begin = .;
.init.text : {
diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h
new file mode 100644
index 0000000000..9e47ca6362
--- /dev/null
+++ b/xen/include/asm-arm/device.h
@@ -0,0 +1,52 @@
+#ifndef __ASM_ARM_DEVICE_H
+#define __ASM_ARM_DEVICE_H
+
+#include <xen/init.h>
+#include <xen/device_tree.h>
+
+enum device_type
+{
+ DEVICE_SERIAL
+};
+
+struct device_desc {
+ /* Device name */
+ const char *name;
+ /* Device type */
+ enum device_type type;
+ /* Array of device tree 'compatible' strings */
+ const char *const *compatible;
+ /* Device initialization */
+ int (*init)(struct dt_device_node *dev, const void *data);
+};
+
+/**
+ * device_init - Initialize a device
+ * @dev: device to initialize
+ * @type: type of the device (serial, network...)
+ * @data: specific data for initializing the device
+ *
+ * Return 0 on success.
+ */
+int __init device_init(struct dt_device_node *dev, enum device_type type,
+ const void *data);
+
+#define DT_DEVICE_START(_name, _namestr, _type) \
+static const struct device_desc __dev_desc_##_name __used \
+__attribute__((__section__(".dev.info"))) = { \
+ .name = _namestr, \
+ .type = _type, \
+
+#define DT_DEVICE_END \
+};
+
+#endif /* __ASM_ARM_DEVICE_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */