aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Konovalov <andrey.konovalov@linaro.org>2012-01-17 00:05:56 +0400
committerAndrey Konovalov <andrey.konovalov@linaro.org>2012-01-17 00:06:21 +0400
commitb93b9d935637fc8ecc90d163587bd37201de3aed (patch)
tree36c383c4bb9ae0b95b71f853a5b1d5d49116cf1d
parentddd06511cec618157b50ffa54c0f0f6ae0f67a01 (diff)
parent027d7c326426cc82f6190ac905f23e061b10de04 (diff)
Merge device tree support patches from linux-linaro-3.1
-rw-r--r--Documentation/devicetree/bindings/arm/freescale.txt7
-rw-r--r--Documentation/devicetree/bindings/arm/genesi.txt8
-rw-r--r--Documentation/devicetree/bindings/arm/samsung.txt9
-rw-r--r--Documentation/devicetree/usage-model403
-rw-r--r--arch/arm/boot/dts/exynos4-smdkv310.dts11
-rw-r--r--arch/arm/boot/dts/genesi-efikamx.dts22
-rw-r--r--arch/arm/boot/dts/genesi-efikasb.dts22
-rw-r--r--arch/arm/boot/dts/isee-igep-v2.dts7
-rw-r--r--arch/arm/boot/dts/isee-igep-v3.dts7
-rw-r--r--arch/arm/boot/dts/mx51-babbage.dts22
-rw-r--r--arch/arm/boot/dts/mx53-loco.dts22
-rw-r--r--arch/arm/boot/dts/omap3-overo.dts7
-rw-r--r--arch/arm/boot/dts/vexpress.dts10
-rw-r--r--arch/arm/mach-exynos/Makefile.boot2
-rw-r--r--arch/arm/mach-exynos/mach-smdkv310.c6
-rw-r--r--arch/arm/mach-mx5/Makefile.boot5
-rw-r--r--arch/arm/mach-mx5/board-mx51_babbage.c6
-rw-r--r--arch/arm/mach-mx5/board-mx51_efikamx.c6
-rw-r--r--arch/arm/mach-mx5/board-mx51_efikasb.c6
-rw-r--r--arch/arm/mach-mx5/board-mx53_loco.c5
-rw-r--r--arch/arm/mach-omap2/Makefile.boot6
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c12
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c6
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c6
-rw-r--r--arch/arm/mach-omap2/board-overo.c6
-rw-r--r--arch/arm/mach-versatile/Makefile.boot2
-rw-r--r--arch/arm/mach-vexpress/Makefile.boot2
-rw-r--r--arch/arm/mach-vexpress/v2m.c6
-rw-r--r--drivers/of/platform.c7
-rw-r--r--include/linux/of_platform.h7
30 files changed, 652 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/arm/freescale.txt b/Documentation/devicetree/bindings/arm/freescale.txt
new file mode 100644
index 00000000000..8c52102b225
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/freescale.txt
@@ -0,0 +1,7 @@
+mx51 "Babbage" evalutation board
+Required root node properties:
+ - compatible = "fsl,mx51-babbage", "fsl,mx51";
+
+mx53 "Loco" evaluation board
+Required root node properties:
+ - compatible = "fsl,mx53-loco", "fsl,mx53";
diff --git a/Documentation/devicetree/bindings/arm/genesi.txt b/Documentation/devicetree/bindings/arm/genesi.txt
new file mode 100644
index 00000000000..b353489acd4
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/genesi.txt
@@ -0,0 +1,8 @@
+Genesi EfikaMX based on Freescale mx51
+Required root node properties:
+ - compatible = "genesi,efikamx", "fsl,mx51";
+
+Genesi EfikaMX Smartbook based on Freescale mx51
+Required root node properties:
+ - compatible = "genesi,efikasb", "fsl,mx51";
+
diff --git a/Documentation/devicetree/bindings/arm/samsung.txt b/Documentation/devicetree/bindings/arm/samsung.txt
new file mode 100644
index 00000000000..594cb97e3d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/samsung.txt
@@ -0,0 +1,9 @@
+Samsung Exynos4 S5PV310 SoC based SMDKV310 eval board
+
+ SMDKV310 eval board is based on S5PV310 SoC which belongs to
+ Samsung's Exynos4 family of application processors.
+
+Required root node properties:
+ - compatible = "samsung,smdkv310","samsung,s5pv310"
+ (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
+ (b) "samsung,s5pv310" - for boards based on S5PV310 SoC.
diff --git a/Documentation/devicetree/usage-model b/Documentation/devicetree/usage-model
new file mode 100644
index 00000000000..45e03b8dd04
--- /dev/null
+++ b/Documentation/devicetree/usage-model
@@ -0,0 +1,403 @@
+Linux and the Device Tree
+The Linux usage model for device tree data
+
+Author: Grant Likely <grant.likely@secretlab.ca>
+
+This article describes how Linux uses the device tree. An overview of
+the device tree data format can be found at the <a
+href="http://devicetree.org/Device_Tree_Usage">Device Tree Usage</a>
+page on <a href="http://devicetree.org">devicetree.org</a>.
+
+
+ All the cool architectures are using device tree. I want to
+ use device tree too!
+
+The "Open Firmware Device Tree", or simply Device Tree (DT), is a data
+structure and language for describing hardware. More specifically, it
+is a description of hardware that is readable by an operating system
+so that the operating system doesn't need to hard code details of the
+machine.
+
+Structurally, the DT is a tree, or acyclic graph with named nodes, and
+nodes may have an arbitrary number of named properties encapsulating
+arbitrary data. A mechanism also exists to create arbitrary
+links from one node to another outside of the natural tree structure.
+
+Conceptually, a common set of usage conventions, called 'bindings',
+is defined for how data should appear in the tree to describe typical
+hardware characteristics including data busses, interrupt lines, GPIO
+connections, and peripheral devices.
+
+As much as possible, hardware is described using existing bindings to
+maximize use of existing support code, but since property and node
+names are simply text strings, it is easy to extend existing bindings
+or create new ones by defining new nodes and properties.
+
+<h2>History</h2>
+The DT was originally created by Open Firmware as part of the
+communication method for passing data from Open Firmware to a client
+program (like to an operating system). An operating system used the
+Device Tree to discover the topology of the hardware at runtime, and
+thereby support a majority of available hardware without hard coded
+information (assuming drivers were available for all devices).
+
+Since Open Firmware is commonly used on PowerPC and SPARC platforms,
+the Linux support for those architectures has for a long time used the
+Device Tree.
+
+In 2005, when PowerPC Linux began a major cleanup and to merge 32-bit
+and 64-bit support, the decision was made to require DT support on all
+powerpc platforms, regardless of whether or not they used Open
+Firmware. To do this, a DT representation called the Flattened Device
+Tree (FDT) was created which could be passed to the kernel as a binary
+blob without requiring a real Open Firmware implementation. U-Boot,
+kexec, and other bootloaders were modified to support both passing a
+Device Tree Binary (dtb) and to modify a dtb at boot time.
+
+Some time later, FDT infrastructure was generalized to be usable by
+all architectures. At the time of this writing, 6 mainlined
+architectures (arm, microblaze, mips, powerpc, sparc, and x86) and 1
+out of mainline (nios) have some level of DT support.
+
+<h2>Data Model</h2>
+If you haven't already read the
+href="http://devicetree.org/Device_Tree_Usage">Device Tree Usage</a>
+page, then go read it now. It's okay, I'll wait....
+
+<h3>High Level View</h3>
+The most important thing to understand is that the DT is simply a data
+structure that describes the hardware. There is nothing magical about
+it, and it doesn't magically make all hardware configuration problems
+go away. What it does do is provide a language for decoupling the
+hardware configuration from the board and device driver support in the
+Linux kernel (or any other operating system for that matter). Using
+it allows board and device support to become data driven; to make
+setup decisions based on data passed into the kernel instead of on
+per-machine hard coded selections.
+
+Ideally, data driven platform setup should result in less code
+duplication and make it easier to support a wide range of hardware
+with a single kernel image.
+
+Linux uses DT data for three major purposes:
+1) platform identification,
+2) runtime configuration, and
+3) device population.
+
+<h4>Platform Identification</h4>
+First and foremost, the kernel will use data in the DT to identify the
+specific machine. In a perfect world, the specific platform shouldn't
+matter to the kernel because all platform details would be described
+perfectly by the device tree in a consistent and reliable manner.
+Hardware is not perfect though, and so the kernel must identify the
+machine during early boot so that it has the opportunity to run
+machine-specific fixups.
+
+In the majority of cases, the machine identity is irrelevant, and the
+kernel will instead select setup code based on the machine's core
+CPU or SoC. On ARM for example, setup_arch() in
+arch/arm/kernel/setup.c will call setup_machine_fdt() in
+arch/arm/kernel/devicetree.c which searches through the machine_desc
+table and selects the machine_desc which best matches the device tree
+data. It determines the best match by looking at the 'compatible'
+property in the root device tree node, and comparing it with the
+dt_compat list in struct machine_desc.
+
+The 'compatible' property contains a sorted list of strings starting
+with the exact name of the machine, followed by an optional list of
+boards it is compatible with sorted from most compatible to least. For
+example, the root compatible properties for the TI BeagleBoard and its
+successor, the BeagleBoard xM board might look like:
+
+ compatible = "ti,omap3-beagleboard", "ti,omap3450", "ti,omap3";
+ compatible = "ti,omap3-beagleboard-xm", "ti,omap3450", "ti,omap3";
+
+Where "ti,omap3-beagleboard-xm" specifies the exact model, it also
+claims that it compatible with the OMAP 3450 SoC, and the omap3 family
+of SoCs in general. You'll notice that the list is sorted from most
+specific (exact board) to least specific (SoC family).
+
+Astute readers might point out that the Beagle xM could also claim
+compatibility with the original Beagle board. However, one should be
+cautioned about doing so at the board level since there is typically a
+high level of change from one board to another, even within the same
+product line, and it is hard to nail down exactly what is meant when one
+board claims to be compatible with another. For the top level, it is
+better to err on the side of caution and not claim one board is
+compatible with another. The notable exception would be when one
+board is a carrier for another, such as a CPU module attached to a
+carrier board.
+
+One more note on compatible values. Any string used in a compatible
+property must be documented as to what it indicates. Add
+documentation for compatible strings in Documentation/devicetree/bindings.
+
+Again on ARM, for each machine_desc, the kernel looks to see if
+any of the dt_compat list entries appear in the compatible property.
+If one does, then that machine_desc is a candidate for driving the
+machine. After searching the entire table of machine_descs,
+setup_machine_fdt() returns the 'most compatible' machine_desc based
+on which entry in the compatible property each machine_desc matches
+against. If no matching machine_desc is found, then it returns NULL.
+
+The reasoning behind this scheme is the observation that in the majority
+of cases, a single machine_desc can support a large number of boards
+if they all use the same SoC, or same family of SoCs. However,
+invariably there will be some exceptions where a specific board will
+require special setup code that is not useful in the generic case.
+Special cases could be handled by explicitly checking for the
+troublesome board(s) in generic setup code, but doing so very quickly
+becomes ugly and/or unmaintainable if it is more than just a couple of
+cases.
+
+Instead, the compatible list allows a generic machine_desc to provide
+support for a wide common set of boards by specifying "less
+compatible" value in the dt_compat list. In the example above,
+generic board support can claim compatibility with "ti,omap3" or
+"ti,omap3450". If a bug was discovered on the original beagleboard
+that required special workaround code during early boot, then a new
+machine_desc could be added which implements the workarounds and only
+matches on "ti,omap3-beagleboard".
+
+PowerPC uses a slightly different scheme where it calls the .probe()
+hook from each machine_desc, and the first one returning TRUE is used.
+However, this approach does not take into account the priority of the
+compatible list, and probably should be avoided for new architecture
+support.
+
+<h4>Runtime configuration</h4>
+In most cases, a DT will be the sole method of communicating data from
+firmware to the kernel, so also gets used to pass in runtime and
+configuration data like the kernel parameters string and the location
+of an initrd image.
+
+Most of this data is contained in the /chosen node, and when booting
+Linux it will look something like this:
+
+ chosen {
+ bootargs = "console=ttyS0,115200 loglevel=8";
+ initrd-start = &lt;0xc8000000&gt;;
+ initrd-end = &lt;0xc8200000&gt;;
+ };
+
+The bootargs property contains the kernel arguments, and the initrd-*
+properties define the address and size of an initrd blob. The
+chosen node may also optionally contain an arbitrary number of
+additional properties for platform-specific configuration data.
+
+During early boot, the architecture setup code calls of_scan_flat_dt()
+several times with different helper callbacks to parse device tree
+data before paging is setup. The of_scan_flat_dt() code scans through
+the device tree and uses the helpers to extract information required
+during early boot. Typically the early_init_dt_scan_chosen() helper
+is used to parse the chosen node including kernel parameters,
+early_init_dt_scan_root() to initialize the DT address space model,
+and early_init_dt_scan_memory() to determine the size and
+location of usable RAM.
+
+On ARM, the function setup_machine_fdt() is responsible for early
+scanning of the device tree after selecting the correct machine_desc
+that supports the board.
+
+<h4>Device population</h4>
+After the board has been identified, and after the early configuration data
+has been parsed, then kernel initialization can proceed in the normal
+way. At some point in this process, unflatten_device_tree() is called
+to convert the data into a more efficient runtime representation.
+This is also when machine-specific setup hooks will get called, like
+the machine_desc .init_early(), .init_irq() and .init_machine() hooks
+on ARM. The remainder of this section uses examples from the ARM
+implementation, but all architectures will do pretty much the same
+thing when using a DT.
+
+As can be guessed by the names, .init_early() is used for any machine-
+specific setup that needs to be executed early in the boot process,
+and .init_irq() is used to set up interrupt handling. Using a DT
+doesn't materially change the behaviour of either of these functions.
+If a DT is provided, then both .init_early() and .init_irq() are able
+to call any of the DT query functions (of_* in include/linux/of*.h) to
+get additional data about the platform.
+
+The most interesting hook in the DT context is .init_machine() which
+is primarily responsible for populating the Linux device model with
+data about the platform. Historically this has been implemented on
+embedded platforms by defining a set of static clock structures,
+platform_devices, and other data in the board support .c file, and
+registering it en-masse in .init_machine(). When DT is used, then
+instead of hard coding static devices for each platform, the list of
+devices can be obtained by parsing the DT, and allocating device
+structures dynamically.
+
+The simplest case is when .init_machine() is only responsible for
+registering a block of platform_devices. A platform_device is a concept
+used by Linux for memory or I/O mapped devices which cannot be detected
+by hardware, and for 'composite' or 'virtual' devices (more on those
+later). While there is no 'platform device' terminology for the DT,
+platform devices roughly correspond to device nodes at the root of the
+tree and children of simple memory mapped bus nodes.
+
+About now is a good time to lay out an example. Here is part of the
+device tree for the NVIDIA Tegra board.
+
+/{
+ compatible = "nvidia,harmony", "nvidia,tegra20";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+
+ chosen { };
+ aliases { };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>;
+ };
+
+ soc {
+ compatible = "nvidia,tegra20-soc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ intc: interrupt-controller@50041000 {
+ compatible = "nvidia,tegra20-gic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x50041000 0x1000>, < 0x50040100 0x0100 >;
+ };
+
+ serial@70006300 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006300 0x100>;
+ interrupts = <122>;
+ };
+
+ i2s-1: i2s@70002800 {
+ compatible = "nvidia,tegra20-i2s";
+ reg = <0x70002800 0x100>;
+ interrupts = <77>;
+ codec = <&wm8903>;
+ };
+
+ i2c@7000c000 {
+ compatible = "nvidia,tegra20-i2c";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x7000c000 0x100>;
+ interrupts = <70>;
+
+ wm8903: codec@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupts = <347>;
+ };
+ };
+ };
+
+ sound {
+ compatible = "nvidia,harmony-sound";
+ i2s-controller = <&i2s-1>;
+ i2s-codec = <&wm8903>;
+ };
+};
+
+At .machine_init() time, Tegra board support code will need to look at
+this DT and decide which nodes to create platform_devices for.
+However, looking at the tree, it is not immediately obvious what kind
+of device each node represents, or even if a node represents a device
+at all. The /chosen, /aliases, and /memory nodes are informational
+nodes that don't describe devices (although arguably memory could be
+considered a device). The children of the /soc node are memory mapped
+devices, but the codec@1a is an i2c device, and the sound node
+represents not a device, but rather how other devices are connected
+together to create the audio subsystem. I know what each device is
+because I'm familiar with the board design, but how does the kernel
+know what to do with each node?
+
+The trick is that the kernel starts at the root of the tree and looks
+for nodes that have a 'compatible' property. First, it is generally
+assumed that any node with a 'compatible' property represents a device
+of some kind, and second, it can be assumed that any node at the root
+of the tree is either directly attached to the processor bus, or is a
+miscellaneous system device that cannot be described any other way.
+For each of these nodes, Linux allocates and registers a
+platform_device, which in turn may get bound to a platform_driver.
+
+Why is using a platform_device for these nodes a safe assumption?
+Well, for the way that Linux models devices, just about all bus_types
+assume that its devices are children of a bus controller. For
+example, each i2c_client is a child of an i2c_master. Each spi_device
+is a child of an SPI bus. Similarly for USB, PCI, MDIO, etc. The
+same hierarchy is also found in the DT, where I2C device nodes only
+ever appear as children of an I2C bus node. Ditto for SPI, MDIO, USB,
+etc. The only devices which do not require a specific type of parent
+device are platform_devices (and amba_devices, but more on that
+later), which will happily live at the base of the Linux /sys/devices
+tree. Therefore, if a DT node is at the root of the tree, then it
+really probably is best registered as a platform_device.
+
+Linux board support code calls of_platform_populate(NULL, NULL, NULL)
+to kick off discovery of devices at the root of the tree. The
+parameters are all NULL because when starting from the root of the
+tree, there is no need to provide a starting node (the first NULL), a
+parent struct device (the last NULL), and we're not using a match
+table (yet). For a board that only needs to register devices,
+.init_machine() can be completely empty except for the
+of_platform_populate() call.
+
+In the Tegra example, this accounts for the /soc and /sound nodes, but
+what about the children of the SoC node? Shouldn't they be registered
+as platform devices too? For Linux DT support, the generic behaviour
+is for child devices to be registered by the parent's device driver at
+driver .probe() time. So, an i2c bus device driver will register a
+i2c_client for each child node, an SPI bus driver will register
+its spi_device children, and similarly for other bus_types.
+According to that model, a driver could be written that binds to the
+SoC node and simply registers platform_devices for each of its
+children. The board support code would allocate and register an SoC
+device, an SoC device driver would bind to the SoC device, and
+register platform_devices for /soc/interrupt-controller, /soc/serial,
+/soc/i2s, and /soc/i2c in its .probe() hook. Easy, right? Although
+it is a lot of mucking about for just registering platform devices.
+
+It turns out that registering children of certain platform_devices as
+more platform_devices is a common pattern, and the device tree support
+code reflects that. The second argument to of_platform_populate() is
+an of_device_id table, and any node that matches an entry in that
+table will also get its child nodes registered. In the tegra case,
+the code can look something like this:
+
+static struct of_device_id harmony_bus_ids[] __initdata = {
+ { .compatible = "simple-bus", },
+ {}
+};
+
+static void __init harmony_init_machine(void)
+{
+ /* ... */
+ of_platform_populate(NULL, harmony_bus_ids, NULL);
+}
+
+"simple-bus" is defined in the ePAPR 1.0 specification as a property
+meaning a simple memory mapped bus, so the of_platform_populate() code
+could be written to just assume simple-bus compatible nodes will
+always be traversed. However, we pass it in as an argument so that
+board support code can always override the default behaviour.
+
+<h2>Appendix A: AMBA devices</h2>
+
+ARM Primecells are a certain kind of device attached to the ARM AMBA
+bus which include some support for hardware detection and power
+management. In Linux, struct amba_device and the amba_bus_type is
+used to represent Primecell devices. However, the fiddly bit is that
+not all devices on an AMBA bus are Primecells, and for Linux it is
+typical for both amba_device and platform_device instances to be
+siblings of the same bus segment.
+
+When using the DT, this creates problems for of_platform_populate()
+because it must decide whether to register each node as either a
+platform_device or an amba_device. This unfortunately complicates the
+device creation model a little bit, but the solution turns out not to
+be too invasive. If a node is compatible with "arm,amba-primecell", then
+of_platform_populate() will register it as an amba_device instead of a
+platform_device.
diff --git a/arch/arm/boot/dts/exynos4-smdkv310.dts b/arch/arm/boot/dts/exynos4-smdkv310.dts
new file mode 100644
index 00000000000..dd6c80a7ffc
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4-smdkv310.dts
@@ -0,0 +1,11 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Samsung Exynos4 SMDKV310 eval board";
+ compatible = "samsung,smdkv310", "samsung,s5pv310";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/genesi-efikamx.dts b/arch/arm/boot/dts/genesi-efikamx.dts
new file mode 100644
index 00000000000..e81ffcc8443
--- /dev/null
+++ b/arch/arm/boot/dts/genesi-efikamx.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Genesi EfikaMX nettop";
+ compatible = "genesi,efikamx", "fsl,mx51";
+
+ memory {
+ reg = <0x90000000 0x20000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/genesi-efikasb.dts b/arch/arm/boot/dts/genesi-efikasb.dts
new file mode 100644
index 00000000000..9fda6ae314e
--- /dev/null
+++ b/arch/arm/boot/dts/genesi-efikasb.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Genesi Efika Smartbook";
+ compatible = "genesi,efikasb", "fsl,mx51";
+
+ memory {
+ reg = <0x90000000 0x20000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/isee-igep-v2.dts b/arch/arm/boot/dts/isee-igep-v2.dts
new file mode 100644
index 00000000000..72caabb85b7
--- /dev/null
+++ b/arch/arm/boot/dts/isee-igep-v2.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "ISSE IGEPv2 Board";
+ compatible = "ISEE,igep-v2";
+};
diff --git a/arch/arm/boot/dts/isee-igep-v3.dts b/arch/arm/boot/dts/isee-igep-v3.dts
new file mode 100644
index 00000000000..f40886fef69
--- /dev/null
+++ b/arch/arm/boot/dts/isee-igep-v3.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "ISSE IGEPv3 Module";
+ compatible = "ISEE,igep-v3";
+};
diff --git a/arch/arm/boot/dts/mx51-babbage.dts b/arch/arm/boot/dts/mx51-babbage.dts
new file mode 100644
index 00000000000..e5e9c8913d0
--- /dev/null
+++ b/arch/arm/boot/dts/mx51-babbage.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Freescale i.MX51 Babbage";
+ compatible = "fsl,mx51-babbage", "fsl,mx51";
+
+ memory {
+ reg = <0x90000000 0x20000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/mx53-loco.dts b/arch/arm/boot/dts/mx53-loco.dts
new file mode 100644
index 00000000000..8426c620614
--- /dev/null
+++ b/arch/arm/boot/dts/mx53-loco.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Freescale i.MX53 LOCO";
+ compatible = "fsl,mx53-loco", "fsl,mx53";
+
+ memory {
+ reg = <0x70000000 0x40000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-overo.dts b/arch/arm/boot/dts/omap3-overo.dts
new file mode 100644
index 00000000000..c61f0112bf3
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-overo.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Gumstix Overo";
+ compatible = "gumstix,omap3-overo";
+};
diff --git a/arch/arm/boot/dts/vexpress.dts b/arch/arm/boot/dts/vexpress.dts
new file mode 100644
index 00000000000..5f3bc1d1f1c
--- /dev/null
+++ b/arch/arm/boot/dts/vexpress.dts
@@ -0,0 +1,10 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "ARM Versatile Express";
+ compatible = "arm,vexpress";
+ memory {
+ reg = <0x60000000 0x40000000>;
+ };
+};
diff --git a/arch/arm/mach-exynos/Makefile.boot b/arch/arm/mach-exynos/Makefile.boot
index b9862e22bf1..5edf9f81d37 100644
--- a/arch/arm/mach-exynos/Makefile.boot
+++ b/arch/arm/mach-exynos/Makefile.boot
@@ -1,2 +1,4 @@
zreladdr-y += 0x40008000
params_phys-y := 0x40000100
+
+dtb-$(CONFIG_MACH_SMDKV310) += exynos4-smdkv310.dtb
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index edc60b6108e..2f349cbade0 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -370,6 +370,11 @@ static void __init smdkv310_machine_init(void)
s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
}
+static char const *smdkv310_dt_compat[] __initdata = {
+ "samsung,smdkv310",
+ NULL
+};
+
MACHINE_START(SMDKV310, "SMDKV310")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
@@ -390,4 +395,5 @@ MACHINE_START(SMDKC210, "SMDKC210")
.handle_irq = gic_handle_irq,
.init_machine = smdkv310_machine_init,
.timer = &exynos4_timer,
+ .dt_compat = smdkv310_dt_compat,
MACHINE_END
diff --git a/arch/arm/mach-mx5/Makefile.boot b/arch/arm/mach-mx5/Makefile.boot
index ca207ca305e..0e8a0ec082e 100644
--- a/arch/arm/mach-mx5/Makefile.boot
+++ b/arch/arm/mach-mx5/Makefile.boot
@@ -7,3 +7,8 @@ initrd_phys-$(CONFIG_ARCH_MX51) := 0x90800000
zreladdr-$(CONFIG_ARCH_MX53) += 0x70008000
params_phys-$(CONFIG_ARCH_MX53) := 0x70000100
initrd_phys-$(CONFIG_ARCH_MX53) := 0x70800000
+
+dtb-$(CONFIG_MACH_MX51_BABBAGE) += mx51-babbage.dtb
+dtb-$(CONFIG_MACH_MX51_EFIKAMX) += genesi-efikamx.dtb
+dtb-$(CONFIG_MACH_MX51_EFIKASB) += genesi-efikasb.dtb
+dtb-$(CONFIG_MACH_MX53_LOCO) += mx53-loco.dtb
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index 24994bb5214..bb821ed219a 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -417,6 +417,11 @@ static struct sys_timer mx51_babbage_timer = {
.init = mx51_babbage_timer_init,
};
+static const char *mx51_babbage_dt_match[] __initdata = {
+ "fsl,mx51-babbage",
+ NULL
+};
+
MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")
/* Maintainer: Amit Kucheria <amit.kucheria@canonical.com> */
.atag_offset = 0x100,
@@ -426,4 +431,5 @@ MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")
.handle_irq = imx51_handle_irq,
.timer = &mx51_babbage_timer,
.init_machine = mx51_babbage_init,
+ .dt_compat = mx51_babbage_dt_match,
MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-mx5/board-mx51_efikamx.c
index a9e48662cf7..667bc3c5661 100644
--- a/arch/arm/mach-mx5/board-mx51_efikamx.c
+++ b/arch/arm/mach-mx5/board-mx51_efikamx.c
@@ -283,6 +283,11 @@ static struct sys_timer mx51_efikamx_timer = {
.init = mx51_efikamx_timer_init,
};
+static const char *mx51_efikamx_dt_match[] __initdata = {
+ "genesi,efikamx",
+ NULL
+};
+
MACHINE_START(MX51_EFIKAMX, "Genesi EfikaMX nettop")
/* Maintainer: Amit Kucheria <amit.kucheria@linaro.org> */
.atag_offset = 0x100,
@@ -292,4 +297,5 @@ MACHINE_START(MX51_EFIKAMX, "Genesi EfikaMX nettop")
.handle_irq = imx51_handle_irq,
.timer = &mx51_efikamx_timer,
.init_machine = mx51_efikamx_init,
+ .dt_compat = mx51_efikamx_dt_match,
MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx51_efikasb.c b/arch/arm/mach-mx5/board-mx51_efikasb.c
index 38c4a3e28d3..d2b4e0ee604 100644
--- a/arch/arm/mach-mx5/board-mx51_efikasb.c
+++ b/arch/arm/mach-mx5/board-mx51_efikasb.c
@@ -279,6 +279,11 @@ static struct sys_timer mx51_efikasb_timer = {
.init = mx51_efikasb_timer_init,
};
+static const char *mx51_efikasb_dt_match[] __initdata = {
+ "genesi,efikasb",
+ NULL
+};
+
MACHINE_START(MX51_EFIKASB, "Genesi Efika Smartbook")
.atag_offset = 0x100,
.map_io = mx51_map_io,
@@ -287,4 +292,5 @@ MACHINE_START(MX51_EFIKASB, "Genesi Efika Smartbook")
.handle_irq = imx51_handle_irq,
.init_machine = efikasb_board_init,
.timer = &mx51_efikasb_timer,
+ .dt_compat = mx51_efikasb_dt_match,
MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c
index 237bdecd933..9d6811d2fc8 100644
--- a/arch/arm/mach-mx5/board-mx53_loco.c
+++ b/arch/arm/mach-mx5/board-mx53_loco.c
@@ -310,6 +310,10 @@ static struct sys_timer mx53_loco_timer = {
.init = mx53_loco_timer_init,
};
+static const char *mx53_loco_dt_match[] __initdata = {
+ "fsl,mx53-loco",
+ NULL
+};
MACHINE_START(MX53_LOCO, "Freescale MX53 LOCO Board")
.map_io = mx53_map_io,
.init_early = imx53_init_early,
@@ -317,4 +321,5 @@ MACHINE_START(MX53_LOCO, "Freescale MX53 LOCO Board")
.handle_irq = imx53_handle_irq,
.timer = &mx53_loco_timer,
.init_machine = mx53_loco_board_init,
+ .dt_compat = mx53_loco_dt_match,
MACHINE_END
diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot
index b03e562acc6..eab4c41e41b 100644
--- a/arch/arm/mach-omap2/Makefile.boot
+++ b/arch/arm/mach-omap2/Makefile.boot
@@ -1,3 +1,9 @@
zreladdr-y += 0x80008000
params_phys-y := 0x80000100
initrd_phys-y := 0x80800000
+
+dtb-$(CONFIG_MACH_OMAP3_BEAGLE) += omap3-beagle.dtb
+dtb-$(CONFIG_MACH_OMAP4_PANDA) += omap4-panda.dtb
+dtb-$(CONFIG_MACH_OVERO) += omap3-overo.dtb
+dtb-$(CONFIG_MACH_IGEP0020) += isee-igep-v2.dtb
+dtb-$(CONFIG_MACH_IGEP0030) += isee-igep-v3.dtb
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 5949f6ae3ed..416f9e08c9c 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -666,6 +666,11 @@ static void __init igep_init(void)
}
}
+static const char *igep2_dt_compat[] = {
+ "ISEE,igep-v2",
+ NULL
+};
+
MACHINE_START(IGEP0020, "IGEP v2 board")
.atag_offset = 0x100,
.reserve = omap_reserve,
@@ -675,8 +680,14 @@ MACHINE_START(IGEP0020, "IGEP v2 board")
.handle_irq = omap3_intc_handle_irq,
.init_machine = igep_init,
.timer = &omap3_timer,
+ .dt_compat = igep2_dt_compat,
MACHINE_END
+static const char *igep3_dt_compat[] = {
+ "ISEE,igep-v3",
+ NULL
+};
+
MACHINE_START(IGEP0030, "IGEP OMAP3 module")
.atag_offset = 0x100,
.reserve = omap_reserve,
@@ -686,4 +697,5 @@ MACHINE_START(IGEP0030, "IGEP OMAP3 module")
.handle_irq = omap3_intc_handle_irq,
.init_machine = igep_init,
.timer = &omap3_timer,
+ .dt_compat = &igep3_dt_compat,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index c34f5658828..5cf3c9319a8 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -552,6 +552,11 @@ static void __init omap3_beagle_init(void)
beagle_opp_init();
}
+static const char *omap3_beagle_dt_match[] = {
+ "ti,omap3-beagle",
+ NULL
+};
+
MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
/* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
.atag_offset = 0x100,
@@ -562,4 +567,5 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap3_beagle_init,
.timer = &omap3_secure_timer,
+ .dt_compat = omap3_beagle_dt_match,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index b6f114436db..fc962acf15c 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -570,6 +570,11 @@ static void __init omap4_panda_init(void)
omap4_panda_display_init();
}
+static const char *omap4_panda_match[] = {
+ "ti,omap4-panda",
+ NULL,
+};
+
MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
/* Maintainer: David Anders - Texas Instruments Inc */
.atag_offset = 0x100,
@@ -580,4 +585,5 @@ MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
.handle_irq = gic_handle_irq,
.init_machine = omap4_panda_init,
.timer = &omap4_timer,
+ .dt_compat = omap4_panda_match,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 60a61ea759b..df934e45717 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -556,6 +556,11 @@ static void __init overo_init(void)
"OVERO_GPIO_USBH_CPEN\n");
}
+static const char *omap3_overo_dt_match[] = {
+ "gumstix,omap3-overo",
+ NULL
+};
+
MACHINE_START(OVERO, "Gumstix Overo")
.atag_offset = 0x100,
.reserve = omap_reserve,
@@ -565,4 +570,5 @@ MACHINE_START(OVERO, "Gumstix Overo")
.handle_irq = omap3_intc_handle_irq,
.init_machine = overo_init,
.timer = &omap3_timer,
+ .dt_compat = omap3_overo_dt_match,
MACHINE_END
diff --git a/arch/arm/mach-versatile/Makefile.boot b/arch/arm/mach-versatile/Makefile.boot
index ff0a4b5b0a8..6910b314456 100644
--- a/arch/arm/mach-versatile/Makefile.boot
+++ b/arch/arm/mach-versatile/Makefile.boot
@@ -2,3 +2,5 @@
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
+dtb-$(CONFIG_MACH_VERSATILE_DT) += versatile-pb.dtb
+dtb-$(CONFIG_MACH_VERSATILE_DT) += versatile-ab.dtb
diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot
index 8630b3d10a4..27f47b75a89 100644
--- a/arch/arm/mach-vexpress/Makefile.boot
+++ b/arch/arm/mach-vexpress/Makefile.boot
@@ -1,3 +1,5 @@
zreladdr-y += 0x60008000
params_phys-y := 0x60000100
initrd_phys-y := 0x60800000
+
+dtb-$(CONFIG_ARCH_VEXPRESS_CA9X4) += vexpress.dtb
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 7aa07a8ce23..d44f542ab8a 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -443,6 +443,11 @@ static void __init v2m_init(void)
ct_desc->init_tile();
}
+static const char *vexpress_dt_match[] __initdata = {
+ "arm,vexpress",
+ NULL,
+};
+
MACHINE_START(VEXPRESS, "ARM-Versatile Express")
.atag_offset = 0x100,
.map_io = v2m_map_io,
@@ -451,4 +456,5 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express")
.timer = &v2m_timer,
.handle_irq = gic_handle_irq,
.init_machine = v2m_init,
+ .dt_compat = vexpress_dt_match,
MACHINE_END
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 63b3ec48c20..7cf22e1f6ed 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -349,6 +349,7 @@ static int of_platform_bus_create(struct device_node *bus,
struct platform_device *dev;
const char *bus_id = NULL;
void *platform_data = NULL;
+ int id = -1;
int rc = 0;
/* Make sure it has a compatible property */
@@ -361,6 +362,7 @@ static int of_platform_bus_create(struct device_node *bus,
auxdata = of_dev_lookup(lookup, bus);
if (auxdata) {
bus_id = auxdata->name;
+ id = auxdata->id;
platform_data = auxdata->platform_data;
}
@@ -370,6 +372,11 @@ static int of_platform_bus_create(struct device_node *bus,
}
dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);
+
+ /* override the id if auxdata gives an id */
+ if (id != -1)
+ dev->id = id;
+
if (!dev || !of_match_node(matches, bus))
return 0;
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 040ce2f6e8d..2e6631f4c13 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -44,13 +44,18 @@ struct of_dev_auxdata {
char *compatible;
resource_size_t phys_addr;
char *name;
+ int id;
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 }
+ .id = -1, .platform_data = _pdata }
+
+#define OF_DEV_AUXDATA_ID(_compat,_phys,_name,_id,_pdata) \
+ { .compatible = _compat, .phys_addr = _phys, .name = _name, \
+ .id = _id, .platform_data = _pdata }
/**
* of_platform_driver - Legacy of-aware driver for platform devices.