* [PATCH 01/15] driver: add dev_get_drvdata function
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 02/15] of: add devicetree probing support Sascha Hauer
` (14 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Drivers need to get their driver data either from devicetree or the platform
information. It should matter for the driver where this data comes from, so
introduce a common function for it.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/base/driver.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 47d3803..4d6b250 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -376,6 +376,16 @@ static int do_devinfo_subtree(struct device_d *dev, int depth)
return 0;
}
+int dev_get_drvdata(struct device_d *dev, unsigned long *data)
+{
+ if (dev->id_entry) {
+ *data = dev->id_entry->driver_data;
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
static int do_devinfo(int argc, char *argv[])
{
struct device_d *dev;
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 02/15] of: add devicetree probing support
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
2012-09-12 20:06 ` [PATCH 01/15] driver: add dev_get_drvdata function Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-18 15:48 ` Jean-Christophe PLAGNIOL-VILLARD
2012-09-12 20:06 ` [PATCH 03/15] oftree command: Add devicetree probe support Sascha Hauer
` (13 subsequent siblings)
15 siblings, 1 reply; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
This adds code to probe devices from a devicetree. Most helper
functions are directly imported from Linux.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
common/oftree.c | 4 +-
drivers/Kconfig | 1 +
drivers/Makefile | 1 +
drivers/base/driver.c | 25 +-
drivers/base/platform.c | 5 +
drivers/of/Kconfig | 2 +
drivers/of/Makefile | 2 +
drivers/of/base.c | 802 +++++++++++++++++++++++++++++++++++++++++++++++
drivers/of/gpio.c | 28 ++
include/driver.h | 10 +
include/of.h | 104 ++++++
11 files changed, 980 insertions(+), 4 deletions(-)
create mode 100644 drivers/of/Kconfig
create mode 100644 drivers/of/Makefile
create mode 100644 drivers/of/base.c
create mode 100644 drivers/of/gpio.c
diff --git a/common/oftree.c b/common/oftree.c
index 677e934..3e8c6f8 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -57,7 +57,7 @@ static int is_printable_string(const void *data, int len)
* a string, concatenated strings, a byte, word, double word, or (if all
* else fails) it is printed as a stream of bytes.
*/
-static void print_data(const void *data, int len)
+void of_print_property(const void *data, int len)
{
int j;
@@ -169,7 +169,7 @@ int fdt_print(struct fdt_header *working_fdt, const char *pathp)
printf_indent(level, "%s;\n", pathp);
} else {
printf_indent(level, "%s = ", pathp);
- print_data(nodep, len);
+ of_print_property(nodep, len);
printf(";\n");
}
break;
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 70797c1..d0b5e3a 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -20,5 +20,6 @@ source "drivers/watchdog/Kconfig"
source "drivers/pwm/Kconfig"
source "drivers/dma/Kconfig"
source "drivers/gpio/Kconfig"
+source "drivers/of/Kconfig"
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 28a5cb8..d398a12 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -19,3 +19,4 @@ obj-y += misc/
obj-y += dma/
obj-y += watchdog/
obj-y += gpio/
+obj-$(CONFIG_OFDEVICE) += of/
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 4d6b250..e3a7bf2 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -116,9 +116,19 @@ int register_device(struct device_d *new_device)
debug ("register_device: %s\n", dev_name(new_device));
- if (!new_device->bus) {
-// dev_err(new_device, "no bus type associated. Needs fixup\n");
+ if (!new_device->bus)
new_device->bus = &platform_bus;
+
+ if (new_device->bus == &platform_bus && new_device->resource) {
+ struct device_d *dev;
+
+ for_each_device(dev) {
+ if (!dev->resource)
+ continue;
+ if (dev->resource->start == new_device->resource->start) {
+ return -EBUSY;
+ }
+ }
}
list_add_tail(&new_device->list, &device_list);
@@ -378,6 +388,11 @@ static int do_devinfo_subtree(struct device_d *dev, int depth)
int dev_get_drvdata(struct device_d *dev, unsigned long *data)
{
+ if (dev->of_id_entry) {
+ *data = dev->of_id_entry->data;
+ return 0;
+ }
+
if (dev->id_entry) {
*data = dev->id_entry->driver_data;
return 0;
@@ -435,6 +450,12 @@ static int do_devinfo(int argc, char *argv[])
list_for_each_entry(param, &dev->parameters, list)
printf("%16s = %s\n", param->name, dev_get_param(dev, param->name));
+#ifdef CONFIG_OFDEVICE
+ if (dev->device_node) {
+ printf("\ndevice node: %s\n", dev->device_node->full_name);
+ of_print_nodes(dev->device_node, 0);
+ }
+#endif
}
return 0;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 82d2521..9b0b1cc 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -21,9 +21,14 @@
*/
#include <common.h>
#include <driver.h>
+#include <errno.h>
static int platform_match(struct device_d *dev, struct driver_d *drv)
{
+ if (IS_ENABLED(CONFIG_OFDEVICE) && dev->device_node &&
+ drv->of_compatible)
+ return of_match(dev, drv);
+
if (!strcmp(dev->name, drv->name))
return 0;
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
new file mode 100644
index 0000000..95f10d0
--- /dev/null
+++ b/drivers/of/Kconfig
@@ -0,0 +1,2 @@
+config OFDEVICE
+ bool
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
new file mode 100644
index 0000000..b38d40b
--- /dev/null
+++ b/drivers/of/Makefile
@@ -0,0 +1,2 @@
+obj-y += base.o
+obj-y += gpio.o
diff --git a/drivers/of/base.c b/drivers/of/base.c
new file mode 100644
index 0000000..ebbaef8
--- /dev/null
+++ b/drivers/of/base.c
@@ -0,0 +1,802 @@
+/*
+ * base.c - basic devicetree functions
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * based on Linux devicetree support
+ *
+ * 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 version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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 <common.h>
+#include <of.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <malloc.h>
+#include <init.h>
+#include <linux/ctype.h>
+
+/**
+ * struct alias_prop - Alias property in 'aliases' node
+ * @link: List node to link the structure in aliases_lookup list
+ * @alias: Alias property name
+ * @np: Pointer to device_node that the alias stands for
+ * @id: Index value from end of alias name
+ * @stem: Alias string without the index
+ *
+ * The structure represents one alias property of 'aliases' node as
+ * an entry in aliases_lookup list.
+ */
+struct alias_prop {
+ struct list_head link;
+ const char *alias;
+ struct device_node *np;
+ int id;
+ char stem[0];
+};
+
+static LIST_HEAD(aliases_lookup);
+
+static LIST_HEAD(phandle_list);
+
+static LIST_HEAD(allnodes);
+
+struct device_node *root_node;
+
+struct device_node *of_aliases;
+
+int of_n_addr_cells(struct device_node *np)
+{
+ const __be32 *ip;
+
+ do {
+ if (np->parent)
+ np = np->parent;
+ ip = of_get_property(np, "#address-cells", NULL);
+ if (ip)
+ return be32_to_cpup(ip);
+ } while (np->parent);
+ /* No #address-cells property for the root node */
+ return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
+}
+EXPORT_SYMBOL(of_n_addr_cells);
+
+int of_n_size_cells(struct device_node *np)
+{
+ const __be32 *ip;
+
+ do {
+ if (np->parent)
+ np = np->parent;
+ ip = of_get_property(np, "#size-cells", NULL);
+ if (ip)
+ return be32_to_cpup(ip);
+ } while (np->parent);
+ /* No #size-cells property for the root node */
+ return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
+}
+EXPORT_SYMBOL(of_n_size_cells);
+
+static void of_bus_default_count_cells(struct device_node *dev,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = of_n_addr_cells(dev);
+ if (sizec)
+ *sizec = of_n_size_cells(dev);
+}
+
+void of_bus_count_cells(struct device_node *dev,
+ int *addrc, int *sizec)
+{
+ of_bus_default_count_cells(dev, addrc, sizec);
+}
+
+struct property *of_find_property(const struct device_node *node, const char *name)
+{
+ struct property *p;
+
+ list_for_each_entry(p, &node->properties, list)
+ if (!strcmp(p->name, name))
+ return p;
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_property);
+
+static void of_alias_add(struct alias_prop *ap, struct device_node *np,
+ int id, const char *stem, int stem_len)
+{
+ ap->np = np;
+ ap->id = id;
+ strncpy(ap->stem, stem, stem_len);
+ ap->stem[stem_len] = 0;
+ list_add_tail(&ap->link, &aliases_lookup);
+ pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
+ ap->alias, ap->stem, ap->id, np->full_name);
+}
+
+/**
+ * of_alias_scan - Scan all properties of 'aliases' node
+ *
+ * The function scans all the properties of 'aliases' node and populates
+ * the global lookup table with the properties. It returns the
+ * number of alias_prop found, or error code in error case.
+ */
+void of_alias_scan(void)
+{
+ struct property *pp;
+
+ of_aliases = of_find_node_by_path("/aliases");
+ if (!of_aliases)
+ return;
+
+ list_for_each_entry(pp, &of_aliases->properties, list) {
+ const char *start = pp->name;
+ const char *end = start + strlen(start);
+ struct device_node *np;
+ struct alias_prop *ap;
+ int id, len;
+
+ /* Skip those we do not want to proceed */
+ if (!strcmp(pp->name, "name") ||
+ !strcmp(pp->name, "phandle") ||
+ !strcmp(pp->name, "linux,phandle"))
+ continue;
+
+ np = of_find_node_by_path(pp->value);
+ if (!np)
+ continue;
+
+ /* walk the alias backwards to extract the id and work out
+ * the 'stem' string */
+ while (isdigit(*(end-1)) && end > start)
+ end--;
+ len = end - start;
+
+ id = simple_strtol(end, 0, 10);
+ if (id < 0)
+ continue;
+
+ /* Allocate an alias_prop with enough space for the stem */
+ ap = xzalloc(sizeof(*ap) + len + 1);
+ if (!ap)
+ continue;
+ ap->alias = start;
+ of_alias_add(ap, np, id, start, len);
+ }
+}
+
+/**
+ * of_alias_get_id - Get alias id for the given device_node
+ * @np: Pointer to the given device_node
+ * @stem: Alias stem of the given device_node
+ *
+ * The function travels the lookup table to get alias id for the given
+ * device_node and alias stem. It returns the alias id if find it.
+ */
+int of_alias_get_id(struct device_node *np, const char *stem)
+{
+ struct alias_prop *app;
+ int id = -ENODEV;
+
+ list_for_each_entry(app, &aliases_lookup, link) {
+ if (strcmp(app->stem, stem) != 0)
+ continue;
+
+ if (np == app->np) {
+ id = app->id;
+ break;
+ }
+ }
+
+ return id;
+}
+EXPORT_SYMBOL_GPL(of_alias_get_id);
+
+u64 of_translate_address(struct device_node *node, const __be32 *in_addr)
+{
+ struct property *p;
+ u64 addr = be32_to_cpu(*in_addr);
+
+ while (1) {
+ int na, nc;
+
+ if (!node->parent)
+ return addr;
+
+ node = node->parent;
+ p = of_find_property(node, "ranges");
+ if (!p && node->parent)
+ return OF_BAD_ADDR;
+ of_bus_count_cells(node, &na, &nc);
+ if (na != 1 || nc != 1) {
+ printk("%s: #size-cells != 1 or #address-cells != 1 "
+ "currently not supported\n", node->name);
+ return OF_BAD_ADDR;
+ }
+ }
+}
+EXPORT_SYMBOL(of_translate_address);
+
+/*
+ * of_find_node_by_phandle - Find a node given a phandle
+ * @handle: phandle of the node to find
+ */
+struct device_node *of_find_node_by_phandle(phandle phandle)
+{
+ struct device_node *node;
+
+ list_for_each_entry(node, &phandle_list, phandles)
+ if (node->phandle == phandle)
+ return node;
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+const void *of_get_property(const struct device_node *np, const char *name,
+ int *lenp)
+{
+ struct property *pp = of_find_property(np, name);
+
+ if (!pp)
+ return NULL;
+
+ if (lenp)
+ *lenp = pp->length;
+
+ return pp ? pp->value : NULL;
+}
+EXPORT_SYMBOL(of_get_property);
+
+/** Checks if the given "compat" string matches one of the strings in
+ * the device's "compatible" property
+ */
+int of_device_is_compatible(const struct device_node *device,
+ const char *compat)
+{
+ const char *cp;
+ int cplen, l;
+
+ cp = of_get_property(device, "compatible", &cplen);
+ if (cp == NULL)
+ return 0;
+ while (cplen > 0) {
+ if (strcmp(cp, compat) == 0)
+ return 1;
+ l = strlen(cp) + 1;
+ cp += l;
+ cplen -= l;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(of_device_is_compatible);
+
+int of_match(struct device_d *dev, struct driver_d *drv)
+{
+ struct of_device_id *id;
+
+ id = drv->of_compatible;
+
+ while (id->compatible) {
+ if (of_device_is_compatible(dev->device_node, id->compatible) == 1) {
+ dev->of_id_entry = id;
+ return 0;
+ }
+ id++;
+ }
+
+ return 1;
+}
+EXPORT_SYMBOL(of_match);
+
+/**
+ * of_property_read_u32_array - Find and read an array of 32 bit integers
+ * from a property.
+ *
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ * @out_value: pointer to return value, modified only if return value is 0.
+ *
+ * Search for a property in a device node and read 32-bit value(s) from
+ * it. Returns 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+ * The out_value is modified only if a valid u32 value can be decoded.
+ */
+int of_property_read_u32_array(const struct device_node *np,
+ const char *propname, u32 *out_values,
+ size_t sz)
+{
+ struct property *prop = of_find_property(np, propname);
+ const __be32 *val;
+
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+ if ((sz * sizeof(*out_values)) > prop->length)
+ return -EOVERFLOW;
+
+ val = prop->value;
+ while (sz--)
+ *out_values++ = be32_to_cpup(val++);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_property_read_u32_array);
+
+/**
+ * of_parse_phandles_with_args - Find a node pointed by phandle in a list
+ * @np: pointer to a device tree node containing a list
+ * @list_name: property name that contains a list
+ * @cells_name: property name that specifies phandles' arguments count
+ * @index: index of a phandle to parse out
+ * @out_node: optional pointer to device_node struct pointer (will be filled)
+ * @out_args: optional pointer to arguments pointer (will be filled)
+ *
+ * This function is useful to parse lists of phandles and their arguments.
+ * Returns 0 on success and fills out_node and out_args, on error returns
+ * appropriate errno value.
+ *
+ * Example:
+ *
+ * phandle1: node1 {
+ * #list-cells = <2>;
+ * }
+ *
+ * phandle2: node2 {
+ * #list-cells = <1>;
+ * }
+ *
+ * node3 {
+ * list = <&phandle1 1 2 &phandle2 3>;
+ * }
+ *
+ * To get a device_node of the `node2' node you may call this:
+ * of_parse_phandles_with_args(node3, "list", "#list-cells", 2, &node2, &args);
+ */
+int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
+ const char *cells_name, int index,
+ struct device_node **out_node,
+ const void **out_args)
+{
+ int ret = -EINVAL;
+ const __be32 *list;
+ const __be32 *list_end;
+ int size;
+ int cur_index = 0;
+ struct device_node *node = NULL;
+ const void *args = NULL;
+
+ list = of_get_property(np, list_name, &size);
+ if (!list) {
+ ret = -ENOENT;
+ goto err0;
+ }
+ list_end = list + size / sizeof(*list);
+
+ while (list < list_end) {
+ const __be32 *cells;
+ phandle phandle;
+
+ phandle = be32_to_cpup(list++);
+ args = list;
+
+ /* one cell hole in the list = <>; */
+ if (!phandle)
+ goto next;
+
+ node = of_find_node_by_phandle(phandle);
+ if (!node) {
+ pr_debug("%s: could not find phandle %d\n",
+ np->full_name, phandle);
+ goto err0;
+ }
+
+ cells = of_get_property(node, cells_name, &size);
+ if (!cells || size != sizeof(*cells)) {
+ pr_debug("%s: could not get %s for %s\n",
+ np->full_name, cells_name, node->full_name);
+ goto err1;
+ }
+
+ list += be32_to_cpup(cells);
+ if (list > list_end) {
+ pr_debug("%s: insufficient arguments length\n",
+ np->full_name);
+ goto err1;
+ }
+next:
+ if (cur_index == index)
+ break;
+
+ node = NULL;
+ args = NULL;
+ cur_index++;
+ }
+
+ if (!node) {
+ /*
+ * args w/o node indicates that the loop above has stopped at
+ * the 'hole' cell. Report this differently.
+ */
+ if (args)
+ ret = -EEXIST;
+ else
+ ret = -ENOENT;
+ goto err0;
+ }
+
+ if (out_node)
+ *out_node = node;
+ if (out_args)
+ *out_args = args;
+
+ return 0;
+err1:
+err0:
+ pr_debug("%s failed with status %d\n", __func__, ret);
+ return ret;
+}
+EXPORT_SYMBOL(of_parse_phandles_with_args);
+
+/**
+ * of_machine_is_compatible - Test root of device tree for a given compatible value
+ * @compat: compatible string to look for in root node's compatible property.
+ *
+ * Returns true if the root node has the given value in its
+ * compatible property.
+ */
+int of_machine_is_compatible(const char *compat)
+{
+ if (!root_node)
+ return 0;
+
+ return of_device_is_compatible(root_node, compat);
+}
+EXPORT_SYMBOL(of_machine_is_compatible);
+
+/**
+ * of_find_node_by_path - Find a node matching a full OF path
+ * @path: The full path to match
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_path(const char *path)
+{
+ struct device_node *np;
+
+ list_for_each_entry(np, &allnodes, list) {
+ if (np->full_name && (strcmp(np->full_name, path) == 0))
+ break;
+ }
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_path);
+
+struct device_node *of_get_root_node(void)
+{
+ return root_node;
+}
+
+static int of_node_disabled(struct device_node *node)
+{
+ struct property *p;
+
+ p = of_find_property(node, "status");
+ if (p) {
+ if (!strcmp("disabled", p->value))
+ return 1;
+ }
+ return 0;
+}
+
+void of_print_nodes(struct device_node *node, int indent)
+{
+ struct device_node *n;
+ struct property *p;
+ int i;
+
+ if (!node)
+ return;
+
+ if (of_node_disabled(node))
+ return;
+
+ for (i = 0; i < indent; i++)
+ printf("\t");
+
+ printf("%s%s\n", node->name, node->name ? " {" : "{");
+
+ list_for_each_entry(p, &node->properties, list) {
+ for (i = 0; i < indent + 1; i++)
+ printf("\t");
+ printf("%s: ", p->name);
+ of_print_property(p->value, p->length);
+ printf("\n");
+ }
+
+ list_for_each_entry(n, &node->children, parent_list) {
+ of_print_nodes(n, indent + 1);
+ }
+
+ for (i = 0; i < indent; i++)
+ printf("\t");
+ printf("};\n");
+}
+
+static struct device_node *new_device_node(struct device_node *parent)
+{
+ struct device_node *node;
+
+ node = xzalloc(sizeof(*node));
+ node->parent = parent;
+ if (parent)
+ list_add_tail(&node->parent_list, &parent->children);
+
+ INIT_LIST_HEAD(&node->children);
+ INIT_LIST_HEAD(&node->properties);
+
+ return node;
+}
+
+static struct property *new_property(struct device_node *node, const char *name,
+ const void *data, int len)
+{
+ struct property *prop;
+
+ prop = xzalloc(sizeof(*prop));
+
+ prop->name = strdup(name);
+ prop->length = len;
+ prop->value = xzalloc(len);
+ memcpy(prop->value, data, len);
+
+ list_add_tail(&prop->list, &node->properties);
+
+ return prop;
+}
+
+static struct device_d *add_of_device(struct device_node *node)
+{
+ struct device_d *dev;
+ char *name, *at;
+ const struct property *cp;
+
+ if (of_node_disabled(node))
+ return NULL;
+
+ cp = of_get_property(node, "compatible", NULL);
+ if (!cp)
+ return NULL;
+
+ dev = xzalloc(sizeof(*dev));
+
+ name = xstrdup(node->name);
+ at = strchr(name, '@');
+ if (at) {
+ *at = 0;
+ snprintf(dev->name, MAX_DRIVER_NAME, "%s.%s", at + 1, name);
+ } else {
+ strncpy(dev->name, node->name, MAX_DRIVER_NAME);
+ }
+
+ dev->id = DEVICE_ID_SINGLE;
+ dev->resource = node->resource;
+ dev->num_resources = 1;
+ dev->device_node = node;
+ node->device = dev;
+
+ debug("register device 0x%08x\n", node->resource[0].start);
+
+ register_device(dev);
+
+ free(name);
+
+ return dev;
+}
+EXPORT_SYMBOL(add_of_device);
+
+static int add_of_device_resource(struct device_node *node)
+{
+ struct property *reg;
+ u64 address, size;
+ struct resource *res;
+ struct device_d *dev;
+ phandle phandle;
+ int ret;
+
+ ret = of_property_read_u32(node, "phandle", &phandle);
+ if (!ret) {
+ node->phandle = phandle;
+ list_add_tail(&node->phandles, &phandle_list);
+ }
+
+ reg = of_find_property(node, "reg");
+ if (!reg)
+ return -ENODEV;
+
+ address = of_translate_address(node, reg->value);
+ if (address == OF_BAD_ADDR)
+ return -EINVAL;
+
+ size = be32_to_cpu(((u32 *)reg->value)[1]);
+
+ /*
+ * A device may already be registered as platform_device.
+ * Instead of registering the same device again, just
+ * add this node to the existing device.
+ */
+ for_each_device(dev) {
+ if (!dev->resource)
+ continue;
+ if (dev->resource->start == address) {
+ debug("connecting %s to %s\n", node->name, dev_name(dev));
+ node->device = dev;
+ dev->device_node = node;
+ node->resource = dev->resource;
+ return 0;
+ }
+ }
+
+ res = xzalloc(sizeof(*res));
+ res->start = address;
+ res->end = address + size - 1;
+ res->flags = IORESOURCE_MEM;
+
+ node->resource = res;
+
+ add_of_device(node);
+
+ return 0;
+}
+
+void of_free(struct device_node *node)
+{
+ struct device_node *n, *nt;
+ struct property *p, *pt;
+
+ if (!node)
+ return;
+
+ list_for_each_entry_safe(p, pt, &node->properties, list) {
+ list_del(&p->list);
+ free(p->name);
+ free(p->value);
+ free(p);
+ }
+
+ list_for_each_entry_safe(n, nt, &node->children, parent_list) {
+ of_free(n);
+ }
+
+ if (node->parent)
+ list_del(&node->parent_list);
+
+ if (node->device)
+ node->device->device_node = NULL;
+ else
+ free(node->resource);
+
+ free(node->name);
+ free(node->full_name);
+ free(node);
+}
+
+static void __of_probe(struct device_node *node)
+{
+ struct device_node *n;
+
+ if (node->device)
+ return;
+
+ add_of_device_resource(node);
+
+ list_for_each_entry(n, &node->children, parent_list)
+ __of_probe(n);
+}
+
+int of_probe(void)
+{
+ if(!root_node)
+ return -ENODEV;
+
+ __of_probe(root_node);
+
+ return 0;
+}
+
+/*
+ * Parse a flat device tree binary blob and store it in the barebox
+ * internal tree format,
+ */
+int of_parse_dtb(struct fdt_header *fdt)
+{
+ const void *nodep; /* property node pointer */
+ int nodeoffset; /* node offset from libfdt */
+ int nextoffset; /* next node offset from libfdt */
+ uint32_t tag; /* tag */
+ int len; /* length of the property */
+ int level = 0; /* keep track of nesting level */
+ const struct fdt_property *fdt_prop;
+ const char *pathp;
+ int depth = 10000;
+ struct device_node *node = NULL;
+ char buf[1024];
+ int ret;
+
+ if (root_node)
+ return -EBUSY;
+
+ nodeoffset = fdt_path_offset(fdt, "/");
+ if (nodeoffset < 0) {
+ /*
+ * Not found or something else bad happened.
+ */
+ printf ("libfdt fdt_path_offset() returned %s\n",
+ fdt_strerror(nodeoffset));
+ return -EINVAL;
+ }
+
+ while (1) {
+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ pathp = fdt_get_name(fdt, nodeoffset, NULL);
+
+ if (pathp == NULL)
+ pathp = "/* NULL pointer error */";
+
+ ret = fdt_get_path(fdt, nodeoffset, buf, 1024);
+ if (ret)
+ return -EINVAL;
+
+ node = new_device_node(node);
+ if (!node->parent)
+ root_node = node;
+ node->full_name = xstrdup(buf);
+ node->name = xstrdup(pathp);
+ list_add_tail(&node->list, &allnodes);
+ break;
+ case FDT_END_NODE:
+ node = node->parent;
+ break;
+ case FDT_PROP:
+ fdt_prop = fdt_offset_ptr(fdt, nodeoffset,
+ sizeof(*fdt_prop));
+ pathp = fdt_string(fdt,
+ fdt32_to_cpu(fdt_prop->nameoff));
+ len = fdt32_to_cpu(fdt_prop->len);
+ nodep = fdt_prop->data;
+ new_property(node, pathp, nodep, len);
+ break;
+ case FDT_NOP:
+ break;
+ case FDT_END:
+ of_alias_scan();
+ return 0;
+ default:
+ if (level <= depth)
+ printf("Unknown tag 0x%08X\n", tag);
+ return -EINVAL;
+ }
+ nodeoffset = nextoffset;
+ }
+
+ return 0;
+}
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
new file mode 100644
index 0000000..d4314f3
--- /dev/null
+++ b/drivers/of/gpio.c
@@ -0,0 +1,28 @@
+#define DEBUG
+
+#include <common.h>
+#include <errno.h>
+#include <of.h>
+#include <gpio.h>
+
+int of_get_named_gpio(struct device_node *np,
+ const char *propname, int index)
+{
+ int ret;
+ struct device_node *gpio_np;
+ const void *gpio_spec;
+
+ ret = of_parse_phandles_with_args(np, propname, "#gpio-cells", index,
+ &gpio_np, &gpio_spec);
+ if (ret) {
+ pr_debug("%s: can't parse gpios property: %d\n", __func__, ret);
+ return -EINVAL;
+ }
+
+ ret = gpio_get_num(gpio_np->device, be32_to_cpup(gpio_spec));
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
diff --git a/include/driver.h b/include/driver.h
index 40b76c1..705e7d9 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -25,6 +25,7 @@
#include <linux/list.h>
#include <linux/ioport.h>
+#include <of.h>
#define MAX_DRIVER_NAME 32
#define FORMAT_DRIVER_NAME_ID "%s%d"
@@ -106,6 +107,9 @@ struct device_d {
struct list_head cdevs;
struct platform_device_id *id_entry;
+ struct device_node *device_node;
+
+ struct of_device_id *of_id_entry;
};
/** @brief Describes a driver present in the system */
@@ -128,6 +132,7 @@ struct driver_d {
struct bus_type *bus;
struct platform_device_id *id_table;
+ struct of_device_id *of_compatible;
};
/*@}*/ /* do not delete, doxygen relevant */
@@ -432,5 +437,10 @@ int devfs_add_partition(const char *devname, loff_t offset, loff_t size,
int flags, const char *name);
int devfs_del_partition(const char *name);
+#define DRV_OF_COMPAT(compat) \
+ IS_ENABLED(CONFIG_OFDEVICE) ? (compat) : NULL
+
+int dev_get_drvdata(struct device_d *dev, unsigned long *data);
+
#endif /* DRIVER_H */
diff --git a/include/of.h b/include/of.h
index 609b3b5..762df9d 100644
--- a/include/of.h
+++ b/include/of.h
@@ -2,6 +2,8 @@
#define __OF_H
#include <fdt.h>
+#include <errno.h>
+#include <asm/byteorder.h>
extern struct fdt_header *barebox_fdt;
@@ -19,4 +21,106 @@ void do_fixup_by_path_u32(struct fdt_header *fdt, const char *path, const char *
u32 val, int create);
int fdt_get_path_or_create(struct fdt_header *fdt, const char *path);
+#define OF_BAD_ADDR ((u64)-1)
+
+typedef u32 phandle;
+
+struct property {
+ char *name;
+ int length;
+ void *value;
+ struct list_head list;
+};
+
+struct device_node {
+ char *name;
+ char *full_name;
+
+ struct list_head properties;
+ struct device_node *parent;
+ struct list_head children;
+ struct list_head parent_list;
+ struct list_head list;
+ struct resource *resource;
+ struct device_d *device;
+ struct list_head phandles;
+ phandle phandle;
+};
+
+struct of_device_id {
+ char *compatible;
+ unsigned long data;
+};
+
+struct driver_d;
+
+int of_match(struct device_d *dev, struct driver_d *drv);
+
+struct property *of_find_property(const struct device_node *node, const char *name);
+
+struct device_node *of_find_node_by_path(const char *path);
+
+struct fdt_header *fdt_get_tree(void);
+
+#define device_node_for_nach_child(node, child) \
+ list_for_each_entry(child, &node->children, parent_list)
+
+/* Helper to read a big number; size is in cells (not bytes) */
+static inline u64 of_read_number(const __be32 *cell, int size)
+{
+ u64 r = 0;
+ while (size--)
+ r = (r << 32) | be32_to_cpu(*(cell++));
+ return r;
+}
+
+int of_property_read_u32_array(const struct device_node *np,
+ const char *propname, u32 *out_values,
+ size_t sz);
+
+static inline int of_property_read_u32(const struct device_node *np,
+ const char *propname,
+ u32 *out_value)
+{
+ return of_property_read_u32_array(np, propname, out_value, 1);
+}
+
+const void *of_get_property(const struct device_node *np, const char *name,
+ int *lenp);
+
+int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
+ const char *cells_name, int index,
+ struct device_node **out_node,
+ const void **out_args);
+
+int of_get_named_gpio(struct device_node *np,
+ const char *propname, int index);
+
+struct device_node *of_find_node_by_phandle(phandle phandle);
+void of_print_property(const void *data, int len);
+
+int of_machine_is_compatible(const char *compat);
+
+#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
+
+void of_print_nodes(struct device_node *node, int indent);
+int of_probe(void);
+int of_parse_dtb(struct fdt_header *fdt);
+
+#ifdef CONFIG_OFDEVICE
+struct device_node *of_get_root_node(void);
+int of_alias_get_id(struct device_node *np, const char *stem);
+#else
+static inline struct device_node *of_get_root_node(void)
+{
+ return NULL;
+}
+
+static inline int of_alias_get_id(struct device_node *np, const char *stem)
+{
+ return -ENOENT;
+}
+#endif
+
#endif /* __OF_H */
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 02/15] of: add devicetree probing support
2012-09-12 20:06 ` [PATCH 02/15] of: add devicetree probing support Sascha Hauer
@ 2012-09-18 15:48 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 0 replies; 21+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-09-18 15:48 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
> + !strcmp(pp->name, "linux,phandle"))
> + continue;
> +
> + np = of_find_node_by_path(pp->value);
> + if (!np)
> + continue;
> +
> + /* walk the alias backwards to extract the id and work out
> + * the 'stem' string */
> + while (isdigit(*(end-1)) && end > start)
> + end--;
> + len = end - start;
> +
> + id = simple_strtol(end, 0, 10);
> + if (id < 0)
> + continue;
> +
> + /* Allocate an alias_prop with enough space for the stem */
> + ap = xzalloc(sizeof(*ap) + len + 1);
xzalloc does not if nomem
> + if (!ap)
> + continue;
> + ap->alias = start;
> + of_alias_add(ap, np, id, start, len);
> + }
> +}
> +
Best Regards,
J.
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 03/15] oftree command: Add devicetree probe support
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
2012-09-12 20:06 ` [PATCH 01/15] driver: add dev_get_drvdata function Sascha Hauer
2012-09-12 20:06 ` [PATCH 02/15] of: add devicetree probing support Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 04/15] of: Add devicetree partition parsing Sascha Hauer
` (12 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
With this the -p option is no longer for parse, but for probe instead.
Using this parses a devicetree given on the command line and probes
the devices found in this tree. Devices which already exist are not
probed again, but instead their device_node is attached to the existing
device.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
commands/Kconfig | 12 +++++++++++-
commands/oftree.c | 28 +++++++++++++++-------------
2 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/commands/Kconfig b/commands/Kconfig
index f2756cc..8a3edfa 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -468,7 +468,17 @@ config CMD_OFTREE
tristate
select OFTREE
prompt "oftree"
- select FDT
+ help
+ The oftree command has support for dumping devicetrees and, if
+ enabled, to probe devices from the devicetree
+
+config CMD_OFTREE_PROBE
+ bool
+ depends on CMD_OFTREE
+ select OFDEVICE
+ prompt "oftree probe support"
+ help
+ This enables the -p option to probe devices from the devicetree
endmenu
diff --git a/commands/oftree.c b/commands/oftree.c
index 77afbc5..6479fa4 100644
--- a/commands/oftree.c
+++ b/commands/oftree.c
@@ -48,7 +48,8 @@ static int do_oftree(int argc, char *argv[])
char *file = NULL;
const char *node = "/";
int dump = 0;
- int parse = 0;
+ int probe = 0;
+ int ret;
while ((opt = getopt(argc, argv, "dpfn:")) > 0) {
switch (opt) {
@@ -56,7 +57,12 @@ static int do_oftree(int argc, char *argv[])
dump = 1;
break;
case 'p':
- parse = 1;
+ if (IS_ENABLED(CONFIG_CMD_OFTREE_PROBE)) {
+ probe = 1;
+ } else {
+ printf("oftree device probe support disabled\n");
+ return COMMAND_ERROR_USAGE;
+ }
break;
case 'f':
free(barebox_fdt);
@@ -71,7 +77,7 @@ static int do_oftree(int argc, char *argv[])
if (optind < argc)
file = argv[optind];
- if (!dump && !parse)
+ if (!dump && !probe)
return COMMAND_ERROR_USAGE;
if (dump) {
@@ -95,7 +101,7 @@ static int do_oftree(int argc, char *argv[])
return 0;
}
- if (parse) {
+ if (probe) {
if (!file)
return COMMAND_ERROR_USAGE;
@@ -105,17 +111,13 @@ static int do_oftree(int argc, char *argv[])
return 1;
}
- fdt = xrealloc(fdt, size + 0x8000);
- fdt_open_into(fdt, fdt, size + 0x8000);
- if (!fdt) {
- printf("unable to read %s\n", file);
+ ret = of_parse_dtb(fdt);
+ if (ret) {
+ printf("parse oftree: %s\n", strerror(-ret));
return 1;
}
- if (barebox_fdt)
- free(barebox_fdt);
-
- barebox_fdt = fdt;
+ of_probe();
}
return 0;
@@ -123,7 +125,7 @@ static int do_oftree(int argc, char *argv[])
BAREBOX_CMD_HELP_START(oftree)
BAREBOX_CMD_HELP_USAGE("oftree [OPTIONS]\n")
-BAREBOX_CMD_HELP_OPT ("-p <FILE>", "parse and store oftree from <file>\n")
+BAREBOX_CMD_HELP_OPT ("-p <FILE>", "probe devices in oftree from <file>\n")
BAREBOX_CMD_HELP_OPT ("-d [FILE]", "dump oftree from [FILE] or the parsed tree if no file is given\n")
BAREBOX_CMD_HELP_OPT ("-f", "free stored oftree\n")
BAREBOX_CMD_HELP_END
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 04/15] of: Add devicetree partition parsing
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (2 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 03/15] oftree command: Add devicetree probe support Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 05/15] spi: add oftree support Sascha Hauer
` (11 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Helper code to probe mtd partitions from the devicetree.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/of/Makefile | 1 +
drivers/of/partition.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
include/of.h | 9 +++++++
3 files changed, 74 insertions(+)
create mode 100644 drivers/of/partition.c
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index b38d40b..c14aaec 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,2 +1,3 @@
obj-y += base.o
obj-y += gpio.o
+obj-y += partition.o
diff --git a/drivers/of/partition.c b/drivers/of/partition.c
new file mode 100644
index 0000000..6a57a60
--- /dev/null
+++ b/drivers/of/partition.c
@@ -0,0 +1,64 @@
+/*
+ * partition.c - devicetree partition parsing
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * based on Linux devicetree support
+ *
+ * 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 version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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 <common.h>
+#include <of.h>
+#include <malloc.h>
+#include <linux/mtd/mtd.h>
+
+int of_parse_partitions(const char *cdevname,
+ struct device_node *node)
+{
+ struct device_node *n;
+ const char *partname;
+ char *filename;
+
+ device_node_for_nach_child(node, n) {
+ const __be32 *reg;
+ unsigned long offset, size;
+ const char *name;
+ int len;
+ unsigned long flags = 0;
+
+ reg = of_get_property(n, "reg", &len);
+ if (!reg)
+ continue;
+
+ offset = be32_to_cpu(reg[0]);
+ size = be32_to_cpu(reg[1]);
+
+ partname = of_get_property(n, "label", &len);
+ if (!partname)
+ partname = of_get_property(n, "name", &len);
+ name = (char *)partname;
+
+ debug("add partition: %s.%s 0x%08lx 0x%08lx\n", cdevname, partname, offset, size);
+
+ if (of_get_property(n, "read-only", &len))
+ flags = DEVFS_PARTITION_READONLY;
+
+ filename = asprintf("%s.%s", cdevname, partname);
+
+ devfs_add_partition(cdevname, offset, size, flags, filename);
+
+ free(filename);
+ }
+
+ return 0;
+}
diff --git a/include/of.h b/include/of.h
index 762df9d..7b6a23a 100644
--- a/include/of.h
+++ b/include/of.h
@@ -109,9 +109,18 @@ int of_probe(void);
int of_parse_dtb(struct fdt_header *fdt);
#ifdef CONFIG_OFDEVICE
+int of_parse_partitions(const char *cdevname,
+ struct device_node *node);
+
struct device_node *of_get_root_node(void);
int of_alias_get_id(struct device_node *np, const char *stem);
#else
+static inline int of_parse_partitions(const char *cdevname,
+ struct device_node *node)
+{
+ return -EINVAL;
+}
+
static inline struct device_node *of_get_root_node(void)
{
return NULL;
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 05/15] spi: add oftree support
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (3 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 04/15] of: Add devicetree partition parsing Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 06/15] ARM i.MX: Use platform_device_id for gpio driver Sascha Hauer
` (10 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/spi/spi.c | 34 +++++++++++++++++++++++++++++++++-
include/spi/spi.h | 6 ++++++
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 4416783..bbb7679 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -83,6 +83,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
/* allocate a free id for this chip */
proxy->dev.id = DEVICE_ID_DYNAMIC;
proxy->dev.type_data = proxy;
+ proxy->dev.device_node = chip->device_node;
dev_add_child(master->dev, &proxy->dev);
/* drivers may modify this initial i/o setup */
@@ -102,6 +103,29 @@ fail:
}
EXPORT_SYMBOL(spi_new_device);
+#ifdef CONFIG_OFTREE
+#include <of.h>
+
+void spi_of_register_slaves(struct spi_master *master, struct device_node *node)
+{
+ struct device_node *n;
+ struct spi_board_info chip;
+ struct property *reg;
+
+ device_node_for_nach_child(node, n) {
+ chip.name = n->name;
+ chip.bus_num = master->bus_num;
+ chip.max_speed_hz = 300000; /* FIXME */
+ reg = of_find_property(n, "reg");
+ if (!reg)
+ continue;
+ chip.chip_select = of_read_number(reg->value, 1);
+ chip.device_node = n;
+ spi_register_board_info(&chip, 1);
+ }
+}
+#endif
+
/**
* spi_register_board_info - register SPI devices for a given board
* @info: array of chip descriptors
@@ -145,7 +169,7 @@ static void scan_boardinfo(struct spi_master *master)
unsigned n;
for (n = bi->n_board_info; n > 0; n--, chip++) {
- debug("%s %d %d\n", __FUNCTION__, chip->bus_num, master->bus_num);
+ printf("%s %d %d\n", __FUNCTION__, chip->bus_num, master->bus_num);
if (chip->bus_num != master->bus_num)
continue;
/* NOTE: this relies on spi_new_device to
@@ -156,6 +180,8 @@ static void scan_boardinfo(struct spi_master *master)
}
}
+static LIST_HEAD(spi_master_list);
+
/**
* spi_register_master - register SPI master controller
* @master: initialized master, originally from spi_alloc_master()
@@ -188,6 +214,8 @@ int spi_register_master(struct spi_master *master)
if (master->num_chipselect == 0)
return -EINVAL;
+ list_add_tail(&master->list, &spi_master_list);
+
/* populate children from any spi device tables */
scan_boardinfo(master);
status = 0;
@@ -245,6 +273,10 @@ EXPORT_SYMBOL(spi_write_then_read);
static int spi_match(struct device_d *dev, struct driver_d *drv)
{
+ if (IS_ENABLED(CONFIG_OFDEVICE) && dev->device_node &&
+ drv->of_compatible)
+ return of_match(dev, drv);
+
return strcmp(dev->name, drv->name) ? -1 : 0;
}
diff --git a/include/spi/spi.h b/include/spi/spi.h
index 569cdcd..1773ca2 100644
--- a/include/spi/spi.h
+++ b/include/spi/spi.h
@@ -17,6 +17,7 @@ struct spi_board_info {
u8 mode;
u8 bits_per_word;
void *platform_data;
+ struct device_node *device_node;
};
/**
@@ -163,6 +164,8 @@ struct spi_master {
/* called on release() to free memory provided by spi_master */
void (*cleanup)(struct spi_device *spi);
+
+ struct list_head list;
};
/*---------------------------------------------------------------------------*/
@@ -434,4 +437,7 @@ static inline int spi_register_driver(struct driver_d *drv)
drv->bus = &spi_bus;
return register_driver(drv);
}
+
+void spi_of_register_slaves(struct spi_master *master, struct device_node *node);
+
#endif /* __INCLUDE_SPI_H */
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 06/15] ARM i.MX: Use platform_device_id for gpio driver
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (4 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 05/15] spi: add oftree support Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 07/15] ARM i.MX: implement clocksource as driver Sascha Hauer
` (9 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
So we get the type of the gpio controller from the device
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/gpio.c | 72 +++++++++++++++++++++++++++++----------------
arch/arm/mach-imx/imx1.c | 8 ++---
arch/arm/mach-imx/imx21.c | 12 ++++----
arch/arm/mach-imx/imx25.c | 8 ++---
arch/arm/mach-imx/imx27.c | 15 +++++-----
arch/arm/mach-imx/imx31.c | 6 ++--
arch/arm/mach-imx/imx35.c | 6 ++--
arch/arm/mach-imx/imx51.c | 8 ++---
arch/arm/mach-imx/imx53.c | 14 ++++-----
arch/arm/mach-imx/imx6.c | 14 ++++-----
10 files changed, 91 insertions(+), 72 deletions(-)
diff --git a/arch/arm/mach-imx/gpio.c b/arch/arm/mach-imx/gpio.c
index 8d5d4ce..b7426fe 100644
--- a/arch/arm/mach-imx/gpio.c
+++ b/arch/arm/mach-imx/gpio.c
@@ -30,28 +30,28 @@
#include <gpio.h>
#include <init.h>
-#if defined CONFIG_ARCH_IMX1 || defined CONFIG_ARCH_IMX21 || defined CONFIG_ARCH_IMX27
-#define GPIO_DR 0x1c
-#define GPIO_GDIR 0x00
-#define GPIO_PSR 0x24
-#define GPIO_ICR1 0x28
-#define GPIO_ICR2 0x2C
-#define GPIO_IMR 0x30
-#define GPIO_ISR 0x34
-#else
-#define GPIO_DR 0x00
-#define GPIO_GDIR 0x04
-#define GPIO_PSR 0x08
-#define GPIO_ICR1 0x0C
-#define GPIO_ICR2 0x10
-#define GPIO_IMR 0x14
-#define GPIO_ISR 0x18
-#define GPIO_ISR 0x18
-#endif
-
struct imx_gpio_chip {
void __iomem *base;
struct gpio_chip chip;
+ struct imx_gpio_regs *regs;
+};
+
+struct imx_gpio_regs {
+ unsigned int dr;
+ unsigned int gdir;
+ unsigned int psr;
+};
+
+static struct imx_gpio_regs regs_imx1 = {
+ .dr = 0x1c,
+ .gdir = 0x00,
+ .psr = 0x24,
+};
+
+static struct imx_gpio_regs regs_imx31 = {
+ .dr = 0x00,
+ .gdir = 0x04,
+ .psr = 0x08,
};
static void imx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
@@ -63,14 +63,14 @@ static void imx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
if (!base)
return;
- val = readl(base + GPIO_DR);
+ val = readl(base + imxgpio->regs->dr);
if (value)
val |= 1 << gpio;
else
val &= ~(1 << gpio);
- writel(val, base + GPIO_DR);
+ writel(val, base + imxgpio->regs->dr);
}
static int imx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
@@ -82,9 +82,9 @@ static int imx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
if (!base)
return -EINVAL;
- val = readl(base + GPIO_GDIR);
+ val = readl(base + imxgpio->regs->gdir);
val &= ~(1 << gpio);
- writel(val, base + GPIO_GDIR);
+ writel(val, base + imxgpio->regs->gdir);
return 0;
}
@@ -98,9 +98,9 @@ static int imx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int
gpio_set_value(gpio + chip->base, value);
- val = readl(base + GPIO_GDIR);
+ val = readl(base + imxgpio->regs->gdir);
val |= 1 << gpio;
- writel(val, base + GPIO_GDIR);
+ writel(val, base + imxgpio->regs->gdir);
return 0;
}
@@ -111,7 +111,7 @@ static int imx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
void __iomem *base = imxgpio->base;
u32 val;
- val = readl(base + GPIO_PSR);
+ val = readl(base + imxgpio->regs->psr);
return val & (1 << gpio) ? 1 : 0;
}
@@ -126,6 +126,12 @@ static struct gpio_ops imx_gpio_ops = {
static int imx_gpio_probe(struct device_d *dev)
{
struct imx_gpio_chip *imxgpio;
+ struct imx_gpio_regs *regs;
+ int ret;
+
+ ret = dev_get_drvdata(dev, (unsigned long *)®s);
+ if (ret)
+ return ret;
imxgpio = xzalloc(sizeof(*imxgpio));
imxgpio->base = dev_request_mem_region(dev, 0);
@@ -133,6 +139,7 @@ static int imx_gpio_probe(struct device_d *dev)
imxgpio->chip.base = -1;
imxgpio->chip.ngpio = 32;
imxgpio->chip.dev = dev;
+ imxgpio->regs = regs;
gpiochip_add(&imxgpio->chip);
dev_info(dev, "probed gpiochip%d with base %d\n", dev->id, imxgpio->chip.base);
@@ -140,9 +147,22 @@ static int imx_gpio_probe(struct device_d *dev)
return 0;
}
+static struct platform_device_id imx_gpio_ids[] = {
+ {
+ .name = "imx1-gpio",
+ .driver_data = (unsigned long)®s_imx1,
+ }, {
+ .name = "imx31-gpio",
+ .driver_data = (unsigned long)®s_imx31,
+ }, {
+ /* sentinel */
+ },
+};
+
static struct driver_d imx_gpio_driver = {
.name = "imx-gpio",
.probe = imx_gpio_probe,
+ .id_table = imx_gpio_ids,
};
static int imx_gpio_add(void)
diff --git a/arch/arm/mach-imx/imx1.c b/arch/arm/mach-imx/imx1.c
index 5a000bc..a81b244 100644
--- a/arch/arm/mach-imx/imx1.c
+++ b/arch/arm/mach-imx/imx1.c
@@ -20,10 +20,10 @@
static int imx1_init(void)
{
- add_generic_device("imx-gpio", 0, NULL, 0x0021c000, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x0021c100, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x0021c200, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, 0x0021c300, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 0, NULL, 0x0021c000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 1, NULL, 0x0021c100, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 2, NULL, 0x0021c200, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 3, NULL, 0x0021c300, 0x100, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx21.c b/arch/arm/mach-imx/imx21.c
index 85590ee..619a826 100644
--- a/arch/arm/mach-imx/imx21.c
+++ b/arch/arm/mach-imx/imx21.c
@@ -28,12 +28,12 @@ int imx_silicon_revision(void)
static int imx21_init(void)
{
- add_generic_device("imx-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, 0x10015300, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 4, NULL, 0x10015400, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 5, NULL, 0x10015500, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 3, NULL, 0x10015300, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 4, NULL, 0x10015400, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 5, NULL, 0x10015500, 0x100, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c
index d605022..183a492 100644
--- a/arch/arm/mach-imx/imx25.c
+++ b/arch/arm/mach-imx/imx25.c
@@ -48,10 +48,10 @@ static int imx25_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, &imx25_iim_pdata);
- add_generic_device("imx-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, 0x53f9c000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 3, NULL, 0x53f9c000, 0x1000, IORESOURCE_MEM, NULL);
return 0;
}
coredevice_initcall(imx25_init);
diff --git a/arch/arm/mach-imx/imx27.c b/arch/arm/mach-imx/imx27.c
index c6e6942..8f0461d 100644
--- a/arch/arm/mach-imx/imx27.c
+++ b/arch/arm/mach-imx/imx27.c
@@ -72,13 +72,12 @@ static int imx27_init(void)
IORESOURCE_MEM, NULL);
imx27_init_max();
-
- add_generic_device("imx-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, 0x10015300, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 4, NULL, 0x10015400, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 5, NULL, 0x10015500, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 3, NULL, 0x10015300, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 4, NULL, 0x10015400, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 5, NULL, 0x10015500, 0x100, IORESOURCE_MEM, NULL);
return 0;
}
-coredevice_initcall(imx27_init);
+console_initcall(imx27_init);
diff --git a/arch/arm/mach-imx/imx31.c b/arch/arm/mach-imx/imx31.c
index 90dc4e3..faad11e 100644
--- a/arch/arm/mach-imx/imx31.c
+++ b/arch/arm/mach-imx/imx31.c
@@ -25,9 +25,9 @@ static int imx31_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx35.c b/arch/arm/mach-imx/imx35.c
index efbee98..6952219 100644
--- a/arch/arm/mach-imx/imx35.c
+++ b/arch/arm/mach-imx/imx35.c
@@ -56,9 +56,9 @@ static int imx35_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
index e43cc65..6a394bf 100644
--- a/arch/arm/mach-imx/imx51.c
+++ b/arch/arm/mach-imx/imx51.c
@@ -78,10 +78,10 @@ static int imx51_init(void)
add_generic_device("imx_iim", 0, NULL, MX51_IIM_BASE_ADDR, SZ_4K,
IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 0, NULL, 0x73f84000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x73f88000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x73f8c000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, 0x73f90000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, 0x73f84000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, 0x73f88000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, 0x73f8c000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 3, NULL, 0x73f90000, 0x1000, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c
index cb94575..228e47d 100644
--- a/arch/arm/mach-imx/imx53.c
+++ b/arch/arm/mach-imx/imx53.c
@@ -74,13 +74,13 @@ static int imx53_init(void)
add_generic_device("imx_iim", 0, NULL, MX53_IIM_BASE_ADDR, SZ_4K,
IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 0, NULL, MX53_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, MX53_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, MX53_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, MX53_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 4, NULL, MX53_GPIO5_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 5, NULL, MX53_GPIO6_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 6, NULL, MX53_GPIO7_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, MX53_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, MX53_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, MX53_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 3, NULL, MX53_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 4, NULL, MX53_GPIO5_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 5, NULL, MX53_GPIO6_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 6, NULL, MX53_GPIO7_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
return 0;
}
coredevice_initcall(imx53_init);
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index c693724..085b5c8 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -58,13 +58,13 @@ void imx6_init_lowlevel(void)
static int imx6_init(void)
{
- add_generic_device("imx-gpio", 0, NULL, MX6_GPIO1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, MX6_GPIO2_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, MX6_GPIO3_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, MX6_GPIO4_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 4, NULL, MX6_GPIO5_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 5, NULL, MX6_GPIO6_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 6, NULL, MX6_GPIO7_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, MX6_GPIO1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, MX6_GPIO2_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, MX6_GPIO3_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 3, NULL, MX6_GPIO4_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 4, NULL, MX6_GPIO5_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 5, NULL, MX6_GPIO6_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 6, NULL, MX6_GPIO7_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
return 0;
}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 07/15] ARM i.MX: implement clocksource as driver
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (5 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 06/15] ARM i.MX: Use platform_device_id for gpio driver Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-17 16:17 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 08/15] serial i.MX: oftree support Sascha Hauer
` (8 subsequent siblings)
15 siblings, 1 reply; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
To get rid of the register definitions in the SoC header files.
platform_device_id is used to distinguish between gpt types.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/clocksource.c | 72 +++++++++++++++++++++++++--
arch/arm/mach-imx/imx1.c | 1 +
arch/arm/mach-imx/imx21.c | 1 +
arch/arm/mach-imx/imx25.c | 2 +
arch/arm/mach-imx/imx27.c | 2 +
arch/arm/mach-imx/imx31.c | 1 +
arch/arm/mach-imx/imx35.c | 1 +
arch/arm/mach-imx/imx51.c | 1 +
arch/arm/mach-imx/imx53.c | 2 +
arch/arm/mach-imx/imx6.c | 1 +
arch/arm/mach-imx/include/mach/imx1-regs.h | 23 ---------
arch/arm/mach-imx/include/mach/imx21-regs.h | 24 ---------
arch/arm/mach-imx/include/mach/imx25-regs.h | 27 ----------
arch/arm/mach-imx/include/mach/imx27-regs.h | 23 ---------
arch/arm/mach-imx/include/mach/imx31-regs.h | 27 ----------
arch/arm/mach-imx/include/mach/imx35-regs.h | 28 -----------
arch/arm/mach-imx/include/mach/imx51-regs.h | 19 -------
arch/arm/mach-imx/include/mach/imx53-regs.h | 19 -------
arch/arm/mach-imx/include/mach/imx6-regs.h | 19 -------
19 files changed, 79 insertions(+), 214 deletions(-)
diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index 4e77ece..166710c 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -32,17 +32,46 @@
#include <common.h>
#include <init.h>
#include <clock.h>
+#include <errno.h>
#include <notifier.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
#include <io.h>
-#define GPT(x) __REG(IMX_TIM1_BASE + (x))
-#define timer_base IOMEM(IMX_TIM1_BASE)
+/* Part 1: Registers */
+# define GPT_TCTL 0x00
+# define GPT_TPRER 0x04
+
+/* Part 2: Bitfields */
+#define TCTL_SWR (1<<15) /* Software reset */
+#define TCTL_FRR (1<<8) /* Freerun / restart */
+#define TCTL_CAP (3<<6) /* Capture Edge */
+#define TCTL_OM (1<<5) /* output mode */
+#define TCTL_IRQEN (1<<4) /* interrupt enable */
+#define TCTL_CLKSOURCE (1) /* Clock source bit position */
+#define TCTL_TEN (1) /* Timer enable */
+#define TPRER_PRES (0xff) /* Prescale */
+#define TSTAT_CAPT (1<<1) /* Capture event */
+#define TSTAT_COMP (1) /* Compare event */
+
+struct imx_gpt_regs {
+ unsigned int tcn;
+};
+
+static struct imx_gpt_regs regs_imx1 = {
+ .tcn = 0x10,
+};
+
+static struct imx_gpt_regs regs_imx31 = {
+ .tcn = 0x24,
+};
+
+static struct imx_gpt_regs *regs;
+static void __iomem *timer_base;
static uint64_t imx_clocksource_read(void)
{
- return readl(timer_base + GPT_TCN);
+ return readl(timer_base + regs->tcn);
}
static struct clocksource cs = {
@@ -61,10 +90,21 @@ static struct notifier_block imx_clock_notifier = {
.notifier_call = imx_clocksource_clock_change,
};
-static int clocksource_init (void)
+static int imx_gpt_probe(struct device_d *dev)
{
int i;
uint32_t val;
+ int ret;
+
+ /* one timer is enough */
+ if (timer_base)
+ return -EBUSY;
+
+ ret = dev_get_drvdata(dev, (unsigned long *)®s);
+ if (ret)
+ return ret;
+
+ timer_base = dev_request_mem_region(dev, 0);
/* setup GP Timer 1 */
writel(TCTL_SWR, timer_base + GPT_TCTL);
@@ -98,7 +138,29 @@ static int clocksource_init (void)
return 0;
}
-core_initcall(clocksource_init);
+static struct platform_device_id imx_gpt_ids[] = {
+ {
+ .name = "imx1-gpt",
+ .driver_data = (unsigned long)®s_imx1,
+ }, {
+ .name = "imx31-gpt",
+ .driver_data = (unsigned long)®s_imx31,
+ }, {
+ /* sentinel */
+ },
+};
+
+static struct driver_d imx_gpt_driver = {
+ .name = "imx-gpt",
+ .probe = imx_gpt_probe,
+ .id_table = imx_gpt_ids,
+};
+
+static int imx_gpt_init(void)
+{
+ return register_driver(&imx_gpt_driver);
+}
+coredevice_initcall(imx_gpt_init);
/*
* Watchdog Registers
diff --git a/arch/arm/mach-imx/imx1.c b/arch/arm/mach-imx/imx1.c
index a81b244..5dd71f5 100644
--- a/arch/arm/mach-imx/imx1.c
+++ b/arch/arm/mach-imx/imx1.c
@@ -20,6 +20,7 @@
static int imx1_init(void)
{
+ add_generic_device("imx1-gpt", 0, NULL, 0x00202000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 0, NULL, 0x0021c000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 1, NULL, 0x0021c100, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 2, NULL, 0x0021c200, 0x100, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx21.c b/arch/arm/mach-imx/imx21.c
index 619a826..2a06e50 100644
--- a/arch/arm/mach-imx/imx21.c
+++ b/arch/arm/mach-imx/imx21.c
@@ -28,6 +28,7 @@ int imx_silicon_revision(void)
static int imx21_init(void)
{
+ add_generic_device("imx1-gpt", 0, NULL, 0x10003000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c
index 183a492..397ddde 100644
--- a/arch/arm/mach-imx/imx25.c
+++ b/arch/arm/mach-imx/imx25.c
@@ -48,10 +48,12 @@ static int imx25_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, &imx25_iim_pdata);
+ add_generic_device("imx31-gpt", 0, NULL, 0x53f90000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 3, NULL, 0x53f9c000, 0x1000, IORESOURCE_MEM, NULL);
+
return 0;
}
coredevice_initcall(imx25_init);
diff --git a/arch/arm/mach-imx/imx27.c b/arch/arm/mach-imx/imx27.c
index 8f0461d..6c8f3fc 100644
--- a/arch/arm/mach-imx/imx27.c
+++ b/arch/arm/mach-imx/imx27.c
@@ -72,6 +72,8 @@ static int imx27_init(void)
IORESOURCE_MEM, NULL);
imx27_init_max();
+
+ add_generic_device("imx1-gpt", 0, NULL, 0x10003000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx31.c b/arch/arm/mach-imx/imx31.c
index faad11e..08f9143 100644
--- a/arch/arm/mach-imx/imx31.c
+++ b/arch/arm/mach-imx/imx31.c
@@ -25,6 +25,7 @@ static int imx31_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x53f90000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx35.c b/arch/arm/mach-imx/imx35.c
index 6952219..7f49582 100644
--- a/arch/arm/mach-imx/imx35.c
+++ b/arch/arm/mach-imx/imx35.c
@@ -56,6 +56,7 @@ static int imx35_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x53f90000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
index 6a394bf..117bda9 100644
--- a/arch/arm/mach-imx/imx51.c
+++ b/arch/arm/mach-imx/imx51.c
@@ -78,6 +78,7 @@ static int imx51_init(void)
add_generic_device("imx_iim", 0, NULL, MX51_IIM_BASE_ADDR, SZ_4K,
IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x73fa0000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, 0x73f84000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, 0x73f88000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, 0x73f8c000, 0x1000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c
index 228e47d..9fc44e5 100644
--- a/arch/arm/mach-imx/imx53.c
+++ b/arch/arm/mach-imx/imx53.c
@@ -74,6 +74,7 @@ static int imx53_init(void)
add_generic_device("imx_iim", 0, NULL, MX53_IIM_BASE_ADDR, SZ_4K,
IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0X53fa0000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, MX53_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, MX53_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, MX53_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
@@ -81,6 +82,7 @@ static int imx53_init(void)
add_generic_device("imx31-gpio", 4, NULL, MX53_GPIO5_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 5, NULL, MX53_GPIO6_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 6, NULL, MX53_GPIO7_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+
return 0;
}
coredevice_initcall(imx53_init);
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index 085b5c8..66c44e1 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -58,6 +58,7 @@ void imx6_init_lowlevel(void)
static int imx6_init(void)
{
+ add_generic_device("imx31-gpt", 0, NULL, 0x02098000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, MX6_GPIO1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, MX6_GPIO2_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, MX6_GPIO3_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/include/mach/imx1-regs.h b/arch/arm/mach-imx/include/mach/imx1-regs.h
index f940cdb..d5ee3f5 100644
--- a/arch/arm/mach-imx/include/mach/imx1-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx1-regs.h
@@ -207,27 +207,4 @@
#define PD31_PF_TMR2OUT ( GPIO_PORTD | GPIO_PF | 31 )
#define PD31_BIN_SPI2_TXD ( GPIO_PORTD | GPIO_BIN | 31 )
-/*
- * Definitions for the clocksource driver
- */
-/* Part 1: Registers */
-# define GPT_TCTL 0x00
-# define GPT_TPRER 0x04
-# define GPT_TCMP 0x08
-# define GPT_TCR 0x0c
-# define GPT_TCN 0x10
-# define GPT_TSTAT 0x14
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<8) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (1) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#endif /* _IMX1_REGS_H */
diff --git a/arch/arm/mach-imx/include/mach/imx21-regs.h b/arch/arm/mach-imx/include/mach/imx21-regs.h
index a2c4d03..98e73ef 100644
--- a/arch/arm/mach-imx/include/mach/imx21-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx21-regs.h
@@ -107,30 +107,6 @@
#define CCSR_32K_SR (1 << 15)
-/*
- * Definitions for the clocksource driver
- */
-/* Part 1: Registers */
-# define GPT_TCTL 0x00
-# define GPT_TPRER 0x04
-# define GPT_TCMP 0x08
-# define GPT_TCR 0x0c
-# define GPT_TCN 0x10
-# define GPT_TSTAT 0x14
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_CC (1<<10) /* counter clear */
-#define TCTL_FRR (1<<8) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_CAPEN (1<<5) /* compare interrupt enable */
-#define TCTL_COMPEN (1<<4) /* compare interrupt enable */
-#define TCTL_CLKSOURCE (1) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define IMX_CS0_BASE 0xC8000000
#define IMX_CS1_BASE 0xCC000000
#define IMX_CS2_BASE 0xD0000000
diff --git a/arch/arm/mach-imx/include/mach/imx25-regs.h b/arch/arm/mach-imx/include/mach/imx25-regs.h
index 73307c4..a35d9e3 100644
--- a/arch/arm/mach-imx/include/mach/imx25-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx25-regs.h
@@ -108,33 +108,6 @@
#define CSCR_A(x) (WEIM_BASE + 8 + (x) * 0x10)
/*
- * Definitions for the clocksource driver
- *
- * These defines are using the i.MX1/27 notation
- * to reuse the clocksource code for these CPUs
- * on the i.MX35
- */
-/* Part 1: Registers */
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
-/*
* Watchdog Registers
*/
#define WCR __REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */
diff --git a/arch/arm/mach-imx/include/mach/imx27-regs.h b/arch/arm/mach-imx/include/mach/imx27-regs.h
index 19dcad9..8686a9d 100644
--- a/arch/arm/mach-imx/include/mach/imx27-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx27-regs.h
@@ -221,29 +221,6 @@
#define ESDCFG_TWTR (1 << 20)
#define ESDCFG_TXP(x) (((x) & 0x3) << 21)
-/*
- * Definitions for the clocksource driver
- */
-/* Part 1: Registers */
-# define GPT_TCTL 0x00
-# define GPT_TPRER 0x04
-# define GPT_TCMP 0x08
-# define GPT_TCR 0x0c
-# define GPT_TCN 0x10
-# define GPT_TSTAT 0x14
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<8) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (1) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define IMX_CS0_BASE 0xC0000000
#define IMX_CS1_BASE 0xC8000000
#define IMX_CS2_BASE 0xD0000000
diff --git a/arch/arm/mach-imx/include/mach/imx31-regs.h b/arch/arm/mach-imx/include/mach/imx31-regs.h
index 536bf0d..062af75 100644
--- a/arch/arm/mach-imx/include/mach/imx31-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx31-regs.h
@@ -57,33 +57,6 @@
#define IMX_CS5_BASE 0xB6000000
#define IMX_CS5_RANGE (32 * 1024 * 1024)
-/*
- * Definitions for the clocksource driver
- *
- * These defines are using the i.MX1/27 notation
- * to reuse the clocksource code for these CPUs
- * on the i.MX31
- */
-/* Part 1: Registers */
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#if 0
#define IMX_IO_BASE 0x00200000
diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h
index 91d4b9b..5f00052 100644
--- a/arch/arm/mach-imx/include/mach/imx35-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx35-regs.h
@@ -116,32 +116,4 @@
#define CSCR_L(x) (WEIM_BASE + 4 + (x) * 0x10)
#define CSCR_A(x) (WEIM_BASE + 8 + (x) * 0x10)
-/*
- * Definitions for the clocksource driver
- *
- * These defines are using the i.MX1/27 notation
- * to reuse the clocksource code for these CPUs
- * on the i.MX35
- */
-/* Part 1: Registers */
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#endif /* __ASM_ARCH_MX35_REGS_H */
-
diff --git a/arch/arm/mach-imx/include/mach/imx51-regs.h b/arch/arm/mach-imx/include/mach/imx51-regs.h
index b51aa67..c451004 100644
--- a/arch/arm/mach-imx/include/mach/imx51-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx51-regs.h
@@ -5,13 +5,6 @@
#define IMX_WDT_BASE 0x73f98000
#define IMX_IOMUXC_BASE 0x73fa8000
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
/* WEIM registers */
#define WEIM_CSxGCR1(n) (((n) * 0x18) + 0x00)
#define WEIM_CSxGCR2(n) (((n) * 0x18) + 0x04)
@@ -22,18 +15,6 @@
#define WEIM_WIAR 0x94
#define WEIM_EAR 0x98
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define MX51_IROM_BASE_ADDR 0x0
/*
diff --git a/arch/arm/mach-imx/include/mach/imx53-regs.h b/arch/arm/mach-imx/include/mach/imx53-regs.h
index 8fefc54..e57d1ab 100644
--- a/arch/arm/mach-imx/include/mach/imx53-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx53-regs.h
@@ -5,25 +5,6 @@
#define IMX_WDT_BASE 0X53F98000
#define IMX_IOMUXC_BASE 0X53FA8000
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define MX53_IROM_BASE_ADDR 0x0
/*
diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h
index c7b7481..eca4fa6 100644
--- a/arch/arm/mach-imx/include/mach/imx6-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx6-regs.h
@@ -5,25 +5,6 @@
#define IMX_WDT_BASE 0x020bc000
#define IMX_IOMUXC_BASE 0x020e0000
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define MX6_AIPS1_ARB_BASE_ADDR 0x02000000
#define MX6_AIPS2_ARB_BASE_ADDR 0x02100000
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 07/15] ARM i.MX: implement clocksource as driver
2012-09-12 20:06 ` [PATCH 07/15] ARM i.MX: implement clocksource as driver Sascha Hauer
@ 2012-09-17 16:17 ` Sascha Hauer
0 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-17 16:17 UTC (permalink / raw)
To: barebox
On Wed, Sep 12, 2012 at 10:06:39PM +0200, Sascha Hauer wrote:
> To get rid of the register definitions in the SoC header files.
> platform_device_id is used to distinguish between gpt types.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> arch/arm/mach-imx/clocksource.c | 72 +++++++++++++++++++++++++--
> arch/arm/mach-imx/imx1.c | 1 +
> arch/arm/mach-imx/imx21.c | 1 +
> arch/arm/mach-imx/imx25.c | 2 +
> arch/arm/mach-imx/imx27.c | 2 +
> arch/arm/mach-imx/imx31.c | 1 +
> arch/arm/mach-imx/imx35.c | 1 +
> arch/arm/mach-imx/imx51.c | 1 +
> arch/arm/mach-imx/imx53.c | 2 +
> arch/arm/mach-imx/imx6.c | 1 +
> arch/arm/mach-imx/include/mach/imx1-regs.h | 23 ---------
> arch/arm/mach-imx/include/mach/imx21-regs.h | 24 ---------
> arch/arm/mach-imx/include/mach/imx25-regs.h | 27 ----------
> arch/arm/mach-imx/include/mach/imx27-regs.h | 23 ---------
> arch/arm/mach-imx/include/mach/imx31-regs.h | 27 ----------
> arch/arm/mach-imx/include/mach/imx35-regs.h | 28 -----------
> arch/arm/mach-imx/include/mach/imx51-regs.h | 19 -------
> arch/arm/mach-imx/include/mach/imx53-regs.h | 19 -------
> arch/arm/mach-imx/include/mach/imx6-regs.h | 19 -------
> 19 files changed, 79 insertions(+), 214 deletions(-)
>
> diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
> index 4e77ece..166710c 100644
> --- a/arch/arm/mach-imx/clocksource.c
> +++ b/arch/arm/mach-imx/clocksource.c
> @@ -32,17 +32,46 @@
> #include <common.h>
> #include <init.h>
> #include <clock.h>
> +#include <errno.h>
> #include <notifier.h>
> #include <mach/imx-regs.h>
> #include <mach/clock.h>
> #include <io.h>
>
> -#define GPT(x) __REG(IMX_TIM1_BASE + (x))
> -#define timer_base IOMEM(IMX_TIM1_BASE)
> +/* Part 1: Registers */
> +# define GPT_TCTL 0x00
> +# define GPT_TPRER 0x04
> +
> +/* Part 2: Bitfields */
> +#define TCTL_SWR (1<<15) /* Software reset */
> +#define TCTL_FRR (1<<8) /* Freerun / restart */
> +#define TCTL_CAP (3<<6) /* Capture Edge */
> +#define TCTL_OM (1<<5) /* output mode */
> +#define TCTL_IRQEN (1<<4) /* interrupt enable */
> +#define TCTL_CLKSOURCE (1) /* Clock source bit position */
> +#define TCTL_TEN (1) /* Timer enable */
> +#define TPRER_PRES (0xff) /* Prescale */
> +#define TSTAT_CAPT (1<<1) /* Capture event */
> +#define TSTAT_COMP (1) /* Compare event */
This doesn't work on i.MX31 upwards as I haven't realized that not only
the registers differ, but also the bits. Replaced this patch with the
following:
8<-----------------------------------------------------------
From 6a2262de50b2000dd353f1a2d3b00316bc9e18c1 Mon Sep 17 00:00:00 2001
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Sun, 9 Sep 2012 21:02:09 +0200
Subject: [PATCH] ARM i.MX: implement clocksource as driver
To get rid of the register definitions in the SoC header files.
platform_device_id is used to distinguish between gpt types.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/clocksource.c | 76 +++++++++++++++++++++++----
arch/arm/mach-imx/imx1.c | 1 +
arch/arm/mach-imx/imx21.c | 1 +
arch/arm/mach-imx/imx25.c | 2 +
arch/arm/mach-imx/imx27.c | 2 +
arch/arm/mach-imx/imx31.c | 1 +
arch/arm/mach-imx/imx35.c | 1 +
arch/arm/mach-imx/imx51.c | 1 +
arch/arm/mach-imx/imx53.c | 2 +
arch/arm/mach-imx/imx6.c | 1 +
arch/arm/mach-imx/include/mach/imx1-regs.h | 23 --------
arch/arm/mach-imx/include/mach/imx21-regs.h | 24 ---------
arch/arm/mach-imx/include/mach/imx25-regs.h | 27 ----------
arch/arm/mach-imx/include/mach/imx27-regs.h | 23 --------
arch/arm/mach-imx/include/mach/imx31-regs.h | 27 ----------
arch/arm/mach-imx/include/mach/imx35-regs.h | 28 ----------
arch/arm/mach-imx/include/mach/imx51-regs.h | 19 -------
arch/arm/mach-imx/include/mach/imx53-regs.h | 19 -------
arch/arm/mach-imx/include/mach/imx6-regs.h | 19 -------
19 files changed, 79 insertions(+), 218 deletions(-)
diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index 4e77ece..746ecc8 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -32,17 +32,45 @@
#include <common.h>
#include <init.h>
#include <clock.h>
+#include <errno.h>
#include <notifier.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
#include <io.h>
-#define GPT(x) __REG(IMX_TIM1_BASE + (x))
-#define timer_base IOMEM(IMX_TIM1_BASE)
+/* Part 1: Registers */
+# define GPT_TCTL 0x00
+# define GPT_TPRER 0x04
+
+/* Part 2: Bitfields */
+#define TCTL_SWR (1 << 15) /* Software reset */
+#define IMX1_TCTL_FRR (1 << 8) /* Freerun / restart */
+#define IMX31_TCTL_FRR (1 << 9) /* Freerun / restart */
+#define IMX1_TCTL_CLKSOURCE_IPG (1 << 1) /* Clock source bit position */
+#define IMX31_TCTL_CLKSOURCE_IPG (1 << 6) /* Clock source bit position */
+#define TCTL_TEN (1 << 0) /* Timer enable */
+
+struct imx_gpt_regs {
+ unsigned int tcn;
+ uint32_t tctl_val;
+};
+
+static struct imx_gpt_regs regs_imx1 = {
+ .tcn = 0x10,
+ .tctl_val = IMX1_TCTL_FRR | IMX1_TCTL_CLKSOURCE_IPG | TCTL_TEN,
+};
+
+static struct imx_gpt_regs regs_imx31 = {
+ .tcn = 0x24,
+ .tctl_val = IMX31_TCTL_FRR | IMX31_TCTL_CLKSOURCE_IPG | TCTL_TEN,
+};
+
+static struct imx_gpt_regs *regs;
+static void __iomem *timer_base;
static uint64_t imx_clocksource_read(void)
{
- return readl(timer_base + GPT_TCN);
+ return readl(timer_base + regs->tcn);
}
static struct clocksource cs = {
@@ -61,10 +89,20 @@ static struct notifier_block imx_clock_notifier = {
.notifier_call = imx_clocksource_clock_change,
};
-static int clocksource_init (void)
+static int imx_gpt_probe(struct device_d *dev)
{
int i;
- uint32_t val;
+ int ret;
+
+ /* one timer is enough */
+ if (timer_base)
+ return -EBUSY;
+
+ ret = dev_get_drvdata(dev, (unsigned long *)®s);
+ if (ret)
+ return ret;
+
+ timer_base = dev_request_mem_region(dev, 0);
/* setup GP Timer 1 */
writel(TCTL_SWR, timer_base + GPT_TCTL);
@@ -85,9 +123,7 @@ static int clocksource_init (void)
writel(0, timer_base + GPT_TCTL); /* We have no udelay by now */
writel(0, timer_base + GPT_TPRER);
- val = readl(timer_base + GPT_TCTL);
- val |= TCTL_FRR | (1 << TCTL_CLKSOURCE) | TCTL_TEN; /* Freerun Mode, PERCLK1 input */
- writel(val, timer_base + GPT_TCTL);
+ writel(regs->tctl_val, timer_base + GPT_TCTL);
cs.mult = clocksource_hz2mult(imx_get_gptclk(), cs.shift);
@@ -98,7 +134,29 @@ static int clocksource_init (void)
return 0;
}
-core_initcall(clocksource_init);
+static struct platform_device_id imx_gpt_ids[] = {
+ {
+ .name = "imx1-gpt",
+ .driver_data = (unsigned long)®s_imx1,
+ }, {
+ .name = "imx31-gpt",
+ .driver_data = (unsigned long)®s_imx31,
+ }, {
+ /* sentinel */
+ },
+};
+
+static struct driver_d imx_gpt_driver = {
+ .name = "imx-gpt",
+ .probe = imx_gpt_probe,
+ .id_table = imx_gpt_ids,
+};
+
+static int imx_gpt_init(void)
+{
+ return register_driver(&imx_gpt_driver);
+}
+coredevice_initcall(imx_gpt_init);
/*
* Watchdog Registers
diff --git a/arch/arm/mach-imx/imx1.c b/arch/arm/mach-imx/imx1.c
index a81b244..5dd71f5 100644
--- a/arch/arm/mach-imx/imx1.c
+++ b/arch/arm/mach-imx/imx1.c
@@ -20,6 +20,7 @@
static int imx1_init(void)
{
+ add_generic_device("imx1-gpt", 0, NULL, 0x00202000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 0, NULL, 0x0021c000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 1, NULL, 0x0021c100, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 2, NULL, 0x0021c200, 0x100, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx21.c b/arch/arm/mach-imx/imx21.c
index 619a826..2a06e50 100644
--- a/arch/arm/mach-imx/imx21.c
+++ b/arch/arm/mach-imx/imx21.c
@@ -28,6 +28,7 @@ int imx_silicon_revision(void)
static int imx21_init(void)
{
+ add_generic_device("imx1-gpt", 0, NULL, 0x10003000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c
index 183a492..397ddde 100644
--- a/arch/arm/mach-imx/imx25.c
+++ b/arch/arm/mach-imx/imx25.c
@@ -48,10 +48,12 @@ static int imx25_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, &imx25_iim_pdata);
+ add_generic_device("imx31-gpt", 0, NULL, 0x53f90000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 3, NULL, 0x53f9c000, 0x1000, IORESOURCE_MEM, NULL);
+
return 0;
}
coredevice_initcall(imx25_init);
diff --git a/arch/arm/mach-imx/imx27.c b/arch/arm/mach-imx/imx27.c
index 8f0461d..6c8f3fc 100644
--- a/arch/arm/mach-imx/imx27.c
+++ b/arch/arm/mach-imx/imx27.c
@@ -72,6 +72,8 @@ static int imx27_init(void)
IORESOURCE_MEM, NULL);
imx27_init_max();
+
+ add_generic_device("imx1-gpt", 0, NULL, 0x10003000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx1-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx31.c b/arch/arm/mach-imx/imx31.c
index faad11e..08f9143 100644
--- a/arch/arm/mach-imx/imx31.c
+++ b/arch/arm/mach-imx/imx31.c
@@ -25,6 +25,7 @@ static int imx31_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x53f90000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx35.c b/arch/arm/mach-imx/imx35.c
index 6952219..7f49582 100644
--- a/arch/arm/mach-imx/imx35.c
+++ b/arch/arm/mach-imx/imx35.c
@@ -56,6 +56,7 @@ static int imx35_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x53f90000, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
index 6a394bf..117bda9 100644
--- a/arch/arm/mach-imx/imx51.c
+++ b/arch/arm/mach-imx/imx51.c
@@ -78,6 +78,7 @@ static int imx51_init(void)
add_generic_device("imx_iim", 0, NULL, MX51_IIM_BASE_ADDR, SZ_4K,
IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x73fa0000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, 0x73f84000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, 0x73f88000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, 0x73f8c000, 0x1000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c
index 228e47d..9fc44e5 100644
--- a/arch/arm/mach-imx/imx53.c
+++ b/arch/arm/mach-imx/imx53.c
@@ -74,6 +74,7 @@ static int imx53_init(void)
add_generic_device("imx_iim", 0, NULL, MX53_IIM_BASE_ADDR, SZ_4K,
IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0X53fa0000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, MX53_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, MX53_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, MX53_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
@@ -81,6 +82,7 @@ static int imx53_init(void)
add_generic_device("imx31-gpio", 4, NULL, MX53_GPIO5_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 5, NULL, MX53_GPIO6_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 6, NULL, MX53_GPIO7_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+
return 0;
}
coredevice_initcall(imx53_init);
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index 085b5c8..66c44e1 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -58,6 +58,7 @@ void imx6_init_lowlevel(void)
static int imx6_init(void)
{
+ add_generic_device("imx31-gpt", 0, NULL, 0x02098000, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 0, NULL, MX6_GPIO1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 1, NULL, MX6_GPIO2_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpio", 2, NULL, MX6_GPIO3_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/include/mach/imx1-regs.h b/arch/arm/mach-imx/include/mach/imx1-regs.h
index f940cdb..d5ee3f5 100644
--- a/arch/arm/mach-imx/include/mach/imx1-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx1-regs.h
@@ -207,27 +207,4 @@
#define PD31_PF_TMR2OUT ( GPIO_PORTD | GPIO_PF | 31 )
#define PD31_BIN_SPI2_TXD ( GPIO_PORTD | GPIO_BIN | 31 )
-/*
- * Definitions for the clocksource driver
- */
-/* Part 1: Registers */
-# define GPT_TCTL 0x00
-# define GPT_TPRER 0x04
-# define GPT_TCMP 0x08
-# define GPT_TCR 0x0c
-# define GPT_TCN 0x10
-# define GPT_TSTAT 0x14
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<8) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (1) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#endif /* _IMX1_REGS_H */
diff --git a/arch/arm/mach-imx/include/mach/imx21-regs.h b/arch/arm/mach-imx/include/mach/imx21-regs.h
index a2c4d03..98e73ef 100644
--- a/arch/arm/mach-imx/include/mach/imx21-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx21-regs.h
@@ -107,30 +107,6 @@
#define CCSR_32K_SR (1 << 15)
-/*
- * Definitions for the clocksource driver
- */
-/* Part 1: Registers */
-# define GPT_TCTL 0x00
-# define GPT_TPRER 0x04
-# define GPT_TCMP 0x08
-# define GPT_TCR 0x0c
-# define GPT_TCN 0x10
-# define GPT_TSTAT 0x14
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_CC (1<<10) /* counter clear */
-#define TCTL_FRR (1<<8) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_CAPEN (1<<5) /* compare interrupt enable */
-#define TCTL_COMPEN (1<<4) /* compare interrupt enable */
-#define TCTL_CLKSOURCE (1) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define IMX_CS0_BASE 0xC8000000
#define IMX_CS1_BASE 0xCC000000
#define IMX_CS2_BASE 0xD0000000
diff --git a/arch/arm/mach-imx/include/mach/imx25-regs.h b/arch/arm/mach-imx/include/mach/imx25-regs.h
index 73307c4..a35d9e3 100644
--- a/arch/arm/mach-imx/include/mach/imx25-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx25-regs.h
@@ -108,33 +108,6 @@
#define CSCR_A(x) (WEIM_BASE + 8 + (x) * 0x10)
/*
- * Definitions for the clocksource driver
- *
- * These defines are using the i.MX1/27 notation
- * to reuse the clocksource code for these CPUs
- * on the i.MX35
- */
-/* Part 1: Registers */
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
-/*
* Watchdog Registers
*/
#define WCR __REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */
diff --git a/arch/arm/mach-imx/include/mach/imx27-regs.h b/arch/arm/mach-imx/include/mach/imx27-regs.h
index 19dcad9..8686a9d 100644
--- a/arch/arm/mach-imx/include/mach/imx27-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx27-regs.h
@@ -221,29 +221,6 @@
#define ESDCFG_TWTR (1 << 20)
#define ESDCFG_TXP(x) (((x) & 0x3) << 21)
-/*
- * Definitions for the clocksource driver
- */
-/* Part 1: Registers */
-# define GPT_TCTL 0x00
-# define GPT_TPRER 0x04
-# define GPT_TCMP 0x08
-# define GPT_TCR 0x0c
-# define GPT_TCN 0x10
-# define GPT_TSTAT 0x14
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<8) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (1) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define IMX_CS0_BASE 0xC0000000
#define IMX_CS1_BASE 0xC8000000
#define IMX_CS2_BASE 0xD0000000
diff --git a/arch/arm/mach-imx/include/mach/imx31-regs.h b/arch/arm/mach-imx/include/mach/imx31-regs.h
index 536bf0d..062af75 100644
--- a/arch/arm/mach-imx/include/mach/imx31-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx31-regs.h
@@ -57,33 +57,6 @@
#define IMX_CS5_BASE 0xB6000000
#define IMX_CS5_RANGE (32 * 1024 * 1024)
-/*
- * Definitions for the clocksource driver
- *
- * These defines are using the i.MX1/27 notation
- * to reuse the clocksource code for these CPUs
- * on the i.MX31
- */
-/* Part 1: Registers */
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#if 0
#define IMX_IO_BASE 0x00200000
diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h
index 91d4b9b..5f00052 100644
--- a/arch/arm/mach-imx/include/mach/imx35-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx35-regs.h
@@ -116,32 +116,4 @@
#define CSCR_L(x) (WEIM_BASE + 4 + (x) * 0x10)
#define CSCR_A(x) (WEIM_BASE + 8 + (x) * 0x10)
-/*
- * Definitions for the clocksource driver
- *
- * These defines are using the i.MX1/27 notation
- * to reuse the clocksource code for these CPUs
- * on the i.MX35
- */
-/* Part 1: Registers */
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#endif /* __ASM_ARCH_MX35_REGS_H */
-
diff --git a/arch/arm/mach-imx/include/mach/imx51-regs.h b/arch/arm/mach-imx/include/mach/imx51-regs.h
index b51aa67..c451004 100644
--- a/arch/arm/mach-imx/include/mach/imx51-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx51-regs.h
@@ -5,13 +5,6 @@
#define IMX_WDT_BASE 0x73f98000
#define IMX_IOMUXC_BASE 0x73fa8000
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
/* WEIM registers */
#define WEIM_CSxGCR1(n) (((n) * 0x18) + 0x00)
#define WEIM_CSxGCR2(n) (((n) * 0x18) + 0x04)
@@ -22,18 +15,6 @@
#define WEIM_WIAR 0x94
#define WEIM_EAR 0x98
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define MX51_IROM_BASE_ADDR 0x0
/*
diff --git a/arch/arm/mach-imx/include/mach/imx53-regs.h b/arch/arm/mach-imx/include/mach/imx53-regs.h
index 8fefc54..e57d1ab 100644
--- a/arch/arm/mach-imx/include/mach/imx53-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx53-regs.h
@@ -5,25 +5,6 @@
#define IMX_WDT_BASE 0X53F98000
#define IMX_IOMUXC_BASE 0X53FA8000
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define MX53_IROM_BASE_ADDR 0x0
/*
diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h
index c7b7481..eca4fa6 100644
--- a/arch/arm/mach-imx/include/mach/imx6-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx6-regs.h
@@ -5,25 +5,6 @@
#define IMX_WDT_BASE 0x020bc000
#define IMX_IOMUXC_BASE 0x020e0000
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define MX6_AIPS1_ARB_BASE_ADDR 0x02000000
#define MX6_AIPS2_ARB_BASE_ADDR 0x02100000
--
1.7.10.4
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 08/15] serial i.MX: oftree support
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (6 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 07/15] ARM i.MX: implement clocksource as driver Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 09/15] net fec_imx: " Sascha Hauer
` (7 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/serial/serial_imx.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index 1e1e8e3..9d15038 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -357,10 +357,23 @@ static void imx_serial_remove(struct device_d *dev)
free(priv);
}
+static __maybe_unused struct of_device_id imx_serial_dt_ids[] = {
+ {
+ .compatible = "fsl,imx1-uart",
+ .data = 0,
+ }, {
+ .compatible = "fsl,imx21-uart",
+ .data = 1,
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d imx_serial_driver = {
- .name = "imx_serial",
- .probe = imx_serial_probe,
+ .name = "imx_serial",
+ .probe = imx_serial_probe,
.remove = imx_serial_remove,
+ .of_compatible = DRV_OF_COMPAT(imx_serial_dt_ids),
};
static int imx_serial_init(void)
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 09/15] net fec_imx: oftree support
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (7 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 08/15] serial i.MX: oftree support Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 10/15] spi imx: dt support Sascha Hauer
` (6 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/fec_imx.c | 34 +++++++++++++++++++++++++++-------
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 599a9b4..d9a97b8 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -617,6 +617,7 @@ static int fec_probe(struct device_d *dev)
struct eth_device *edev;
struct fec_priv *fec;
void *base;
+
#ifdef CONFIG_ARCH_IMX27
PCCR0 |= PCCR0_FEC_EN;
#endif
@@ -656,13 +657,19 @@ static int fec_probe(struct device_d *dev)
fec_alloc_receive_packets(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE);
- fec->xcv_type = pdata->xcv_type;
+ if (pdata)
+ fec->xcv_type = pdata->xcv_type;
+ else
+ fec->xcv_type = MII100;
if (fec->xcv_type != SEVENWIRE) {
fec->miidev.read = fec_miidev_read;
fec->miidev.write = fec_miidev_write;
- fec->miidev.address = pdata->phy_addr;
- fec->miidev.flags = pdata->xcv_type == MII10 ? MIIDEV_FORCE_10 : 0;
+ if (pdata) {
+ fec->miidev.address = pdata->phy_addr;
+ fec->miidev.flags = pdata->xcv_type == MII10 ? MIIDEV_FORCE_10 : 0;
+ } else
+ fec->miidev.address = 0;
fec->miidev.edev = edev;
fec->miidev.parent = dev;
@@ -680,19 +687,32 @@ static void fec_remove(struct device_d *dev)
fec_halt(&fec->edev);
}
+static __maybe_unused struct of_device_id imx_fec_dt_ids[] = {
+ {
+ .compatible = "fsl,imx25-fec",
+ }, {
+ .compatible = "fsl,imx27-fec",
+ }, {
+ .compatible = "fsl,imx6q-fec",
+ }, {
+ /* sentinel */
+ }
+};
+
/**
* Driver description for registering
*/
static struct driver_d fec_driver = {
- .name = "fec_imx",
- .probe = fec_probe,
+ .name = "fec_imx",
+ .probe = fec_probe,
.remove = fec_remove,
+ .of_compatible = DRV_OF_COMPAT(imx_fec_dt_ids),
};
static int fec_register(void)
{
- register_driver(&fec_driver);
- return 0;
+ register_driver(&fec_driver);
+ return 0;
}
device_initcall(fec_register);
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 10/15] spi imx: dt support
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (8 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 09/15] net fec_imx: " Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 11/15] mfd mc13xxx: Add devicetree support Sascha Hauer
` (5 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/spi/imx_spi.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 80a1450..299c1a4 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -24,6 +24,7 @@
#include <spi/spi.h>
#include <xfuncs.h>
#include <io.h>
+#include <errno.h>
#include <gpio.h>
#include <mach/spi.h>
#include <mach/generic.h>
@@ -495,6 +496,32 @@ static struct spi_imx_devtype_data spi_imx_devtype_data[] = {
#endif
};
+static int imx_spi_dt_probe(struct imx_spi *imx)
+{
+ struct device_node *node = imx->master.dev->device_node;
+ int ret, i;
+ u32 num_cs;
+
+ if (!node)
+ return -ENODEV;
+
+ ret = of_property_read_u32(node, "fsl,spi-num-chipselects", &num_cs);
+ if (ret)
+ return ret;
+
+ imx->master.num_chipselect = num_cs;
+ imx->cs_array = xzalloc(sizeof(u32) * num_cs);
+
+ for (i = 0; i < num_cs; i++) {
+ int cs_gpio = of_get_named_gpio(node, "cs-gpios", i);
+ imx->cs_array[i] = cs_gpio;
+ }
+
+ spi_of_register_slaves(&imx->master, node);
+
+ return 0;
+}
+
static int imx_spi_probe(struct device_d *dev)
{
struct spi_master *master;
@@ -509,8 +536,13 @@ static int imx_spi_probe(struct device_d *dev)
master->setup = imx_spi_setup;
master->transfer = imx_spi_transfer;
- master->num_chipselect = pdata->num_chipselect;
- imx->cs_array = pdata->chipselect;
+ if (pdata) {
+ master->num_chipselect = pdata->num_chipselect;
+ imx->cs_array = pdata->chipselect;
+ } else {
+ if (IS_ENABLED(CONFIG_OFDEVICE))
+ imx_spi_dt_probe(imx);
+ }
#ifdef CONFIG_DRIVER_SPI_IMX_0_0
if (cpu_is_mx27())
@@ -536,9 +568,22 @@ static int imx_spi_probe(struct device_d *dev)
return 0;
}
+static __maybe_unused struct of_device_id imx_spi_dt_ids[] = {
+ {
+ .compatible = "fsl,imx27-cspi",
+ }, {
+ .compatible = "fsl,imx35-cspi",
+ }, {
+ .compatible = "fsl,imx51-ecspi",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d imx_spi_driver = {
.name = "imx_spi",
.probe = imx_spi_probe,
+ .of_compatible = DRV_OF_COMPAT(imx_spi_dt_ids),
};
static int imx_spi_init(void)
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 11/15] mfd mc13xxx: Add devicetree support
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (9 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 10/15] spi imx: dt support Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 12/15] cfi-flash: Add devicetree probe support Sascha Hauer
` (4 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mfd/mc13xxx.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/mfd/mc13xxx.c b/drivers/mfd/mc13xxx.c
index a62eca8..4577816 100644
--- a/drivers/mfd/mc13xxx.c
+++ b/drivers/mfd/mc13xxx.c
@@ -336,6 +336,16 @@ static int mc_probe(struct device_d *dev, enum mc13xxx_mode mode)
return 0;
}
+static __maybe_unused struct of_device_id mc13892_dt_ids[] = {
+ {
+ .compatible = "fsl,mc13892",
+ }, {
+ .compatible = "fsl,mc13783",
+ }, {
+ /* sentinel */
+ }
+};
+
#ifdef CONFIG_I2C
static int mc_i2c_probe(struct device_d *dev)
{
@@ -345,6 +355,7 @@ static int mc_i2c_probe(struct device_d *dev)
static struct driver_d mc_i2c_driver = {
.name = "mc13xxx-i2c",
.probe = mc_i2c_probe,
+ .of_compatible = DRV_OF_COMPAT(mc13892_dt_ids),
};
static int mc_i2c_init(void)
@@ -363,6 +374,7 @@ static int mc_spi_probe(struct device_d *dev)
static struct driver_d mc_spi_driver = {
.name = "mc13xxx-spi",
.probe = mc_spi_probe,
+ .of_compatible = DRV_OF_COMPAT(mc13892_dt_ids),
};
static int mc_spi_init(void)
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 12/15] cfi-flash: Add devicetree probe support
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (10 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 11/15] mfd mc13xxx: Add devicetree support Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 13/15] mci i.MX esdhc: Add oftree support Sascha Hauer
` (3 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/nor/cfi_flash.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 16885c0..a8eebf5 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -982,6 +982,7 @@ static void cfi_init_mtd(struct flash_info *info)
static int cfi_probe (struct device_d *dev)
{
struct flash_info *info = xzalloc(sizeof(*info));
+ int cfinum;
dev->priv = (void *)info;
@@ -1000,7 +1001,12 @@ static int cfi_probe (struct device_d *dev)
dev_info(dev, "found cfi flash at %p, size %ld\n",
info->base, info->size);
- info->cdev.name = asprintf("nor%d", dev->id);
+ if (dev->id < 0)
+ cfinum = cdev_find_free_index("nor");
+ else
+ cfinum = dev->id;
+
+ info->cdev.name = asprintf("nor%d", cfinum);
info->cdev.size = info->size;
info->cdev.dev = dev;
info->cdev.ops = &cfi_ops;
@@ -1011,19 +1017,30 @@ static int cfi_probe (struct device_d *dev)
#endif
devfs_create(&info->cdev);
+ if (dev->device_node)
+ of_parse_partitions(info->cdev.name, dev->device_node);
+
return 0;
}
+static __maybe_unused struct of_device_id cfi_dt_ids[] = {
+ {
+ .compatible = "cfi-flash",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d cfi_driver = {
- .name = "cfi_flash",
- .probe = cfi_probe,
- .info = cfi_info,
+ .name = "cfi_flash",
+ .probe = cfi_probe,
+ .info = cfi_info,
+ .of_compatible = DRV_OF_COMPAT(cfi_dt_ids),
};
static int cfi_init(void)
{
- return register_driver(&cfi_driver);
+ return register_driver(&cfi_driver);
}
device_initcall(cfi_init);
-
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 13/15] mci i.MX esdhc: Add oftree support
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (11 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 12/15] cfi-flash: Add devicetree probe support Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 14/15] ARM i.MX: add devicetree support for gpio driver Sascha Hauer
` (2 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 585cab9..d9ef71b 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -567,16 +567,31 @@ static int fsl_esdhc_probe(struct device_d *dev)
return 0;
}
+static struct of_device_id fsl_esdhc_compatible[] = {
+ {
+ .compatible = "fsl,imx51-esdhc",
+ .data = (void *)0,
+ }, {
+ .compatible = "fsl,imx53-esdhc",
+ .data = (void *)0,
+ }, {
+ .compatible = "fsl,imx6q-usdhc",
+ .data = (void *)0,
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d fsl_esdhc_driver = {
- .name = "imx-esdhc",
- .probe = fsl_esdhc_probe,
+ .name = "imx-esdhc",
+ .probe = fsl_esdhc_probe,
+ .of_compatible = fsl_esdhc_compatible,
};
static int fsl_esdhc_init_driver(void)
{
- register_driver(&fsl_esdhc_driver);
- return 0;
+ register_driver(&fsl_esdhc_driver);
+ return 0;
}
device_initcall(fsl_esdhc_init_driver);
-
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 14/15] ARM i.MX: add devicetree support for gpio driver
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (12 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 13/15] mci i.MX esdhc: Add oftree support Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-12 20:06 ` [PATCH 15/15] ARM i.MX: Add devicetree support for clocksource driver Sascha Hauer
2012-09-20 18:45 ` [PATCH] devicetree probe support Jean-Christophe PLAGNIOL-VILLARD
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/gpio.c | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/gpio.c b/arch/arm/mach-imx/gpio.c
index b7426fe..df0b455 100644
--- a/arch/arm/mach-imx/gpio.c
+++ b/arch/arm/mach-imx/gpio.c
@@ -136,7 +136,13 @@ static int imx_gpio_probe(struct device_d *dev)
imxgpio = xzalloc(sizeof(*imxgpio));
imxgpio->base = dev_request_mem_region(dev, 0);
imxgpio->chip.ops = &imx_gpio_ops;
- imxgpio->chip.base = -1;
+ if (dev->id < 0) {
+ imxgpio->chip.base = of_alias_get_id(dev->device_node, "gpio");
+ if (imxgpio->chip.base < 0)
+ return imxgpio->chip.base;
+ } else {
+ imxgpio->chip.base = dev->id * 32;
+ }
imxgpio->chip.ngpio = 32;
imxgpio->chip.dev = dev;
imxgpio->regs = regs;
@@ -147,6 +153,36 @@ static int imx_gpio_probe(struct device_d *dev)
return 0;
}
+static __maybe_unused struct of_device_id imx_gpio_dt_ids[] = {
+ {
+ .compatible = "fsl,imx1-gpio",
+ .data = (unsigned long)®s_imx1,
+ }, {
+ .compatible = "fsl,imx21-gpio",
+ .data = (unsigned long)®s_imx1,
+ }, {
+ .compatible = "fsl,imx27-gpio",
+ .data = (unsigned long)®s_imx1,
+ }, {
+ .compatible = "fsl,imx31-gpio",
+ .data = (unsigned long)®s_imx31,
+ }, {
+ .compatible = "fsl,imx35-gpio",
+ .data = (unsigned long)®s_imx31,
+ }, {
+ .compatible = "fsl,imx51-gpio",
+ .data = (unsigned long)®s_imx31,
+ }, {
+ .compatible = "fsl,imx53-gpio",
+ .data = (unsigned long)®s_imx31,
+ }, {
+ .compatible = "fsl,imx6q-gpio",
+ .data = (unsigned long)®s_imx31,
+ }, {
+ /* sentinel */
+ }
+};
+
static struct platform_device_id imx_gpio_ids[] = {
{
.name = "imx1-gpio",
@@ -162,6 +198,7 @@ static struct platform_device_id imx_gpio_ids[] = {
static struct driver_d imx_gpio_driver = {
.name = "imx-gpio",
.probe = imx_gpio_probe,
+ .of_compatible = DRV_OF_COMPAT(imx_gpio_dt_ids),
.id_table = imx_gpio_ids,
};
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 15/15] ARM i.MX: Add devicetree support for clocksource driver
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (13 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 14/15] ARM i.MX: add devicetree support for gpio driver Sascha Hauer
@ 2012-09-12 20:06 ` Sascha Hauer
2012-09-20 18:45 ` [PATCH] devicetree probe support Jean-Christophe PLAGNIOL-VILLARD
15 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-12 20:06 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/clocksource.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index 166710c..31a5f25 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -138,6 +138,18 @@ static int imx_gpt_probe(struct device_d *dev)
return 0;
}
+static __maybe_unused struct of_device_id imx_gpt_dt_ids[] = {
+ {
+ .compatible = "fsl,imx1-gpt",
+ .data = (unsigned long)®s_imx1,
+ }, {
+ .compatible = "fsl,imx31-gpt",
+ .data = (unsigned long)®s_imx31,
+ }, {
+ /* sentinel */
+ }
+};
+
static struct platform_device_id imx_gpt_ids[] = {
{
.name = "imx1-gpt",
@@ -153,6 +165,7 @@ static struct platform_device_id imx_gpt_ids[] = {
static struct driver_d imx_gpt_driver = {
.name = "imx-gpt",
.probe = imx_gpt_probe,
+ .of_compatible = DRV_OF_COMPAT(imx_gpt_dt_ids),
.id_table = imx_gpt_ids,
};
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] devicetree probe support
2012-09-12 20:06 [PATCH] devicetree probe support Sascha Hauer
` (14 preceding siblings ...)
2012-09-12 20:06 ` [PATCH 15/15] ARM i.MX: Add devicetree support for clocksource driver Sascha Hauer
@ 2012-09-20 18:45 ` Jean-Christophe PLAGNIOL-VILLARD
2012-09-20 18:51 ` [PATCH 1/1] fb: add it's own bus for fb devices Jean-Christophe PLAGNIOL-VILLARD
15 siblings, 1 reply; 21+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-09-20 18:45 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 22:06 Wed 12 Sep , Sascha Hauer wrote:
> Hi All,
>
> The following patch series adds support for probing barebox from
> devicetree.
>
> Most of the of helper code is taken directly from the Linux Kernel,
> only little glue code is needed to populate the barebox devicetree
> from a dtb.
>
> Currently the dtb can be probed with 'oftree -p <dtb>'. After calling
> this command the devices found in the dtb are probed. Devices which
> were present before are not probed again, instead the corresponding
> device nodes are attached to the barebox devices.
>
> Further directions could be that barebox takes the dtb directly from
> a first stage loader, so a second stage barebox could be started just
> like a Linux Kernel. I have some experimental code for that. Another
> possibility would be to compile a dtb into barebox, but this is not
> done yet.
>
> This series contains support for the basic probing, GPIO, SPI and
> several i.MX devices. The devicetree probe support nearly compiles
> away if disabled and takes about 6k in an uncompressed image when
> enabled.
>
> Here is an example session:
>
> barebox@Phytec phyCORE-i.MX27:/ oftree -p mnt/tftp/sha-oftree-pcm038
> barebox@Phytec phyCORE-i.MX27:/ devinfo 1000c000.serial
> resources:
> num : 0
> start : 0x1000c000
> size : 0x00001000
> driver: imx_serial
>
> no info available for 1000c000.serial
> no parameters available
>
> device node: /soc/aipi@10000000/serial@1000c000
> serial@1000c000 {
> compatible: "fsl,imx27-uart", "fsl,imx21-uart"
> reg: <0x1000c000 0x1000>
> interrupts: <0x12>
> status: "okay"
> fsl,uart-has-rtscts:
> };
this break the fb support as those framework register device
whith resource but that may not init as the start of the ressource is
screen_base which could be 0 as no mode is selected
we really need to finish to clean the bus before applying this one
Best Regards,
J.
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/1] fb: add it's own bus for fb devices
2012-09-20 18:45 ` [PATCH] devicetree probe support Jean-Christophe PLAGNIOL-VILLARD
@ 2012-09-20 18:51 ` Jean-Christophe PLAGNIOL-VILLARD
2012-09-20 21:17 ` Sascha Hauer
0 siblings, 1 reply; 21+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-09-20 18:51 UTC (permalink / raw)
To: barebox
This is need for oftree device probing
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
drivers/video/fb.c | 25 +++++++++++++++++++++----
include/fb.h | 2 ++
2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index d885570..127723c 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -125,6 +125,7 @@ int register_framebuffer(struct fb_info *info)
sprintf(dev->name, "fb");
+ info->dev.bus = &fb_bus;
register_device(&info->dev);
dev_add_param(dev, "enable", fb_enable_set, NULL, 0);
dev_set_param(dev, "enable", "0");
@@ -160,19 +161,35 @@ static void fb_info(struct device_d *dev)
printf("\n");
}
-static int fb_probe(struct device_d *hw_dev)
+static struct driver_d fb_driver = {
+ .name = "fb",
+ .info = fb_info,
+};
+
+static int fb_match(struct device_d *dev, struct driver_d *drv)
{
return 0;
}
-static struct driver_d fb_driver = {
- .name = "fb",
+static int fb_probe(struct device_d *dev)
+{
+ return 0;
+}
+
+static void fb_remove(struct device_d *dev)
+{
+}
+
+struct bus_type fb_bus = {
+ .name = "fb",
+ .match = fb_match,
.probe = fb_probe,
- .info = fb_info,
+ .remove = fb_remove,
};
static int fb_init_driver(void)
{
+ fb_driver.bus = &fb_bus;
register_driver(&fb_driver);
return 0;
}
diff --git a/include/fb.h b/include/fb.h
index 41deb8c..c594418 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -110,5 +110,7 @@ int register_framebuffer(struct fb_info *info);
#define FBIO_ENABLE _IO('F', 2)
#define FBIO_DISABLE _IO('F', 3)
+extern struct bus_type fb_bus;
+
#endif /* __FB_H */
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/1] fb: add it's own bus for fb devices
2012-09-20 18:51 ` [PATCH 1/1] fb: add it's own bus for fb devices Jean-Christophe PLAGNIOL-VILLARD
@ 2012-09-20 21:17 ` Sascha Hauer
0 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2012-09-20 21:17 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox
On Thu, Sep 20, 2012 at 08:51:30PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> This is need for oftree device probing
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Applied, thanks
Sascha
> ---
> drivers/video/fb.c | 25 +++++++++++++++++++++----
> include/fb.h | 2 ++
> 2 files changed, 23 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/video/fb.c b/drivers/video/fb.c
> index d885570..127723c 100644
> --- a/drivers/video/fb.c
> +++ b/drivers/video/fb.c
> @@ -125,6 +125,7 @@ int register_framebuffer(struct fb_info *info)
>
> sprintf(dev->name, "fb");
>
> + info->dev.bus = &fb_bus;
> register_device(&info->dev);
> dev_add_param(dev, "enable", fb_enable_set, NULL, 0);
> dev_set_param(dev, "enable", "0");
> @@ -160,19 +161,35 @@ static void fb_info(struct device_d *dev)
> printf("\n");
> }
>
> -static int fb_probe(struct device_d *hw_dev)
> +static struct driver_d fb_driver = {
> + .name = "fb",
> + .info = fb_info,
> +};
> +
> +static int fb_match(struct device_d *dev, struct driver_d *drv)
> {
> return 0;
> }
>
> -static struct driver_d fb_driver = {
> - .name = "fb",
> +static int fb_probe(struct device_d *dev)
> +{
> + return 0;
> +}
> +
> +static void fb_remove(struct device_d *dev)
> +{
> +}
> +
> +struct bus_type fb_bus = {
> + .name = "fb",
> + .match = fb_match,
> .probe = fb_probe,
> - .info = fb_info,
> + .remove = fb_remove,
> };
>
> static int fb_init_driver(void)
> {
> + fb_driver.bus = &fb_bus;
> register_driver(&fb_driver);
> return 0;
> }
> diff --git a/include/fb.h b/include/fb.h
> index 41deb8c..c594418 100644
> --- a/include/fb.h
> +++ b/include/fb.h
> @@ -110,5 +110,7 @@ int register_framebuffer(struct fb_info *info);
> #define FBIO_ENABLE _IO('F', 2)
> #define FBIO_DISABLE _IO('F', 3)
>
> +extern struct bus_type fb_bus;
> +
> #endif /* __FB_H */
>
> --
> 1.7.10.4
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread