Merge branch 'devicetree/next' of git://git.secretlab.ca/git/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Jul 2011 21:53:38 +0000 (14:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Jul 2011 21:53:38 +0000 (14:53 -0700)
* 'devicetree/next' of git://git.secretlab.ca/git/linux-2.6:
  dt: include linux/errno.h in linux/of_address.h
  of/address: Add of_find_matching_node_by_address helper
  dt: remove extra xsysace platform_driver registration
  tty/serial: Add devicetree support for nVidia Tegra serial ports
  dt: add empty of_property_read_u32[_array] for non-dt
  dt: bindings: move SEC node under new crypto/
  dt: add helper function to read u32 arrays
  tty/serial: change of_serial to use new of_property_read_u32() api
  dt: add 'const' for of_property_read_string parameter **out_string
  dt: add helper functions to read u32 and string property values
  tty: of_serial: support for 32 bit accesses
  dt: document the of_serial bindings
  dt/platform: allow device name to be overridden
  drivers/amba: create devices from device tree
  dt: add of_platform_populate() for creating device from the device tree
  dt: Add default match table for bus ids

Documentation/devicetree/bindings/arm/primecell.txt [new file with mode: 0644]
Documentation/devicetree/bindings/crypto/fsl-sec2.txt [moved from Documentation/devicetree/bindings/powerpc/fsl/sec.txt with 98% similarity]
Documentation/devicetree/bindings/tty/serial/of-serial.txt [new file with mode: 0644]
drivers/block/xsysace.c
drivers/of/address.c
drivers/of/base.c
drivers/of/platform.c
drivers/tty/serial/of_serial.c
include/linux/of.h
include/linux/of_address.h
include/linux/of_platform.h

diff --git a/Documentation/devicetree/bindings/arm/primecell.txt b/Documentation/devicetree/bindings/arm/primecell.txt
new file mode 100644 (file)
index 0000000..1d5d7a8
--- /dev/null
@@ -0,0 +1,21 @@
+* ARM Primecell Peripherals
+
+ARM, Ltd. Primecell peripherals have a standard id register that can be used to
+identify the peripheral type, vendor, and revision. This value can be used for
+driver matching.
+
+Required properties:
+
+- compatible : should be a specific value for peripheral and "arm,primecell"
+
+Optional properties:
+
+- arm,primecell-periphid : Value to override the h/w value with
+
+Example:
+
+serial@fff36000 {
+       compatible = "arm,pl011", "arm,primecell";
+       arm,primecell-periphid = <0x00341011>;
+};
+
@@ -1,4 +1,4 @@
-Freescale SoC SEC Security Engines
+Freescale SoC SEC Security Engines versions 2.x-3.x
 
 Required properties:
 
diff --git a/Documentation/devicetree/bindings/tty/serial/of-serial.txt b/Documentation/devicetree/bindings/tty/serial/of-serial.txt
new file mode 100644 (file)
index 0000000..b8b27b0
--- /dev/null
@@ -0,0 +1,36 @@
+* UART (Universal Asynchronous Receiver/Transmitter)
+
+Required properties:
+- compatible : one of:
+       - "ns8250"
+       - "ns16450"
+       - "ns16550a"
+       - "ns16550"
+       - "ns16750"
+       - "ns16850"
+       - "nvidia,tegra20-uart"
+       - "ibm,qpace-nwp-serial"
+       - "serial" if the port type is unknown.
+- reg : offset and length of the register set for the device.
+- interrupts : should contain uart interrupt.
+- clock-frequency : the input clock frequency for the UART.
+
+Optional properties:
+- current-speed : the current active speed of the UART.
+- reg-offset : offset to apply to the mapbase from the start of the registers.
+- reg-shift : quantity to shift the register offsets by.
+- reg-io-width : the size (in bytes) of the IO accesses that should be
+  performed on the device.  There are some systems that require 32-bit
+  accesses to the UART (e.g. TI davinci).
+- used-by-rtas : set to indicate that the port is in use by the OpenFirmware
+  RTAS and should not be registered.
+
+Example:
+
+       uart@80230000 {
+               compatible = "ns8250";
+               reg = <0x80230000 0x100>;
+               clock-frequency = <3686400>;
+               interrupts = <10>;
+               reg-shift = <2>;
+       };
index 6c7fd7d..fb1975d 100644 (file)
@@ -1155,12 +1155,19 @@ static int __devinit ace_probe(struct platform_device *dev)
 {
        resource_size_t physaddr = 0;
        int bus_width = ACE_BUS_WIDTH_16; /* FIXME: should not be hard coded */
-       int id = dev->id;
+       u32 id = dev->id;
        int irq = NO_IRQ;
        int i;
 
        dev_dbg(&dev->dev, "ace_probe(%p)\n", dev);
 
+       /* device id and bus width */
+       of_property_read_u32(dev->dev.of_node, "port-number", &id);
+       if (id < 0)
+               id = 0;
+       if (of_find_property(dev->dev.of_node, "8-bit", NULL))
+               bus_width = ACE_BUS_WIDTH_8;
+
        for (i = 0; i < dev->num_resources; i++) {
                if (dev->resource[i].flags & IORESOURCE_MEM)
                        physaddr = dev->resource[i].start;
@@ -1181,57 +1188,7 @@ static int __devexit ace_remove(struct platform_device *dev)
        return 0;
 }
 
-static struct platform_driver ace_platform_driver = {
-       .probe = ace_probe,
-       .remove = __devexit_p(ace_remove),
-       .driver = {
-               .owner = THIS_MODULE,
-               .name = "xsysace",
-       },
-};
-
-/* ---------------------------------------------------------------------
- * OF_Platform Bus Support
- */
-
 #if defined(CONFIG_OF)
-static int __devinit ace_of_probe(struct platform_device *op)
-{
-       struct resource res;
-       resource_size_t physaddr;
-       const u32 *id;
-       int irq, bus_width, rc;
-
-       /* device id */
-       id = of_get_property(op->dev.of_node, "port-number", NULL);
-
-       /* physaddr */
-       rc = of_address_to_resource(op->dev.of_node, 0, &res);
-       if (rc) {
-               dev_err(&op->dev, "invalid address\n");
-               return rc;
-       }
-       physaddr = res.start;
-
-       /* irq */
-       irq = irq_of_parse_and_map(op->dev.of_node, 0);
-
-       /* bus width */
-       bus_width = ACE_BUS_WIDTH_16;
-       if (of_find_property(op->dev.of_node, "8-bit", NULL))
-               bus_width = ACE_BUS_WIDTH_8;
-
-       /* Call the bus-independent setup code */
-       return ace_alloc(&op->dev, id ? be32_to_cpup(id) : 0,
-                                               physaddr, irq, bus_width);
-}
-
-static int __devexit ace_of_remove(struct platform_device *op)
-{
-       ace_free(&op->dev);
-       return 0;
-}
-
 /* Match table for of_platform binding */
 static const struct of_device_id ace_of_match[] __devinitconst = {
        { .compatible = "xlnx,opb-sysace-1.00.b", },
@@ -1241,34 +1198,20 @@ static const struct of_device_id ace_of_match[] __devinitconst = {
        {},
 };
 MODULE_DEVICE_TABLE(of, ace_of_match);
+#else /* CONFIG_OF */
+#define ace_of_match NULL
+#endif /* CONFIG_OF */
 
-static struct platform_driver ace_of_driver = {
-       .probe = ace_of_probe,
-       .remove = __devexit_p(ace_of_remove),
+static struct platform_driver ace_platform_driver = {
+       .probe = ace_probe,
+       .remove = __devexit_p(ace_remove),
        .driver = {
-               .name = "xsysace",
                .owner = THIS_MODULE,
+               .name = "xsysace",
                .of_match_table = ace_of_match,
        },
 };
 
-/* Registration helpers to keep the number of #ifdefs to a minimum */
-static inline int __init ace_of_register(void)
-{
-       pr_debug("xsysace: registering OF binding\n");
-       return platform_driver_register(&ace_of_driver);
-}
-
-static inline void __exit ace_of_unregister(void)
-{
-       platform_driver_unregister(&ace_of_driver);
-}
-#else /* CONFIG_OF */
-/* CONFIG_OF not enabled; do nothing helpers */
-static inline int __init ace_of_register(void) { return 0; }
-static inline void __exit ace_of_unregister(void) { }
-#endif /* CONFIG_OF */
-
 /* ---------------------------------------------------------------------
  * Module init/exit routines
  */
@@ -1282,11 +1225,6 @@ static int __init ace_init(void)
                goto err_blk;
        }
 
-       rc = ace_of_register();
-       if (rc)
-               goto err_of;
-
-       pr_debug("xsysace: registering platform binding\n");
        rc = platform_driver_register(&ace_platform_driver);
        if (rc)
                goto err_plat;
@@ -1295,21 +1233,17 @@ static int __init ace_init(void)
        return 0;
 
 err_plat:
-       ace_of_unregister();
-err_of:
        unregister_blkdev(ace_major, "xsysace");
 err_blk:
        printk(KERN_ERR "xsysace: registration failed; err=%i\n", rc);
        return rc;
 }
+module_init(ace_init);
 
 static void __exit ace_exit(void)
 {
        pr_debug("Unregistering Xilinx SystemACE driver\n");
        platform_driver_unregister(&ace_platform_driver);
-       ace_of_unregister();
        unregister_blkdev(ace_major, "xsysace");
 }
-
-module_init(ace_init);
 module_exit(ace_exit);
index b4559c5..da1f4b9 100644 (file)
@@ -577,6 +577,24 @@ int of_address_to_resource(struct device_node *dev, int index,
 }
 EXPORT_SYMBOL_GPL(of_address_to_resource);
 
+struct device_node *of_find_matching_node_by_address(struct device_node *from,
+                                       const struct of_device_id *matches,
+                                       u64 base_address)
+{
+       struct device_node *dn = of_find_matching_node(from, matches);
+       struct resource res;
+
+       while (dn) {
+               if (of_address_to_resource(dn, 0, &res))
+                       continue;
+               if (res.start == base_address)
+                       return dn;
+               dn = of_find_matching_node(dn, matches);
+       }
+
+       return NULL;
+}
+
 
 /**
  * of_iomap - Maps the memory mapped IO for a given device_node
index 632ebae..02ed367 100644 (file)
@@ -595,6 +595,71 @@ struct device_node *of_find_node_by_phandle(phandle handle)
 }
 EXPORT_SYMBOL(of_find_node_by_phandle);
 
+/**
+ * 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, char *propname,
+                              u32 *out_values, size_t sz)
+{
+       struct property *prop = of_find_property(np, propname, NULL);
+       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_property_read_string - Find and read a string from a property
+ * @np:                device node from which the property value is to be read.
+ * @propname:  name of the property to be searched.
+ * @out_string:        pointer to null terminated return string, modified only if
+ *             return value is 0.
+ *
+ * Search for a property in a device tree node and retrieve a null
+ * terminated string value (pointer to data, not a copy). Returns 0 on
+ * success, -EINVAL if the property does not exist, -ENODATA if property
+ * does not have a value, and -EILSEQ if the string is not null-terminated
+ * within the length of the property data.
+ *
+ * The out_string pointer is modified only if a valid string can be decoded.
+ */
+int of_property_read_string(struct device_node *np, char *propname,
+                               const char **out_string)
+{
+       struct property *prop = of_find_property(np, propname, NULL);
+       if (!prop)
+               return -EINVAL;
+       if (!prop->value)
+               return -ENODATA;
+       if (strnlen(prop->value, prop->length) >= prop->length)
+               return -EILSEQ;
+       *out_string = prop->value;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(of_property_read_string);
+
 /**
  * of_parse_phandle - Resolve a phandle property to a device_node pointer
  * @np: Pointer to device node holding phandle property
index 63d3cb7..e75af39 100644 (file)
@@ -13,6 +13,7 @@
  */
 #include <linux/errno.h>
 #include <linux/module.h>
+#include <linux/amba/bus.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 
+const struct of_device_id of_default_bus_match_table[] = {
+       { .compatible = "simple-bus", },
+#ifdef CONFIG_ARM_AMBA
+       { .compatible = "arm,amba-bus", },
+#endif /* CONFIG_ARM_AMBA */
+       {} /* Empty terminated list */
+};
+
 static int of_dev_node_match(struct device *dev, void *data)
 {
        return dev->of_node == data;
@@ -168,17 +177,20 @@ struct platform_device *of_device_alloc(struct device_node *np,
 EXPORT_SYMBOL(of_device_alloc);
 
 /**
- * of_platform_device_create - Alloc, initialize and register an of_device
+ * of_platform_device_create_pdata - Alloc, initialize and register an of_device
  * @np: pointer to node to create device for
  * @bus_id: name to assign device
+ * @platform_data: pointer to populate platform_data pointer with
  * @parent: Linux device model parent device.
  *
  * Returns pointer to created platform device, or NULL if a device was not
  * registered.  Unavailable devices will not get registered.
  */
-struct platform_device *of_platform_device_create(struct device_node *np,
-                                           const char *bus_id,
-                                           struct device *parent)
+struct platform_device *of_platform_device_create_pdata(
+                                       struct device_node *np,
+                                       const char *bus_id,
+                                       void *platform_data,
+                                       struct device *parent)
 {
        struct platform_device *dev;
 
@@ -194,6 +206,7 @@ struct platform_device *of_platform_device_create(struct device_node *np,
 #endif
        dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
        dev->dev.bus = &platform_bus_type;
+       dev->dev.platform_data = platform_data;
 
        /* We do not fill the DMA ops for platform devices by default.
         * This is currently the responsibility of the platform code
@@ -207,8 +220,111 @@ struct platform_device *of_platform_device_create(struct device_node *np,
 
        return dev;
 }
+
+/**
+ * of_platform_device_create - Alloc, initialize and register an of_device
+ * @np: pointer to node to create device for
+ * @bus_id: name to assign device
+ * @parent: Linux device model parent device.
+ *
+ * Returns pointer to created platform device, or NULL if a device was not
+ * registered.  Unavailable devices will not get registered.
+ */
+struct platform_device *of_platform_device_create(struct device_node *np,
+                                           const char *bus_id,
+                                           struct device *parent)
+{
+       return of_platform_device_create_pdata(np, bus_id, NULL, parent);
+}
 EXPORT_SYMBOL(of_platform_device_create);
 
+#ifdef CONFIG_ARM_AMBA
+static struct amba_device *of_amba_device_create(struct device_node *node,
+                                                const char *bus_id,
+                                                void *platform_data,
+                                                struct device *parent)
+{
+       struct amba_device *dev;
+       const void *prop;
+       int i, ret;
+
+       pr_debug("Creating amba device %s\n", node->full_name);
+
+       if (!of_device_is_available(node))
+               return NULL;
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return NULL;
+
+       /* setup generic device info */
+       dev->dev.coherent_dma_mask = ~0;
+       dev->dev.of_node = of_node_get(node);
+       dev->dev.parent = parent;
+       dev->dev.platform_data = platform_data;
+       if (bus_id)
+               dev_set_name(&dev->dev, "%s", bus_id);
+       else
+               of_device_make_bus_id(&dev->dev);
+
+       /* setup amba-specific device info */
+       dev->dma_mask = ~0;
+
+       /* Allow the HW Peripheral ID to be overridden */
+       prop = of_get_property(node, "arm,primecell-periphid", NULL);
+       if (prop)
+               dev->periphid = of_read_ulong(prop, 1);
+
+       /* Decode the IRQs and address ranges */
+       for (i = 0; i < AMBA_NR_IRQS; i++)
+               dev->irq[i] = irq_of_parse_and_map(node, i);
+
+       ret = of_address_to_resource(node, 0, &dev->res);
+       if (ret)
+               goto err_free;
+
+       ret = amba_device_register(dev, &iomem_resource);
+       if (ret)
+               goto err_free;
+
+       return dev;
+
+err_free:
+       kfree(dev);
+       return NULL;
+}
+#else /* CONFIG_ARM_AMBA */
+static struct amba_device *of_amba_device_create(struct device_node *node,
+                                                const char *bus_id,
+                                                void *platform_data,
+                                                struct device *parent)
+{
+       return NULL;
+}
+#endif /* CONFIG_ARM_AMBA */
+
+/**
+ * of_devname_lookup() - Given a device node, lookup the preferred Linux name
+ */
+static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *lookup,
+                                struct device_node *np)
+{
+       struct resource res;
+       if (lookup) {
+               for(; lookup->name != NULL; lookup++) {
+                       if (!of_device_is_compatible(np, lookup->compatible))
+                               continue;
+                       if (of_address_to_resource(np, 0, &res))
+                               continue;
+                       if (res.start != lookup->phys_addr)
+                               continue;
+                       pr_debug("%s: devname=%s\n", np->full_name, lookup->name);
+                       return lookup;
+               }
+       }
+       return NULL;
+}
+
 /**
  * of_platform_bus_create() - Create a device for a node and its children.
  * @bus: device node of the bus to instantiate
@@ -221,19 +337,41 @@ EXPORT_SYMBOL(of_platform_device_create);
  */
 static int of_platform_bus_create(struct device_node *bus,
                                  const struct of_device_id *matches,
-                                 struct device *parent)
+                                 const struct of_dev_auxdata *lookup,
+                                 struct device *parent, bool strict)
 {
+       const struct of_dev_auxdata *auxdata;
        struct device_node *child;
        struct platform_device *dev;
+       const char *bus_id = NULL;
+       void *platform_data = NULL;
        int rc = 0;
 
-       dev = of_platform_device_create(bus, NULL, parent);
+       /* Make sure it has a compatible property */
+       if (strict && (!of_get_property(bus, "compatible", NULL))) {
+               pr_debug("%s() - skipping %s, no compatible prop\n",
+                        __func__, bus->full_name);
+               return 0;
+       }
+
+       auxdata = of_dev_lookup(lookup, bus);
+       if (auxdata) {
+               bus_id = auxdata->name;
+               platform_data = auxdata->platform_data;
+       }
+
+       if (of_device_is_compatible(bus, "arm,primecell")) {
+               of_amba_device_create(bus, bus_id, platform_data, parent);
+               return 0;
+       }
+
+       dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);
        if (!dev || !of_match_node(matches, bus))
                return 0;
 
        for_each_child_of_node(bus, child) {
                pr_debug("   create child: %s\n", child->full_name);
-               rc = of_platform_bus_create(child, matches, &dev->dev);
+               rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict);
                if (rc) {
                        of_node_put(child);
                        break;
@@ -267,11 +405,11 @@ int of_platform_bus_probe(struct device_node *root,
 
        /* Do a self check of bus type, if there's a match, create children */
        if (of_match_node(matches, root)) {
-               rc = of_platform_bus_create(root, matches, parent);
+               rc = of_platform_bus_create(root, matches, NULL, parent, false);
        } else for_each_child_of_node(root, child) {
                if (!of_match_node(matches, child))
                        continue;
-               rc = of_platform_bus_create(child, matches, parent);
+               rc = of_platform_bus_create(child, matches, NULL, parent, false);
                if (rc)
                        break;
        }
@@ -280,4 +418,44 @@ int of_platform_bus_probe(struct device_node *root,
        return rc;
 }
 EXPORT_SYMBOL(of_platform_bus_probe);
+
+/**
+ * of_platform_populate() - Populate platform_devices from device tree data
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * Similar to of_platform_bus_probe(), this function walks the device tree
+ * and creates devices from nodes.  It differs in that it follows the modern
+ * convention of requiring all device nodes to have a 'compatible' property,
+ * and it is suitable for creating devices which are children of the root
+ * node (of_platform_bus_probe will only create children of the root which
+ * are selected by the @matches argument).
+ *
+ * New board support should be using this function instead of
+ * of_platform_bus_probe().
+ *
+ * Returns 0 on success, < 0 on failure.
+ */
+int of_platform_populate(struct device_node *root,
+                       const struct of_device_id *matches,
+                       const struct of_dev_auxdata *lookup,
+                       struct device *parent)
+{
+       struct device_node *child;
+       int rc = 0;
+
+       root = root ? of_node_get(root) : of_find_node_by_path("/");
+       if (!root)
+               return -EINVAL;
+
+       for_each_child_of_node(root, child) {
+               rc = of_platform_bus_create(child, matches, lookup, parent, true);
+               if (rc)
+                       break;
+       }
+
+       of_node_put(root);
+       return rc;
+}
 #endif /* !CONFIG_SPARC */
index c911b24..e58cece 100644 (file)
@@ -32,17 +32,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
 {
        struct resource resource;
        struct device_node *np = ofdev->dev.of_node;
-       const __be32 *clk, *spd;
-       const __be32 *prop;
-       int ret, prop_size;
+       u32 clk, spd, prop;
+       int ret;
 
        memset(port, 0, sizeof *port);
-       spd = of_get_property(np, "current-speed", NULL);
-       clk = of_get_property(np, "clock-frequency", NULL);
-       if (!clk) {
+       if (of_property_read_u32(np, "clock-frequency", &clk)) {
                dev_warn(&ofdev->dev, "no clock-frequency property set\n");
                return -ENODEV;
        }
+       /* If current-speed was set, then try not to change it. */
+       if (of_property_read_u32(np, "current-speed", &spd) == 0)
+               port->custom_divisor = clk / (16 * spd);
 
        ret = of_address_to_resource(np, 0, &resource);
        if (ret) {
@@ -54,25 +54,35 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
        port->mapbase = resource.start;
 
        /* Check for shifted address mapping */
-       prop = of_get_property(np, "reg-offset", &prop_size);
-       if (prop && (prop_size == sizeof(u32)))
-               port->mapbase += be32_to_cpup(prop);
+       if (of_property_read_u32(np, "reg-offset", &prop) == 0)
+               port->mapbase += prop;
 
        /* Check for registers offset within the devices address range */
-       prop = of_get_property(np, "reg-shift", &prop_size);
-       if (prop && (prop_size == sizeof(u32)))
-               port->regshift = be32_to_cpup(prop);
+       if (of_property_read_u32(np, "reg-shift", &prop) == 0)
+               port->regshift = prop;
 
        port->irq = irq_of_parse_and_map(np, 0);
        port->iotype = UPIO_MEM;
+       if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
+               switch (prop) {
+               case 1:
+                       port->iotype = UPIO_MEM;
+                       break;
+               case 4:
+                       port->iotype = UPIO_MEM32;
+                       break;
+               default:
+                       dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n",
+                                prop);
+                       return -EINVAL;
+               }
+       }
+
        port->type = type;
-       port->uartclk = be32_to_cpup(clk);
+       port->uartclk = clk;
        port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
                | UPF_FIXED_PORT | UPF_FIXED_TYPE;
        port->dev = &ofdev->dev;
-       /* If current-speed was set, then try not to change it. */
-       if (spd)
-               port->custom_divisor = be32_to_cpup(clk) / (16 * (be32_to_cpup(spd)));
 
        return 0;
 }
@@ -171,6 +181,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = {
        { .compatible = "ns16550",  .data = (void *)PORT_16550, },
        { .compatible = "ns16750",  .data = (void *)PORT_16750, },
        { .compatible = "ns16850",  .data = (void *)PORT_16850, },
+       { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },
 #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
        { .compatible = "ibm,qpace-nwp-serial",
                .data = (void *)PORT_NWPSERIAL, },
index bfc0ed1..bd716f8 100644 (file)
@@ -195,6 +195,13 @@ extern struct device_node *of_find_node_with_property(
 extern struct property *of_find_property(const struct device_node *np,
                                         const char *name,
                                         int *lenp);
+extern int of_property_read_u32_array(const struct device_node *np,
+                                     char *propname,
+                                     u32 *out_values,
+                                     size_t sz);
+
+extern int of_property_read_string(struct device_node *np, char *propname,
+                                       const char **out_string);
 extern int of_device_is_compatible(const struct device_node *device,
                                   const char *);
 extern int of_device_is_available(const struct device_node *device);
@@ -227,12 +234,32 @@ extern void of_attach_node(struct device_node *);
 extern void of_detach_node(struct device_node *);
 #endif
 
-#else
+#else /* CONFIG_OF */
 
 static inline bool of_have_populated_dt(void)
 {
        return false;
 }
 
+static inline int of_property_read_u32_array(const struct device_node *np,
+                               char *propname, u32 *out_values, size_t sz)
+{
+       return -ENOSYS;
+}
+
+static inline int of_property_read_string(struct device_node *np,
+                               char *propname, const char **out_string)
+{
+       return -ENOSYS;
+}
+
 #endif /* CONFIG_OF */
+
+static inline int of_property_read_u32(const struct device_node *np,
+                                      char *propname,
+                                      u32 *out_value)
+{
+       return of_property_read_u32_array(np, propname, out_value, 1);
+}
+
 #endif /* _LINUX_OF_H */
index 2feda6e..3118623 100644 (file)
@@ -1,11 +1,16 @@
 #ifndef __OF_ADDRESS_H
 #define __OF_ADDRESS_H
 #include <linux/ioport.h>
+#include <linux/errno.h>
 #include <linux/of.h>
 
 extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
 extern int of_address_to_resource(struct device_node *dev, int index,
                                  struct resource *r);
+extern struct device_node *of_find_matching_node_by_address(
+                                       struct device_node *from,
+                                       const struct of_device_id *matches,
+                                       u64 base_address);
 extern void __iomem *of_iomap(struct device_node *device, int index);
 
 /* Extract an address from a device, returns the region size and
index fb51ae3..5a6f458 100644 (file)
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
+/**
+ * struct of_dev_auxdata - lookup table entry for device names & platform_data
+ * @compatible: compatible value of node to match against node
+ * @phys_addr: Start address of registers to match against node
+ * @name: Name to assign for matching nodes
+ * @platform_data: platform_data to assign for matching nodes
+ *
+ * This lookup table allows the caller of of_platform_populate() to override
+ * the names of devices when creating devices from the device tree.  The table
+ * should be terminated with an empty entry.  It also allows the platform_data
+ * pointer to be set.
+ *
+ * The reason for this functionality is that some Linux infrastructure uses
+ * the device name to look up a specific device, but the Linux-specific names
+ * are not encoded into the device tree, so the kernel needs to provide specific
+ * values.
+ *
+ * Note: Using an auxdata lookup table should be considered a last resort when
+ * converting a platform to use the DT.  Normally the automatically generated
+ * device name will not matter, and drivers should obtain data from the device
+ * node instead of from an anonymouns platform_data pointer.
+ */
+struct of_dev_auxdata {
+       char *compatible;
+       resource_size_t phys_addr;
+       char *name;
+       void *platform_data;
+};
+
+/* Macro to simplify populating a lookup table */
+#define OF_DEV_AUXDATA(_compat,_phys,_name,_pdata) \
+       { .compatible = _compat, .phys_addr = _phys, .name = _name, \
+         .platform_data = _pdata }
+
 /**
  * of_platform_driver - Legacy of-aware driver for platform devices.
  *
@@ -40,6 +74,8 @@ struct of_platform_driver
 #define        to_of_platform_driver(drv) \
        container_of(drv,struct of_platform_driver, driver)
 
+extern const struct of_device_id of_default_bus_match_table[];
+
 /* Platform drivers register/unregister */
 extern struct platform_device *of_device_alloc(struct device_node *np,
                                         const char *bus_id,
@@ -55,6 +91,10 @@ extern struct platform_device *of_platform_device_create(struct device_node *np,
 extern int of_platform_bus_probe(struct device_node *root,
                                 const struct of_device_id *matches,
                                 struct device *parent);
+extern int of_platform_populate(struct device_node *root,
+                               const struct of_device_id *matches,
+                               const struct of_dev_auxdata *lookup,
+                               struct device *parent);
 #endif /* !CONFIG_SPARC */
 
 #endif /* CONFIG_OF_DEVICE */