aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2011-10-04 16:54:30 -0400
committerTony Lindgren <tony@atomide.com>2011-10-04 16:54:30 -0400
commit3ae3e253db7385238dd9d6c67c085afa3e770a56 (patch)
treec3f93d9742c4654c9d10af829db1122bac0b6f6f
parentc541c15fb5ab48c47bc9b90121538fd30d152f23 (diff)
parent476b679a5d785d1244f6b43ad26877acf278cd18 (diff)
Merge branch 'for_3.2/3_omap_devicetree' of git://gitorious.org/omap-pm/linux into dt
-rw-r--r--Documentation/devicetree/bindings/arm/omap/dsp.txt14
-rw-r--r--Documentation/devicetree/bindings/arm/omap/iva.txt19
-rw-r--r--Documentation/devicetree/bindings/arm/omap/l3-noc.txt19
-rw-r--r--Documentation/devicetree/bindings/arm/omap/mpu.txt27
-rw-r--r--Documentation/devicetree/bindings/arm/omap/omap.txt43
-rw-r--r--arch/arm/boot/dts/omap3-beagle.dts29
-rw-r--r--arch/arm/boot/dts/omap3.dtsi63
-rw-r--r--arch/arm/boot/dts/omap4-panda.dts29
-rw-r--r--arch/arm/boot/dts/omap4-sdp.dts29
-rw-r--r--arch/arm/boot/dts/omap4.dtsi103
-rw-r--r--arch/arm/mach-omap2/Kconfig8
-rw-r--r--arch/arm/mach-omap2/board-generic.c156
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c4
-rw-r--r--arch/arm/mach-omap2/devices.c51
-rw-r--r--arch/arm/mach-omap2/display.c11
-rw-r--r--arch/arm/mach-omap2/dma.c11
-rw-r--r--arch/arm/mach-omap2/gpio.c12
-rw-r--r--arch/arm/mach-omap2/hsmmc.c18
-rw-r--r--arch/arm/mach-omap2/hwspinlock.c12
-rw-r--r--arch/arm/mach-omap2/mcbsp.c11
-rw-r--r--arch/arm/mach-omap2/omap_l3_noc.c25
-rw-r--r--arch/arm/mach-omap2/pm.c72
-rw-r--r--arch/arm/mach-omap2/serial.c25
-rw-r--r--arch/arm/mach-omap2/sr_device.c11
-rw-r--r--arch/arm/mach-omap2/usb-musb.c11
-rw-r--r--arch/arm/plat-omap/i2c.c10
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h1
-rw-r--r--arch/arm/plat-omap/omap_device.c313
-rw-r--r--drivers/of/base.c84
-rw-r--r--include/linux/of.h18
30 files changed, 929 insertions, 310 deletions
diff --git a/Documentation/devicetree/bindings/arm/omap/dsp.txt b/Documentation/devicetree/bindings/arm/omap/dsp.txt
new file mode 100644
index 000000000000..d3830a32ce08
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/dsp.txt
@@ -0,0 +1,14 @@
1* TI - DSP (Digital Signal Processor)
2
3TI DSP included in OMAP SoC
4
5Required properties:
6- compatible : Should be "ti,omap3-c64" for OMAP3 & 4
7- ti,hwmods: "dsp"
8
9Examples:
10
11dsp {
12 compatible = "ti,omap3-c64";
13 ti,hwmods = "dsp";
14};
diff --git a/Documentation/devicetree/bindings/arm/omap/iva.txt b/Documentation/devicetree/bindings/arm/omap/iva.txt
new file mode 100644
index 000000000000..6d6295171358
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/iva.txt
@@ -0,0 +1,19 @@
1* TI - IVA (Imaging and Video Accelerator) subsystem
2
3The IVA contain various audio, video or imaging HW accelerator
4depending of the version.
5
6Required properties:
7- compatible : Should be:
8 - "ti,ivahd" for OMAP4
9 - "ti,iva2.2" for OMAP3
10 - "ti,iva2.1" for OMAP2430
11 - "ti,iva1" for OMAP2420
12- ti,hwmods: "iva"
13
14Examples:
15
16iva {
17 compatible = "ti,ivahd", "ti,iva";
18 ti,hwmods = "iva";
19};
diff --git a/Documentation/devicetree/bindings/arm/omap/l3-noc.txt b/Documentation/devicetree/bindings/arm/omap/l3-noc.txt
new file mode 100644
index 000000000000..6888a5efc860
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/l3-noc.txt
@@ -0,0 +1,19 @@
1* TI - L3 Network On Chip (NoC)
2
3This version is an implementation of the generic NoC IP
4provided by Arteris.
5
6Required properties:
7- compatible : Should be "ti,omap3-l3-smx" for OMAP3 family
8 Should be "ti,omap4-l3-noc" for OMAP4 family
9- ti,hwmods: "l3_main_1", ... One hwmod for each noc domain.
10
11Examples:
12
13ocp {
14 compatible = "ti,omap4-l3-noc", "simple-bus";
15 #address-cells = <1>;
16 #size-cells = <1>;
17 ranges;
18 ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
19};
diff --git a/Documentation/devicetree/bindings/arm/omap/mpu.txt b/Documentation/devicetree/bindings/arm/omap/mpu.txt
new file mode 100644
index 000000000000..1a5a42ce21bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/mpu.txt
@@ -0,0 +1,27 @@
1* TI - MPU (Main Processor Unit) subsystem
2
3The MPU subsystem contain one or several ARM cores
4depending of the version.
5The MPU contain CPUs, GIC, L2 cache and a local PRCM.
6
7Required properties:
8- compatible : Should be "ti,omap3-mpu" for OMAP3
9 Should be "ti,omap4-mpu" for OMAP4
10- ti,hwmods: "mpu"
11
12Examples:
13
14- For an OMAP4 SMP system:
15
16mpu {
17 compatible = "ti,omap4-mpu";
18 ti,hwmods = "mpu";
19};
20
21
22- For an OMAP3 monocore system:
23
24mpu {
25 compatible = "ti,omap3-mpu";
26 ti,hwmods = "mpu";
27};
diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt
new file mode 100644
index 000000000000..dbdab40ed3a6
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/omap.txt
@@ -0,0 +1,43 @@
1* Texas Instruments OMAP
2
3OMAP is currently using a static file per SoC family to describe the
4IPs present in the SoC.
5On top of that an omap_device is created to extend the platform_device
6capabilities and to allow binding with one or several hwmods.
7The hwmods will contain all the information to build the device:
8adresse range, irq lines, dma lines, interconnect, PRCM register,
9clock domain, input clocks.
10For the moment just point to the existing hwmod, the next step will be
11to move data from hwmod to device-tree representation.
12
13
14Required properties:
15- compatible: Every devices present in OMAP SoC should be in the
16 form: "ti,XXX"
17- ti,hwmods: list of hwmod names (ascii strings), that comes from the OMAP
18 HW documentation, attached to a device. Must contain at least
19 one hwmod.
20
21Optional properties:
22- ti,no_idle_on_suspend: When present, it prevents the PM to idle the module
23 during suspend.
24
25
26Example:
27
28spinlock@1 {
29 compatible = "ti,omap4-spinlock";
30 ti,hwmods = "spinlock";
31};
32
33
34Boards:
35
36- OMAP3 BeagleBoard : Low cost community board
37 compatible = "ti,omap3-beagle", "ti,omap3"
38
39- OMAP4 SDP : Software Developement Board
40 compatible = "ti,omap4-sdp", "ti,omap4430"
41
42- OMAP4 PandaBoard : Low cost community board
43 compatible = "ti,omap4-panda", "ti,omap4430"
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
new file mode 100644
index 000000000000..9486be62bcdd
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8/dts-v1/;
9
10/include/ "omap3.dtsi"
11
12/ {
13 model = "TI OMAP3 BeagleBoard";
14 compatible = "ti,omap3-beagle", "ti,omap3";
15
16 /*
17 * Since the initial device tree board file does not create any
18 * devices (MMC, network...), the only way to boot is to provide a
19 * ramdisk.
20 */
21 chosen {
22 bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug earlyprintk";
23 };
24
25 memory {
26 device_type = "memory";
27 reg = <0x80000000 0x20000000>; /* 512 MB */
28 };
29};
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
new file mode 100644
index 000000000000..d202bb5ec7ef
--- /dev/null
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -0,0 +1,63 @@
1/*
2 * Device Tree Source for OMAP3 SoC
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11/include/ "skeleton.dtsi"
12
13/ {
14 compatible = "ti,omap3430", "ti,omap3";
15
16 cpus {
17 cpu@0 {
18 compatible = "arm,cortex-a8";
19 };
20 };
21
22 /*
23 * The soc node represents the soc top level view. It is uses for IPs
24 * that are not memory mapped in the MPU view or for the MPU itself.
25 */
26 soc {
27 compatible = "ti,omap-infra";
28 mpu {
29 compatible = "ti,omap3-mpu";
30 ti,hwmods = "mpu";
31 };
32
33 iva {
34 compatible = "ti,iva2.2";
35 ti,hwmods = "iva";
36
37 dsp {
38 compatible = "ti,omap3-c64";
39 };
40 };
41 };
42
43 /*
44 * XXX: Use a flat representation of the OMAP3 interconnect.
45 * The real OMAP interconnect network is quite complex.
46 * Since that will not bring real advantage to represent that in DT for
47 * the moment, just use a fake OCP bus entry to represent the whole bus
48 * hierarchy.
49 */
50 ocp {
51 compatible = "simple-bus";
52 #address-cells = <1>;
53 #size-cells = <1>;
54 ranges;
55 ti,hwmods = "l3_main";
56
57 intc: interrupt-controller@1 {
58 compatible = "ti,omap3-intc";
59 interrupt-controller;
60 #interrupt-cells = <1>;
61 };
62 };
63};
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
new file mode 100644
index 000000000000..c7026578ce7d
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8/dts-v1/;
9
10/include/ "omap4.dtsi"
11
12/ {
13 model = "TI OMAP4 PandaBoard";
14 compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";
15
16 /*
17 * Since the initial device tree board file does not create any
18 * devices (MMC, network...), the only way to boot is to provide a
19 * ramdisk.
20 */
21 chosen {
22 bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
23 };
24
25 memory {
26 device_type = "memory";
27 reg = <0x80000000 0x40000000>; /* 1 GB */
28 };
29};
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
new file mode 100644
index 000000000000..066e28c90328
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8/dts-v1/;
9
10/include/ "omap4.dtsi"
11
12/ {
13 model = "TI OMAP4 SDP board";
14 compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4";
15
16 /*
17 * Since the initial device tree board file does not create any
18 * devices (MMC, network...), the only way to boot is to provide a
19 * ramdisk.
20 */
21 chosen {
22 bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
23 };
24
25 memory {
26 device_type = "memory";
27 reg = <0x80000000 0x40000000>; /* 1 GB */
28 };
29};
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
new file mode 100644
index 000000000000..4c61c829043a
--- /dev/null
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -0,0 +1,103 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9/*
10 * Carveout for multimedia usecases
11 * It should be the last 48MB of the first 512MB memory part
12 * In theory, it should not even exist. That zone should be reserved
13 * dynamically during the .reserve callback.
14 */
15/memreserve/ 0x9d000000 0x03000000;
16
17/include/ "skeleton.dtsi"
18
19/ {
20 compatible = "ti,omap4430", "ti,omap4";
21 interrupt-parent = <&gic>;
22
23 aliases {
24 };
25
26 cpus {
27 cpu@0 {
28 compatible = "arm,cortex-a9";
29 };
30 cpu@1 {
31 compatible = "arm,cortex-a9";
32 };
33 };
34
35 /*
36 * The soc node represents the soc top level view. It is uses for IPs
37 * that are not memory mapped in the MPU view or for the MPU itself.
38 */
39 soc {
40 compatible = "ti,omap-infra";
41 mpu {
42 compatible = "ti,omap4-mpu";
43 ti,hwmods = "mpu";
44 };
45
46 dsp {
47 compatible = "ti,omap3-c64";
48 ti,hwmods = "dsp";
49 };
50
51 iva {
52 compatible = "ti,ivahd";
53 ti,hwmods = "iva";
54 };
55 };
56
57 /*
58 * XXX: Use a flat representation of the OMAP4 interconnect.
59 * The real OMAP interconnect network is quite complex.
60 *
61 * MPU -+-- MPU_PRIVATE - GIC, L2
62 * |
63 * +----------------+----------+
64 * | | |
65 * + +- EMIF - DDR |
66 * | | |
67 * | + +--------+
68 * | | |
69 * | +- L4_ABE - AESS, MCBSP, TIMERs...
70 * | |
71 * +- L3_MAIN --+- L4_CORE - IPs...
72 * |
73 * +- L4_PER - IPs...
74 * |
75 * +- L4_CFG -+- L4_WKUP - IPs...
76 * | |
77 * | +- IPs...
78 * +- IPU ----+
79 * | |
80 * +- DSP ----+
81 * | |
82 * +- DSS ----+
83 *
84 * Since that will not bring real advantage to represent that in DT for
85 * the moment, just use a fake OCP bus entry to represent the whole bus
86 * hierarchy.
87 */
88 ocp {
89 compatible = "ti,omap4-l3-noc", "simple-bus";
90 #address-cells = <1>;
91 #size-cells = <1>;
92 ranges;
93 ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
94
95 gic: interrupt-controller@48241000 {
96 compatible = "arm,cortex-a9-gic";
97 interrupt-controller;
98 #interrupt-cells = <1>;
99 reg = <0x48241000 0x1000>,
100 <0x48240100 0x0100>;
101 };
102 };
103};
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 57b66d590c52..e0a318df95bc 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -106,9 +106,13 @@ comment "OMAP Board Type"
106 depends on ARCH_OMAP2PLUS 106 depends on ARCH_OMAP2PLUS
107 107
108config MACH_OMAP_GENERIC 108config MACH_OMAP_GENERIC
109 bool "Generic OMAP board" 109 bool "Generic OMAP2+ board"
110 depends on ARCH_OMAP2 110 depends on ARCH_OMAP2PLUS
111 select USE_OF
111 default y 112 default y
113 help
114 Support for generic TI OMAP2+ boards using Flattened Device Tree.
115 More information at Documentation/devicetree
112 116
113config MACH_OMAP2_TUSB6010 117config MACH_OMAP2_TUSB6010
114 bool 118 bool
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 5223898f50e4..d9ccb9d98e15 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -1,76 +1,154 @@
1/* 1/*
2 * linux/arch/arm/mach-omap2/board-generic.c
3 *
4 * Copyright (C) 2005 Nokia Corporation 2 * Copyright (C) 2005 Nokia Corporation
5 * Author: Paul Mundt <paul.mundt@nokia.com> 3 * Author: Paul Mundt <paul.mundt@nokia.com>
6 * 4 *
7 * Modified from mach-omap/omap1/board-generic.c 5 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
8 * 6 *
9 * Code for generic OMAP2 board. Should work on many OMAP2 systems where 7 * Modified from the original mach-omap/omap2/board-generic.c did by Paul
10 * the bootloader passes the board-specific data to the kernel. 8 * to support the OMAP2+ device tree boards with an unique board file.
11 * Do not put any board specific code to this file; create a new machine
12 * type if you need custom low-level initializations.
13 * 9 *
14 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
17 */ 13 */
18 14
19#include <linux/kernel.h> 15#include <linux/io.h>
20#include <linux/init.h> 16#include <linux/of_platform.h>
21#include <linux/device.h> 17#include <linux/irqdomain.h>
18#include <linux/i2c/twl.h>
22 19
23#include <mach/hardware.h> 20#include <mach/hardware.h>
24#include <asm/mach-types.h>
25#include <asm/mach/arch.h> 21#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27 22
28#include <mach/gpio.h>
29#include <plat/usb.h>
30#include <plat/board.h> 23#include <plat/board.h>
31#include <plat/common.h> 24#include <plat/common.h>
25#include <mach/omap4-common.h>
26#include "common-board-devices.h"
27
28/*
29 * XXX: Still needed to boot until the i2c & twl driver is adapted to
30 * device-tree
31 */
32static struct twl4030_platform_data sdp4430_twldata = {
33 .irq_base = TWL6030_IRQ_BASE,
34 .irq_end = TWL6030_IRQ_END,
35};
32 36
33static struct omap_board_config_kernel generic_config[] = { 37static void __init omap4_i2c_init(void)
38{
39 omap4_pmic_init("twl6030", &sdp4430_twldata);
40}
41
42static struct twl4030_platform_data beagle_twldata = {
43 .irq_base = TWL4030_IRQ_BASE,
44 .irq_end = TWL4030_IRQ_END,
34}; 45};
35 46
36static void __init omap_generic_init_early(void) 47static void __init omap3_i2c_init(void)
37{ 48{
38 omap2_init_common_infrastructure(); 49 omap3_pmic_init("twl4030", &beagle_twldata);
39} 50}
40 51
52static struct of_device_id omap_dt_match_table[] __initdata = {
53 { .compatible = "simple-bus", },
54 { .compatible = "ti,omap-infra", },
55 { }
56};
57
58static struct of_device_id intc_match[] __initdata = {
59 { .compatible = "ti,omap3-intc", },
60 { .compatible = "arm,cortex-a9-gic", },
61 { }
62};
63
41static void __init omap_generic_init(void) 64static void __init omap_generic_init(void)
42{ 65{
66 struct device_node *node = of_find_matching_node(NULL, intc_match);
67 if (node)
68 irq_domain_add_simple(node, 0);
69
43 omap_serial_init(); 70 omap_serial_init();
44 omap_sdrc_init(NULL, NULL); 71 omap_sdrc_init(NULL, NULL);
45 omap_board_config = generic_config; 72
46 omap_board_config_size = ARRAY_SIZE(generic_config); 73 of_platform_populate(NULL, omap_dt_match_table, NULL, NULL);
47} 74}
48 75
49static void __init omap_generic_map_io(void) 76static void __init omap4_init(void)
50{ 77{
51 if (cpu_is_omap242x()) { 78 omap4_i2c_init();
52 omap2_set_globals_242x(); 79 omap_generic_init();
53 omap242x_map_common_io();
54 } else if (cpu_is_omap243x()) {
55 omap2_set_globals_243x();
56 omap243x_map_common_io();
57 } else if (cpu_is_omap34xx()) {
58 omap2_set_globals_3xxx();
59 omap34xx_map_common_io();
60 } else if (cpu_is_omap44xx()) {
61 omap2_set_globals_443x();
62 omap44xx_map_common_io();
63 }
64} 80}
65 81
66/* XXX This machine entry name should be updated */ 82static void __init omap3_init(void)
67MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") 83{
68 /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ 84 omap3_i2c_init();
69 .boot_params = 0x80000100, 85 omap_generic_init();
86}
87
88#if defined(CONFIG_SOC_OMAP2420)
89static const char *omap242x_boards_compat[] __initdata = {
90 "ti,omap2420",
91 NULL,
92};
93
94DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
70 .reserve = omap_reserve, 95 .reserve = omap_reserve,
71 .map_io = omap_generic_map_io, 96 .map_io = omap242x_map_io,
72 .init_early = omap_generic_init_early, 97 .init_early = omap2420_init_early,
73 .init_irq = omap2_init_irq, 98 .init_irq = omap2_init_irq,
74 .init_machine = omap_generic_init, 99 .init_machine = omap_generic_init,
75 .timer = &omap2_timer, 100 .timer = &omap2_timer,
101 .dt_compat = omap242x_boards_compat,
102MACHINE_END
103#endif
104
105#if defined(CONFIG_SOC_OMAP2430)
106static const char *omap243x_boards_compat[] __initdata = {
107 "ti,omap2430",
108 NULL,
109};
110
111DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
112 .reserve = omap_reserve,
113 .map_io = omap243x_map_io,
114 .init_early = omap2430_init_early,
115 .init_irq = omap2_init_irq,
116 .init_machine = omap_generic_init,
117 .timer = &omap2_timer,
118 .dt_compat = omap243x_boards_compat,
119MACHINE_END
120#endif
121
122#if defined(CONFIG_ARCH_OMAP3)
123static const char *omap3_boards_compat[] __initdata = {
124 "ti,omap3",
125 NULL,
126};
127
128DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
129 .reserve = omap_reserve,
130 .map_io = omap3_map_io,
131 .init_early = omap3430_init_early,
132 .init_irq = omap3_init_irq,
133 .init_machine = omap3_init,
134 .timer = &omap3_timer,
135 .dt_compat = omap3_boards_compat,
136MACHINE_END
137#endif
138
139#if defined(CONFIG_ARCH_OMAP4)
140static const char *omap4_boards_compat[] __initdata = {
141 "ti,omap4",
142 NULL,
143};
144
145DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
146 .reserve = omap_reserve,
147 .map_io = omap4_map_io,
148 .init_early = omap4430_init_early,
149 .init_irq = gic_init_irq,
150 .init_machine = omap4_init,
151 .timer = &omap4_timer,
152 .dt_compat = omap4_boards_compat,
76MACHINE_END 153MACHINE_END
154#endif
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index e085371eb494..4a5d75f11610 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -486,8 +486,8 @@ static void __init beagle_opp_init(void)
486 if (cpu_is_omap3630()) { 486 if (cpu_is_omap3630()) {
487 struct device *mpu_dev, *iva_dev; 487 struct device *mpu_dev, *iva_dev;
488 488
489 mpu_dev = omap2_get_mpuss_device(); 489 mpu_dev = omap_device_get_by_hwmod_name("mpu");
490 iva_dev = omap2_get_iva_device(); 490 iva_dev = omap_device_get_by_hwmod_name("iva");
491 491
492 if (!mpu_dev || !iva_dev) { 492 if (!mpu_dev || !iva_dev) {
493 pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", 493 pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 10adf66be7ba..0f8e0eb18166 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -16,6 +16,7 @@
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/of.h>
19 20
20#include <mach/hardware.h> 21#include <mach/hardware.h>
21#include <mach/irqs.h> 22#include <mach/irqs.h>
@@ -77,6 +78,10 @@ static int __init omap4_l3_init(void)
77 struct platform_device *pdev; 78 struct platform_device *pdev;
78 char oh_name[L3_MODULES_MAX_LEN]; 79 char oh_name[L3_MODULES_MAX_LEN];
79 80
81 /* If dtb is there, the devices will be created dynamically */
82 if (of_have_populated_dt())
83 return -ENODEV;
84
80 /* 85 /*
81 * To avoid code running on other OMAPs in 86 * To avoid code running on other OMAPs in
82 * multi-omap builds 87 * multi-omap builds
@@ -221,14 +226,6 @@ static inline void omap_init_camera(void)
221#endif 226#endif
222} 227}
223 228
224struct omap_device_pm_latency omap_keyboard_latency[] = {
225 {
226 .deactivate_func = omap_device_idle_hwmods,
227 .activate_func = omap_device_enable_hwmods,
228 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
229 },
230};
231
232int __init omap4_keyboard_init(struct omap4_keypad_platform_data 229int __init omap4_keyboard_init(struct omap4_keypad_platform_data
233 *sdp4430_keypad_data, struct omap_board_data *bdata) 230 *sdp4430_keypad_data, struct omap_board_data *bdata)
234{ 231{
@@ -248,9 +245,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data
248 keypad_data = sdp4430_keypad_data; 245 keypad_data = sdp4430_keypad_data;
249 246
250 pdev = omap_device_build(name, id, oh, keypad_data, 247 pdev = omap_device_build(name, id, oh, keypad_data,
251 sizeof(struct omap4_keypad_platform_data), 248 sizeof(struct omap4_keypad_platform_data), NULL, 0, 0);
252 omap_keyboard_latency,
253 ARRAY_SIZE(omap_keyboard_latency), 0);
254 249
255 if (IS_ERR(pdev)) { 250 if (IS_ERR(pdev)) {
256 WARN(1, "Can't build omap_device for %s:%s.\n", 251 WARN(1, "Can't build omap_device for %s:%s.\n",
@@ -263,14 +258,6 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data
263} 258}
264 259
265#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE) 260#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
266static struct omap_device_pm_latency mbox_latencies[] = {
267 [0] = {
268 .activate_func = omap_device_enable_hwmods,
269 .deactivate_func = omap_device_idle_hwmods,
270 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
271 },
272};
273
274static inline void omap_init_mbox(void) 261static inline void omap_init_mbox(void)
275{ 262{
276 struct omap_hwmod *oh; 263 struct omap_hwmod *oh;
@@ -282,8 +269,7 @@ static inline void omap_init_mbox(void)
282 return; 269 return;
283 } 270 }
284 271
285 pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, 272 pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, NULL, 0, 0);
286 mbox_latencies, ARRAY_SIZE(mbox_latencies), 0);
287 WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", 273 WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n",
288 __func__, PTR_ERR(pdev)); 274 __func__, PTR_ERR(pdev));
289} 275}
@@ -334,14 +320,6 @@ static inline void omap_init_audio(void) {}
334 320
335#include <plat/mcspi.h> 321#include <plat/mcspi.h>
336 322
337struct omap_device_pm_latency omap_mcspi_latency[] = {
338 [0] = {
339 .deactivate_func = omap_device_idle_hwmods,
340 .activate_func = omap_device_enable_hwmods,
341 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
342 },
343};
344
345static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) 323static int omap_mcspi_init(struct omap_hwmod *oh, void *unused)
346{ 324{
347 struct platform_device *pdev; 325 struct platform_device *pdev;
@@ -372,8 +350,7 @@ static int omap_mcspi_init(struct omap_hwmod *oh, void *unused)
372 350
373 spi_num++; 351 spi_num++;
374 pdev = omap_device_build(name, spi_num, oh, pdata, 352 pdev = omap_device_build(name, spi_num, oh, pdata,
375 sizeof(*pdata), omap_mcspi_latency, 353 sizeof(*pdata), NULL, 0, 0);
376 ARRAY_SIZE(omap_mcspi_latency), 0);
377 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", 354 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n",
378 name, oh->name); 355 name, oh->name);
379 kfree(pdata); 356 kfree(pdata);
@@ -698,14 +675,6 @@ static int __init omap2_init_devices(void)
698arch_initcall(omap2_init_devices); 675arch_initcall(omap2_init_devices);
699 676
700#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) 677#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
701static struct omap_device_pm_latency omap_wdt_latency[] = {
702 [0] = {
703 .deactivate_func = omap_device_idle_hwmods,
704 .activate_func = omap_device_enable_hwmods,
705 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
706 },
707};
708
709static int __init omap_init_wdt(void) 678static int __init omap_init_wdt(void)
710{ 679{
711 int id = -1; 680 int id = -1;
@@ -723,9 +692,7 @@ static int __init omap_init_wdt(void)
723 return -EINVAL; 692 return -EINVAL;
724 } 693 }
725 694
726 pdev = omap_device_build(dev_name, id, oh, NULL, 0, 695 pdev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0);
727 omap_wdt_latency,
728 ARRAY_SIZE(omap_wdt_latency), 0);
729 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", 696 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
730 dev_name, oh->name); 697 dev_name, oh->name);
731 return 0; 698 return 0;
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 18693f6de041..8ad0a2f0367d 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -35,14 +35,6 @@ static struct platform_device omap_display_device = {
35 }, 35 },
36}; 36};
37 37
38static struct omap_device_pm_latency omap_dss_latency[] = {
39 [0] = {
40 .deactivate_func = omap_device_idle_hwmods,
41 .activate_func = omap_device_enable_hwmods,
42 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
43 },
44};
45
46struct omap_dss_hwmod_data { 38struct omap_dss_hwmod_data {
47 const char *oh_name; 39 const char *oh_name;
48 const char *dev_name; 40 const char *dev_name;
@@ -111,8 +103,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
111 pdev = omap_device_build(curr_dss_hwmod[i].dev_name, 103 pdev = omap_device_build(curr_dss_hwmod[i].dev_name,
112 curr_dss_hwmod[i].id, oh, &pdata, 104 curr_dss_hwmod[i].id, oh, &pdata,
113 sizeof(struct omap_display_platform_data), 105 sizeof(struct omap_display_platform_data),
114 omap_dss_latency, 106 NULL, 0, 0);
115 ARRAY_SIZE(omap_dss_latency), 0);
116 107
117 if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n", 108 if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n",
118 curr_dss_hwmod[i].oh_name)) 109 curr_dss_hwmod[i].oh_name))
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index ae8cb3fb1830..a59a45a0096e 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -87,14 +87,6 @@ static u16 reg_map[] = {
87 [CCDN] = 0xd8, 87 [CCDN] = 0xd8,
88}; 88};
89 89
90static struct omap_device_pm_latency omap2_dma_latency[] = {
91 {
92 .deactivate_func = omap_device_idle_hwmods,
93 .activate_func = omap_device_enable_hwmods,
94 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
95 },
96};
97
98static void __iomem *dma_base; 90static void __iomem *dma_base;
99static inline void dma_write(u32 val, int reg, int lch) 91static inline void dma_write(u32 val, int reg, int lch)
100{ 92{
@@ -258,8 +250,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
258 250
259 p->errata = configure_dma_errata(); 251 p->errata = configure_dma_errata();
260 252
261 pdev = omap_device_build(name, 0, oh, p, sizeof(*p), 253 pdev = omap_device_build(name, 0, oh, p, sizeof(*p), NULL, 0, 0);
262 omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0);
263 kfree(p); 254 kfree(p);
264 if (IS_ERR(pdev)) { 255 if (IS_ERR(pdev)) {
265 pr_err("%s: Can't build omap_device for %s:%s.\n", 256 pr_err("%s: Can't build omap_device for %s:%s.\n",
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 652ccc574196..8cbfbc2918ce 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -24,14 +24,6 @@
24#include <plat/omap_hwmod.h> 24#include <plat/omap_hwmod.h>
25#include <plat/omap_device.h> 25#include <plat/omap_device.h>
26 26
27static struct omap_device_pm_latency omap_gpio_latency[] = {
28 [0] = {
29 .deactivate_func = omap_device_idle_hwmods,
30 .activate_func = omap_device_enable_hwmods,
31 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
32 },
33};
34
35static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) 27static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
36{ 28{
37 struct platform_device *pdev; 29 struct platform_device *pdev;
@@ -108,9 +100,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
108 } 100 }
109 101
110 pdev = omap_device_build(name, id - 1, oh, pdata, 102 pdev = omap_device_build(name, id - 1, oh, pdata,
111 sizeof(*pdata), omap_gpio_latency, 103 sizeof(*pdata), NULL, 0, false);
112 ARRAY_SIZE(omap_gpio_latency),
113 false);
114 kfree(pdata); 104 kfree(pdata);
115 105
116 if (IS_ERR(pdev)) { 106 if (IS_ERR(pdev)) {
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 2dc002a388b3..77085847e4e7 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -409,31 +409,17 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
409 return 0; 409 return 0;
410} 410}
411 411
412static struct omap_device_pm_latency omap_hsmmc_latency[] = {
413 [0] = {
414 .deactivate_func = omap_device_idle_hwmods,
415 .activate_func = omap_device_enable_hwmods,
416 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
417 },
418 /*
419 * XXX There should also be an entry here to power off/on the
420 * MMC regulators/PBIAS cells, etc.
421 */
422};
423
424#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16 412#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16
425 413
426void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) 414void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
427{ 415{
428 struct omap_hwmod *oh; 416 struct omap_hwmod *oh;
429 struct platform_device *pdev; 417 struct platform_device *pdev;
430 struct omap_device_pm_latency *ohl;
431 char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN]; 418 char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
432 struct omap_mmc_platform_data *mmc_data; 419 struct omap_mmc_platform_data *mmc_data;
433 struct omap_mmc_dev_attr *mmc_dev_attr; 420 struct omap_mmc_dev_attr *mmc_dev_attr;
434 char *name; 421 char *name;
435 int l; 422 int l;
436 int ohl_cnt = 0;
437 423
438 mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); 424 mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
439 if (!mmc_data) { 425 if (!mmc_data) {
@@ -448,8 +434,6 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
448 omap_hsmmc_mux(mmc_data, (ctrl_nr - 1)); 434 omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
449 435
450 name = "omap_hsmmc"; 436 name = "omap_hsmmc";
451 ohl = omap_hsmmc_latency;
452 ohl_cnt = ARRAY_SIZE(omap_hsmmc_latency);
453 437
454 l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN, 438 l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
455 "mmc%d", ctrl_nr); 439 "mmc%d", ctrl_nr);
@@ -468,7 +452,7 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
468 } 452 }
469 453
470 pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data, 454 pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data,
471 sizeof(struct omap_mmc_platform_data), ohl, ohl_cnt, false); 455 sizeof(struct omap_mmc_platform_data), NULL, 0, false);
472 if (IS_ERR(pdev)) { 456 if (IS_ERR(pdev)) {
473 WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name); 457 WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name);
474 kfree(mmc_data->slots[0].name); 458 kfree(mmc_data->slots[0].name);
diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c
index 0b3ae9d9c3b3..36e21091b06a 100644
--- a/arch/arm/mach-omap2/hwspinlock.c
+++ b/arch/arm/mach-omap2/hwspinlock.c
@@ -23,14 +23,6 @@
23#include <plat/omap_hwmod.h> 23#include <plat/omap_hwmod.h>
24#include <plat/omap_device.h> 24#include <plat/omap_device.h>
25 25
26struct omap_device_pm_latency omap_spinlock_latency[] = {
27 {
28 .deactivate_func = omap_device_idle_hwmods,
29 .activate_func = omap_device_enable_hwmods,
30 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
31 }
32};
33
34int __init hwspinlocks_init(void) 26int __init hwspinlocks_init(void)
35{ 27{
36 int retval = 0; 28 int retval = 0;
@@ -48,9 +40,7 @@ int __init hwspinlocks_init(void)
48 if (oh == NULL) 40 if (oh == NULL)
49 return -EINVAL; 41 return -EINVAL;
50 42
51 pdev = omap_device_build(dev_name, 0, oh, NULL, 0, 43 pdev = omap_device_build(dev_name, 0, oh, NULL, 0, NULL, 0, false);
52 omap_spinlock_latency,
53 ARRAY_SIZE(omap_spinlock_latency), false);
54 if (IS_ERR(pdev)) { 44 if (IS_ERR(pdev)) {
55 pr_err("Can't build omap_device for %s:%s\n", dev_name, 45 pr_err("Can't build omap_device for %s:%s\n", dev_name,
56 oh_name); 46 oh_name);
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 5063f253c4b9..292eee3be15f 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -122,14 +122,6 @@ static int omap3_enable_st_clock(unsigned int id, bool enable)
122 return 0; 122 return 0;
123} 123}
124 124
125struct omap_device_pm_latency omap2_mcbsp_latency[] = {
126 {
127 .deactivate_func = omap_device_idle_hwmods,
128 .activate_func = omap_device_enable_hwmods,
129 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
130 },
131};
132
133static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) 125static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
134{ 126{
135 int id, count = 1; 127 int id, count = 1;
@@ -175,8 +167,7 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
175 count++; 167 count++;
176 } 168 }
177 pdev = omap_device_build_ss(name, id, oh_device, count, pdata, 169 pdev = omap_device_build_ss(name, id, oh_device, count, pdata,
178 sizeof(*pdata), omap2_mcbsp_latency, 170 sizeof(*pdata), NULL, 0, false);
179 ARRAY_SIZE(omap2_mcbsp_latency), false);
180 kfree(pdata); 171 kfree(pdata);
181 if (IS_ERR(pdev)) { 172 if (IS_ERR(pdev)) {
182 pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, 173 pr_err("%s: Can't build omap_device for %s:%s.\n", __func__,
diff --git a/arch/arm/mach-omap2/omap_l3_noc.c b/arch/arm/mach-omap2/omap_l3_noc.c
index 07a3d3ede768..c8b1bef92e5a 100644
--- a/arch/arm/mach-omap2/omap_l3_noc.c
+++ b/arch/arm/mach-omap2/omap_l3_noc.c
@@ -127,7 +127,7 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
127 return IRQ_HANDLED; 127 return IRQ_HANDLED;
128} 128}
129 129
130static int __init omap4_l3_probe(struct platform_device *pdev) 130static int __devinit omap4_l3_probe(struct platform_device *pdev)
131{ 131{
132 static struct omap4_l3 *l3; 132 static struct omap4_l3 *l3;
133 struct resource *res; 133 struct resource *res;
@@ -218,7 +218,7 @@ err0:
218 return ret; 218 return ret;
219} 219}
220 220
221static int __exit omap4_l3_remove(struct platform_device *pdev) 221static int __devexit omap4_l3_remove(struct platform_device *pdev)
222{ 222{
223 struct omap4_l3 *l3 = platform_get_drvdata(pdev); 223 struct omap4_l3 *l3 = platform_get_drvdata(pdev);
224 224
@@ -232,16 +232,29 @@ static int __exit omap4_l3_remove(struct platform_device *pdev)
232 return 0; 232 return 0;
233} 233}
234 234
235#if defined(CONFIG_OF)
236static const struct of_device_id l3_noc_match[] = {
237 {.compatible = "ti,omap4-l3-noc", },
238 {},
239}
240MODULE_DEVICE_TABLE(of, l3_noc_match);
241#else
242#define l3_noc_match NULL
243#endif
244
235static struct platform_driver omap4_l3_driver = { 245static struct platform_driver omap4_l3_driver = {
236 .remove = __exit_p(omap4_l3_remove), 246 .probe = omap4_l3_probe,
237 .driver = { 247 .remove = __devexit_p(omap4_l3_remove),
238 .name = "omap_l3_noc", 248 .driver = {
249 .name = "omap_l3_noc",
250 .owner = THIS_MODULE,
251 .of_match_table = l3_noc_match,
239 }, 252 },
240}; 253};
241 254
242static int __init omap4_l3_init(void) 255static int __init omap4_l3_init(void)
243{ 256{
244 return platform_driver_probe(&omap4_l3_driver, omap4_l3_probe); 257 return platform_driver_register(&omap4_l3_driver);
245} 258}
246postcore_initcall_sync(omap4_l3_init); 259postcore_initcall_sync(omap4_l3_init);
247 260
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 0844e2ecfb4a..2ab7a9e17fe2 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -26,38 +26,7 @@
26 26
27static struct omap_device_pm_latency *pm_lats; 27static struct omap_device_pm_latency *pm_lats;
28 28
29static struct device *mpu_dev; 29static int _init_omap_device(char *name)
30static struct device *iva_dev;
31static struct device *l3_dev;
32static struct device *dsp_dev;
33
34struct device *omap2_get_mpuss_device(void)
35{
36 WARN_ON_ONCE(!mpu_dev);
37 return mpu_dev;
38}
39
40struct device *omap2_get_iva_device(void)
41{
42 WARN_ON_ONCE(!iva_dev);
43 return iva_dev;
44}
45
46struct device *omap2_get_l3_device(void)
47{
48 WARN_ON_ONCE(!l3_dev);
49 return l3_dev;
50}
51
52struct device *omap4_get_dsp_device(void)
53{
54 WARN_ON_ONCE(!dsp_dev);
55 return dsp_dev;
56}
57EXPORT_SYMBOL(omap4_get_dsp_device);
58
59/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
60static int _init_omap_device(char *name, struct device **new_dev)
61{ 30{
62 struct omap_hwmod *oh; 31 struct omap_hwmod *oh;
63 struct platform_device *pdev; 32 struct platform_device *pdev;
@@ -72,8 +41,6 @@ static int _init_omap_device(char *name, struct device **new_dev)
72 __func__, name)) 41 __func__, name))
73 return -ENODEV; 42 return -ENODEV;
74 43
75 *new_dev = &pdev->dev;
76
77 return 0; 44 return 0;
78} 45}
79 46
@@ -82,16 +49,16 @@ static int _init_omap_device(char *name, struct device **new_dev)
82 */ 49 */
83static void omap2_init_processor_devices(void) 50static void omap2_init_processor_devices(void)
84{ 51{
85 _init_omap_device("mpu", &mpu_dev); 52 _init_omap_device("mpu");
86 if (omap3_has_iva()) 53 if (omap3_has_iva())
87 _init_omap_device("iva", &iva_dev); 54 _init_omap_device("iva");
88 55
89 if (cpu_is_omap44xx()) { 56 if (cpu_is_omap44xx()) {
90 _init_omap_device("l3_main_1", &l3_dev); 57 _init_omap_device("l3_main_1");
91 _init_omap_device("dsp", &dsp_dev); 58 _init_omap_device("dsp");
92 _init_omap_device("iva", &iva_dev); 59 _init_omap_device("iva");
93 } else { 60 } else {
94 _init_omap_device("l3_main", &l3_dev); 61 _init_omap_device("l3_main");
95 } 62 }
96} 63}
97 64
@@ -169,18 +136,26 @@ err:
169 * in the opp entry 136 * in the opp entry
170 */ 137 */
171static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, 138static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
172 struct device *dev) 139 const char *oh_name)
173{ 140{
174 struct voltagedomain *voltdm; 141 struct voltagedomain *voltdm;
175 struct clk *clk; 142 struct clk *clk;
176 struct opp *opp; 143 struct opp *opp;
177 unsigned long freq, bootup_volt; 144 unsigned long freq, bootup_volt;
145 struct device *dev;
178 146
179 if (!vdd_name || !clk_name || !dev) { 147 if (!vdd_name || !clk_name || !oh_name) {
180 pr_err("%s: invalid parameters\n", __func__); 148 pr_err("%s: invalid parameters\n", __func__);
181 goto exit; 149 goto exit;
182 } 150 }
183 151
152 dev = omap_device_get_by_hwmod_name(oh_name);
153 if (IS_ERR(dev)) {
154 pr_err("%s: Unable to get dev pointer for hwmod %s\n",
155 __func__, oh_name);
156 goto exit;
157 }
158
184 voltdm = voltdm_lookup(vdd_name); 159 voltdm = voltdm_lookup(vdd_name);
185 if (IS_ERR(voltdm)) { 160 if (IS_ERR(voltdm)) {
186 pr_err("%s: unable to get vdd pointer for vdd_%s\n", 161 pr_err("%s: unable to get vdd pointer for vdd_%s\n",
@@ -224,8 +199,8 @@ static void __init omap3_init_voltages(void)
224 if (!cpu_is_omap34xx()) 199 if (!cpu_is_omap34xx())
225 return; 200 return;
226 201
227 omap2_set_init_voltage("mpu_iva", "dpll1_ck", mpu_dev); 202 omap2_set_init_voltage("mpu_iva", "dpll1_ck", "mpu");
228 omap2_set_init_voltage("core", "l3_ick", l3_dev); 203 omap2_set_init_voltage("core", "l3_ick", "l3_main");
229} 204}
230 205
231static void __init omap4_init_voltages(void) 206static void __init omap4_init_voltages(void)
@@ -233,14 +208,15 @@ static void __init omap4_init_voltages(void)
233 if (!cpu_is_omap44xx()) 208 if (!cpu_is_omap44xx())
234 return; 209 return;
235 210
236 omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev); 211 omap2_set_init_voltage("mpu", "dpll_mpu_ck", "mpu");
237 omap2_set_init_voltage("core", "l3_div_ck", l3_dev); 212 omap2_set_init_voltage("core", "l3_div_ck", "l3_main_1");
238 omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", iva_dev); 213 omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva");
239} 214}
240 215
241static int __init omap2_common_pm_init(void) 216static int __init omap2_common_pm_init(void)
242{ 217{
243 omap2_init_processor_devices(); 218 if (!of_have_populated_dt())
219 omap2_init_processor_devices();
244 omap_pm_if_init(); 220 omap_pm_if_init();
245 221
246 return 0; 222 return 0;
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 3d1c1d393f8f..9992dbfdfdb3 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -107,28 +107,6 @@ struct omap_uart_state {
107static LIST_HEAD(uart_list); 107static LIST_HEAD(uart_list);
108static u8 num_uarts; 108static u8 num_uarts;
109 109
110static int uart_idle_hwmod(struct omap_device *od)
111{
112 omap_hwmod_idle(od->hwmods[0]);
113
114 return 0;
115}
116
117static int uart_enable_hwmod(struct omap_device *od)
118{
119 omap_hwmod_enable(od->hwmods[0]);
120
121 return 0;
122}
123
124static struct omap_device_pm_latency omap_uart_latency[] = {
125 {
126 .deactivate_func = uart_idle_hwmod,
127 .activate_func = uart_enable_hwmod,
128 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
129 },
130};
131
132static inline unsigned int __serial_read_reg(struct uart_port *up, 110static inline unsigned int __serial_read_reg(struct uart_port *up,
133 int offset) 111 int offset)
134{ 112{
@@ -800,8 +778,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
800 return; 778 return;
801 779
802 pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size, 780 pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size,
803 omap_uart_latency, 781 NULL, 0, false);
804 ARRAY_SIZE(omap_uart_latency), false);
805 WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n", 782 WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n",
806 name, oh->name); 783 name, oh->name);
807 784
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index eba9f9a8ab65..9f43fcc05d3e 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -31,14 +31,6 @@
31 31
32static bool sr_enable_on_init; 32static bool sr_enable_on_init;
33 33
34static struct omap_device_pm_latency omap_sr_latency[] = {
35 {
36 .deactivate_func = omap_device_idle_hwmods,
37 .activate_func = omap_device_enable_hwmods,
38 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST
39 },
40};
41
42/* Read EFUSE values from control registers for OMAP3430 */ 34/* Read EFUSE values from control registers for OMAP3430 */
43static void __init sr_set_nvalues(struct omap_volt_data *volt_data, 35static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
44 struct omap_sr_data *sr_data) 36 struct omap_sr_data *sr_data)
@@ -121,8 +113,7 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
121 sr_data->enable_on_init = sr_enable_on_init; 113 sr_data->enable_on_init = sr_enable_on_init;
122 114
123 pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), 115 pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
124 omap_sr_latency, 116 NULL, 0, 0);
125 ARRAY_SIZE(omap_sr_latency), 0);
126 if (IS_ERR(pdev)) 117 if (IS_ERR(pdev))
127 pr_warning("%s: Could not build omap_device for %s: %s.\n\n", 118 pr_warning("%s: Could not build omap_device for %s: %s.\n\n",
128 __func__, name, oh->name); 119 __func__, name, oh->name);
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index d86af3cda8c7..47fb5d607630 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -60,14 +60,6 @@ static struct musb_hdrc_platform_data musb_plat = {
60 60
61static u64 musb_dmamask = DMA_BIT_MASK(32); 61static u64 musb_dmamask = DMA_BIT_MASK(32);
62 62
63static struct omap_device_pm_latency omap_musb_latency[] = {
64 {
65 .deactivate_func = omap_device_idle_hwmods,
66 .activate_func = omap_device_enable_hwmods,
67 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
68 },
69};
70
71static void usb_musb_mux_init(struct omap_musb_board_data *board_data) 63static void usb_musb_mux_init(struct omap_musb_board_data *board_data)
72{ 64{
73 switch (board_data->interface_type) { 65 switch (board_data->interface_type) {
@@ -150,8 +142,7 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
150 return; 142 return;
151 143
152 pdev = omap_device_build(name, bus_id, oh, &musb_plat, 144 pdev = omap_device_build(name, bus_id, oh, &musb_plat,
153 sizeof(musb_plat), omap_musb_latency, 145 sizeof(musb_plat), NULL, 0, false);
154 ARRAY_SIZE(omap_musb_latency), false);
155 if (IS_ERR(pdev)) { 146 if (IS_ERR(pdev)) {
156 pr_err("Could not build omap_device for %s %s\n", 147 pr_err("Could not build omap_device for %s %s\n",
157 name, oh_name); 148 name, oh_name);
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 0c7caf2458b4..c20beb8ed38b 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -123,14 +123,6 @@ static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
123 omap_pm_set_max_mpu_wakeup_lat(dev, t); 123 omap_pm_set_max_mpu_wakeup_lat(dev, t);
124} 124}
125 125
126static struct omap_device_pm_latency omap_i2c_latency[] = {
127 [0] = {
128 .deactivate_func = omap_device_idle_hwmods,
129 .activate_func = omap_device_enable_hwmods,
130 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
131 },
132};
133
134static inline int omap2_i2c_add_bus(int bus_id) 126static inline int omap2_i2c_add_bus(int bus_id)
135{ 127{
136 int l; 128 int l;
@@ -162,7 +154,7 @@ static inline int omap2_i2c_add_bus(int bus_id)
162 pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; 154 pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
163 pdev = omap_device_build(name, bus_id, oh, pdata, 155 pdev = omap_device_build(name, bus_id, oh, pdata,
164 sizeof(struct omap_i2c_bus_platform_data), 156 sizeof(struct omap_i2c_bus_platform_data),
165 omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0); 157 NULL, 0, 0);
166 WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); 158 WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name);
167 159
168 return PTR_ERR(pdev); 160 return PTR_ERR(pdev);
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index d4d9b96f961e..12c5b0c345bf 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -101,6 +101,7 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
101 int pm_lats_cnt, int is_early_device); 101 int pm_lats_cnt, int is_early_device);
102 102
103void __iomem *omap_device_get_rt_va(struct omap_device *od); 103void __iomem *omap_device_get_rt_va(struct omap_device *od);
104struct device *omap_device_get_by_hwmod_name(const char *oh_name);
104 105
105/* OMAP PM interface */ 106/* OMAP PM interface */
106int omap_device_align_pm_lat(struct platform_device *pdev, 107int omap_device_align_pm_lat(struct platform_device *pdev,
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 26aee5cc1fc1..cd90bedd9306 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -85,6 +85,8 @@
85#include <linux/clk.h> 85#include <linux/clk.h>
86#include <linux/clkdev.h> 86#include <linux/clkdev.h>
87#include <linux/pm_runtime.h> 87#include <linux/pm_runtime.h>
88#include <linux/of.h>
89#include <linux/notifier.h>
88 90
89#include <plat/omap_device.h> 91#include <plat/omap_device.h>
90#include <plat/omap_hwmod.h> 92#include <plat/omap_hwmod.h>
@@ -96,6 +98,20 @@
96 98
97static int omap_device_register(struct platform_device *pdev); 99static int omap_device_register(struct platform_device *pdev);
98static int omap_early_device_register(struct platform_device *pdev); 100static int omap_early_device_register(struct platform_device *pdev);
101static struct omap_device *omap_device_alloc(struct platform_device *pdev,
102 struct omap_hwmod **ohs, int oh_cnt,
103 struct omap_device_pm_latency *pm_lats,
104 int pm_lats_cnt);
105static void omap_device_delete(struct omap_device *od);
106
107
108static struct omap_device_pm_latency omap_default_latency[] = {
109 {
110 .deactivate_func = omap_device_idle_hwmods,
111 .activate_func = omap_device_enable_hwmods,
112 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
113 }
114};
99 115
100/* Private functions */ 116/* Private functions */
101 117
@@ -303,6 +319,96 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od,
303} 319}
304 320
305 321
322static struct dev_pm_domain omap_device_pm_domain;
323
324/**
325 * omap_device_build_from_dt - build an omap_device with multiple hwmods
326 * @pdev_name: name of the platform_device driver to use
327 * @pdev_id: this platform_device's connection ID
328 * @oh: ptr to the single omap_hwmod that backs this omap_device
329 * @pdata: platform_data ptr to associate with the platform_device
330 * @pdata_len: amount of memory pointed to by @pdata
331 * @pm_lats: pointer to a omap_device_pm_latency array for this device
332 * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
333 * @is_early_device: should the device be registered as an early device or not
334 *
335 * Function for building an omap_device already registered from device-tree
336 *
337 * Returns 0 or PTR_ERR() on error.
338 */
339static int omap_device_build_from_dt(struct platform_device *pdev)
340{
341 struct omap_hwmod **hwmods;
342 struct omap_device *od;
343 struct omap_hwmod *oh;
344 struct device_node *node = pdev->dev.of_node;
345 const char *oh_name;
346 int oh_cnt, i, ret = 0;
347
348 oh_cnt = of_property_count_strings(node, "ti,hwmods");
349 if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) {
350 dev_warn(&pdev->dev, "No 'hwmods' to build omap_device\n");
351 return -ENODEV;
352 }
353
354 hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
355 if (!hwmods) {
356 ret = -ENOMEM;
357 goto odbfd_exit;
358 }
359
360 for (i = 0; i < oh_cnt; i++) {
361 of_property_read_string_index(node, "ti,hwmods", i, &oh_name);
362 oh = omap_hwmod_lookup(oh_name);
363 if (!oh) {
364 dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n",
365 oh_name);
366 ret = -EINVAL;
367 goto odbfd_exit1;
368 }
369 hwmods[i] = oh;
370 }
371
372 od = omap_device_alloc(pdev, hwmods, oh_cnt, NULL, 0);
373 if (!od) {
374 dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n",
375 oh_name);
376 ret = PTR_ERR(od);
377 goto odbfd_exit1;
378 }
379
380 if (of_get_property(node, "ti,no_idle_on_suspend", NULL))
381 omap_device_disable_idle_on_suspend(pdev);
382
383 pdev->dev.pm_domain = &omap_device_pm_domain;
384
385odbfd_exit1:
386 kfree(hwmods);
387odbfd_exit:
388 return ret;
389}
390
391static int _omap_device_notifier_call(struct notifier_block *nb,
392 unsigned long event, void *dev)
393{
394 struct platform_device *pdev = to_platform_device(dev);
395
396 switch (event) {
397 case BUS_NOTIFY_ADD_DEVICE:
398 if (pdev->dev.of_node)
399 omap_device_build_from_dt(pdev);
400 break;
401
402 case BUS_NOTIFY_DEL_DEVICE:
403 if (pdev->archdata.od)
404 omap_device_delete(pdev->archdata.od);
405 break;
406 }
407
408 return NOTIFY_DONE;
409}
410
411
306/* Public functions for use by core code */ 412/* Public functions for use by core code */
307 413
308/** 414/**
@@ -389,6 +495,113 @@ static int omap_device_fill_resources(struct omap_device *od,
389} 495}
390 496
391/** 497/**
498 * omap_device_alloc - allocate an omap_device
499 * @pdev: platform_device that will be included in this omap_device
500 * @oh: ptr to the single omap_hwmod that backs this omap_device
501 * @pdata: platform_data ptr to associate with the platform_device
502 * @pdata_len: amount of memory pointed to by @pdata
503 * @pm_lats: pointer to a omap_device_pm_latency array for this device
504 * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
505 *
506 * Convenience function for allocating an omap_device structure and filling
507 * hwmods, resources and pm_latency attributes.
508 *
509 * Returns an struct omap_device pointer or ERR_PTR() on error;
510 */
511static struct omap_device *omap_device_alloc(struct platform_device *pdev,
512 struct omap_hwmod **ohs, int oh_cnt,
513 struct omap_device_pm_latency *pm_lats,
514 int pm_lats_cnt)
515{
516 int ret = -ENOMEM;
517 struct omap_device *od;
518 struct resource *res = NULL;
519 int i, res_count;
520 struct omap_hwmod **hwmods;
521
522 od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
523 if (!od) {
524 ret = -ENOMEM;
525 goto oda_exit1;
526 }
527 od->hwmods_cnt = oh_cnt;
528
529 hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
530 if (!hwmods)
531 goto oda_exit2;
532
533 od->hwmods = hwmods;
534 od->pdev = pdev;
535
536 /*
537 * HACK: Ideally the resources from DT should match, and hwmod
538 * should just add the missing ones. Since the name is not
539 * properly populated by DT, stick to hwmod resources only.
540 */
541 if (pdev->num_resources && pdev->resource)
542 dev_warn(&pdev->dev, "%s(): resources already allocated %d\n",
543 __func__, pdev->num_resources);
544
545 res_count = omap_device_count_resources(od);
546 if (res_count > 0) {
547 dev_dbg(&pdev->dev, "%s(): resources allocated from hwmod %d\n",
548 __func__, res_count);
549 res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
550 if (!res)
551 goto oda_exit3;
552
553 omap_device_fill_resources(od, res);
554
555 ret = platform_device_add_resources(pdev, res, res_count);
556 kfree(res);
557
558 if (ret)
559 goto oda_exit3;
560 }
561
562 if (!pm_lats) {
563 pm_lats = omap_default_latency;
564 pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
565 }
566
567 od->pm_lats_cnt = pm_lats_cnt;
568 od->pm_lats = kmemdup(pm_lats,
569 sizeof(struct omap_device_pm_latency) * pm_lats_cnt,
570 GFP_KERNEL);
571 if (!od->pm_lats)
572 goto oda_exit3;
573
574 pdev->archdata.od = od;
575
576 for (i = 0; i < oh_cnt; i++) {
577 hwmods[i]->od = od;
578 _add_hwmod_clocks_clkdev(od, hwmods[i]);
579 }
580
581 return od;
582
583oda_exit3:
584 kfree(hwmods);
585oda_exit2:
586 kfree(od);
587oda_exit1:
588 dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret);
589
590 return ERR_PTR(ret);
591}
592
593static void omap_device_delete(struct omap_device *od)
594{
595 if (!od)
596 return;
597
598 od->pdev->archdata.od = NULL;
599 kfree(od->pm_lats);
600 kfree(od->hwmods);
601 kfree(od);
602}
603
604/**
392 * omap_device_build - build and register an omap_device with one omap_hwmod 605 * omap_device_build - build and register an omap_device with one omap_hwmod
393 * @pdev_name: name of the platform_device driver to use 606 * @pdev_name: name of the platform_device driver to use
394 * @pdev_id: this platform_device's connection ID 607 * @pdev_id: this platform_device's connection ID
@@ -447,9 +660,6 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
447 int ret = -ENOMEM; 660 int ret = -ENOMEM;
448 struct platform_device *pdev; 661 struct platform_device *pdev;
449 struct omap_device *od; 662 struct omap_device *od;
450 struct resource *res = NULL;
451 int i, res_count;
452 struct omap_hwmod **hwmods;
453 663
454 if (!ohs || oh_cnt == 0 || !pdev_name) 664 if (!ohs || oh_cnt == 0 || !pdev_name)
455 return ERR_PTR(-EINVAL); 665 return ERR_PTR(-EINVAL);
@@ -463,67 +673,31 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
463 goto odbs_exit; 673 goto odbs_exit;
464 } 674 }
465 675
466 pr_debug("omap_device: %s: building with %d hwmods\n", pdev_name, 676 /* Set the dev_name early to allow dev_xxx in omap_device_alloc */
467 oh_cnt); 677 if (pdev->id != -1)
678 dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
679 else
680 dev_set_name(&pdev->dev, "%s", pdev->name);
468 681
469 od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); 682 od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt);
470 if (!od) { 683 if (!od)
471 ret = -ENOMEM;
472 goto odbs_exit1; 684 goto odbs_exit1;
473 }
474 od->hwmods_cnt = oh_cnt;
475
476 hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt,
477 GFP_KERNEL);
478 if (!hwmods)
479 goto odbs_exit2;
480
481 memcpy(hwmods, ohs, sizeof(struct omap_hwmod *) * oh_cnt);
482 od->hwmods = hwmods;
483 od->pdev = pdev;
484
485 res_count = omap_device_count_resources(od);
486 if (res_count > 0) {
487 res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
488 if (!res)
489 goto odbs_exit3;
490
491 omap_device_fill_resources(od, res);
492
493 ret = platform_device_add_resources(pdev, res, res_count);
494 kfree(res);
495
496 if (ret)
497 goto odbs_exit3;
498 }
499 685
500 ret = platform_device_add_data(pdev, pdata, pdata_len); 686 ret = platform_device_add_data(pdev, pdata, pdata_len);
501 if (ret) 687 if (ret)
502 goto odbs_exit3; 688 goto odbs_exit2;
503
504 pdev->archdata.od = od;
505 689
506 if (is_early_device) 690 if (is_early_device)
507 ret = omap_early_device_register(pdev); 691 ret = omap_early_device_register(pdev);
508 else 692 else
509 ret = omap_device_register(pdev); 693 ret = omap_device_register(pdev);
510 if (ret) 694 if (ret)
511 goto odbs_exit3; 695 goto odbs_exit2;
512
513 od->pm_lats = pm_lats;
514 od->pm_lats_cnt = pm_lats_cnt;
515
516 for (i = 0; i < oh_cnt; i++) {
517 hwmods[i]->od = od;
518 _add_hwmod_clocks_clkdev(od, hwmods[i]);
519 }
520 696
521 return pdev; 697 return pdev;
522 698
523odbs_exit3:
524 kfree(hwmods);
525odbs_exit2: 699odbs_exit2:
526 kfree(od); 700 omap_device_delete(od);
527odbs_exit1: 701odbs_exit1:
528 platform_device_put(pdev); 702 platform_device_put(pdev);
529odbs_exit: 703odbs_exit:
@@ -844,6 +1018,42 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od)
844 return omap_hwmod_get_mpu_rt_va(od->hwmods[0]); 1018 return omap_hwmod_get_mpu_rt_va(od->hwmods[0]);
845} 1019}
846 1020
1021/**
1022 * omap_device_get_by_hwmod_name() - convert a hwmod name to
1023 * device pointer.
1024 * @oh_name: name of the hwmod device
1025 *
1026 * Returns back a struct device * pointer associated with a hwmod
1027 * device represented by a hwmod_name
1028 */
1029struct device *omap_device_get_by_hwmod_name(const char *oh_name)
1030{
1031 struct omap_hwmod *oh;
1032
1033 if (!oh_name) {
1034 WARN(1, "%s: no hwmod name!\n", __func__);
1035 return ERR_PTR(-EINVAL);
1036 }
1037
1038 oh = omap_hwmod_lookup(oh_name);
1039 if (IS_ERR_OR_NULL(oh)) {
1040 WARN(1, "%s: no hwmod for %s\n", __func__,
1041 oh_name);
1042 return ERR_PTR(oh ? PTR_ERR(oh) : -ENODEV);
1043 }
1044 if (IS_ERR_OR_NULL(oh->od)) {
1045 WARN(1, "%s: no omap_device for %s\n", __func__,
1046 oh_name);
1047 return ERR_PTR(oh->od ? PTR_ERR(oh->od) : -ENODEV);
1048 }
1049
1050 if (IS_ERR_OR_NULL(oh->od->pdev))
1051 return ERR_PTR(oh->od->pdev ? PTR_ERR(oh->od->pdev) : -ENODEV);
1052
1053 return &oh->od->pdev->dev;
1054}
1055EXPORT_SYMBOL(omap_device_get_by_hwmod_name);
1056
847/* 1057/*
848 * Public functions intended for use in omap_device_pm_latency 1058 * Public functions intended for use in omap_device_pm_latency
849 * .activate_func and .deactivate_func function pointers 1059 * .activate_func and .deactivate_func function pointers
@@ -924,8 +1134,13 @@ struct device omap_device_parent = {
924 .parent = &platform_bus, 1134 .parent = &platform_bus,
925}; 1135};
926 1136
1137static struct notifier_block platform_nb = {
1138 .notifier_call = _omap_device_notifier_call,
1139};
1140
927static int __init omap_device_init(void) 1141static int __init omap_device_init(void)
928{ 1142{
1143 bus_register_notifier(&platform_bus_type, &platform_nb);
929 return device_register(&omap_device_parent); 1144 return device_register(&omap_device_parent);
930} 1145}
931core_initcall(omap_device_init); 1146core_initcall(omap_device_init);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 3ff22e32b602..f7239b33d762 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -662,6 +662,90 @@ int of_property_read_string(struct device_node *np, const char *propname,
662EXPORT_SYMBOL_GPL(of_property_read_string); 662EXPORT_SYMBOL_GPL(of_property_read_string);
663 663
664/** 664/**
665 * of_property_read_string_index - Find and read a string from a multiple
666 * strings property.
667 * @np: device node from which the property value is to be read.
668 * @propname: name of the property to be searched.
669 * @index: index of the string in the list of strings
670 * @out_string: pointer to null terminated return string, modified only if
671 * return value is 0.
672 *
673 * Search for a property in a device tree node and retrieve a null
674 * terminated string value (pointer to data, not a copy) in the list of strings
675 * contained in that property.
676 * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
677 * property does not have a value, and -EILSEQ if the string is not
678 * null-terminated within the length of the property data.
679 *
680 * The out_string pointer is modified only if a valid string can be decoded.
681 */
682int of_property_read_string_index(struct device_node *np, const char *propname,
683 int index, const char **output)
684{
685 struct property *prop = of_find_property(np, propname, NULL);
686 int i = 0;
687 size_t l = 0, total = 0;
688 const char *p;
689
690 if (!prop)
691 return -EINVAL;
692 if (!prop->value)
693 return -ENODATA;
694 if (strnlen(prop->value, prop->length) >= prop->length)
695 return -EILSEQ;
696
697 p = prop->value;
698
699 for (i = 0; total < prop->length; total += l, p += l) {
700 l = strlen(p) + 1;
701 if ((*p != 0) && (i++ == index)) {
702 *output = p;
703 return 0;
704 }
705 }
706 return -ENODATA;
707}
708EXPORT_SYMBOL_GPL(of_property_read_string_index);
709
710
711/**
712 * of_property_count_strings - Find and return the number of strings from a
713 * multiple strings property.
714 * @np: device node from which the property value is to be read.
715 * @propname: name of the property to be searched.
716 *
717 * Search for a property in a device tree node and retrieve the number of null
718 * terminated string contain in it. Returns the number of strings on
719 * success, -EINVAL if the property does not exist, -ENODATA if property
720 * does not have a value, and -EILSEQ if the string is not null-terminated
721 * within the length of the property data.
722 */
723int of_property_count_strings(struct device_node *np, const char *propname)
724{
725 struct property *prop = of_find_property(np, propname, NULL);
726 int i = 0;
727 size_t l = 0, total = 0;
728 const char *p;
729
730 if (!prop)
731 return -EINVAL;
732 if (!prop->value)
733 return -ENODATA;
734 if (strnlen(prop->value, prop->length) >= prop->length)
735 return -EILSEQ;
736
737 p = prop->value;
738
739 for (i = 0; total < prop->length; total += l, p += l) {
740 l = strlen(p) + 1;
741 if (*p != 0)
742 i++;
743 }
744 return i;
745}
746EXPORT_SYMBOL_GPL(of_property_count_strings);
747
748/**
665 * of_parse_phandle - Resolve a phandle property to a device_node pointer 749 * of_parse_phandle - Resolve a phandle property to a device_node pointer
666 * @np: Pointer to device node holding phandle property 750 * @np: Pointer to device node holding phandle property
667 * @phandle_name: Name of property holding a phandle value 751 * @phandle_name: Name of property holding a phandle value
diff --git a/include/linux/of.h b/include/linux/of.h
index 9180dc5cb00b..5dfe2d5a8b5d 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -203,6 +203,11 @@ extern int of_property_read_u32_array(const struct device_node *np,
203extern int of_property_read_string(struct device_node *np, 203extern int of_property_read_string(struct device_node *np,
204 const char *propname, 204 const char *propname,
205 const char **out_string); 205 const char **out_string);
206extern int of_property_read_string_index(struct device_node *np,
207 const char *propname,
208 int index, const char **output);
209extern int of_property_count_strings(struct device_node *np,
210 const char *propname);
206extern int of_device_is_compatible(const struct device_node *device, 211extern int of_device_is_compatible(const struct device_node *device,
207 const char *); 212 const char *);
208extern int of_device_is_available(const struct device_node *device); 213extern int of_device_is_available(const struct device_node *device);
@@ -256,6 +261,19 @@ static inline int of_property_read_string(struct device_node *np,
256 return -ENOSYS; 261 return -ENOSYS;
257} 262}
258 263
264static inline int of_property_read_string_index(struct device_node *np,
265 const char *propname, int index,
266 const char **out_string)
267{
268 return -ENOSYS;
269}
270
271static inline int of_property_count_strings(struct device_node *np,
272 const char *propname)
273{
274 return -ENOSYS;
275}
276
259static inline const void *of_get_property(const struct device_node *node, 277static inline const void *of_get_property(const struct device_node *node,
260 const char *name, 278 const char *name,
261 int *lenp) 279 int *lenp)