aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-08-04 01:46:24 -0400
committerTony Lindgren <tony@atomide.com>2010-08-04 01:46:24 -0400
commit331d919af416b9b92428947ef8c535a3e24c6b31 (patch)
tree1f58dfe4ea6ed130f7b970f07cd7589864e9cbad
parent047b51fb208c716294b4682c904df8a3ad8b6a69 (diff)
parentfb8ce14c7e16bd218decb3e1655c5d4ff08042f2 (diff)
Merge branch 'for_2.6.36' of git://git.pwsan.com/linux-2.6 into omap-for-linus
-rw-r--r--arch/arm/mach-omap1/Kconfig6
-rw-r--r--arch/arm/mach-omap1/clock.c22
-rw-r--r--arch/arm/mach-omap1/clock.h2
-rw-r--r--arch/arm/mach-omap1/clock_data.c129
-rw-r--r--arch/arm/mach-omap2/Makefile4
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/cm.c6
-rw-r--r--arch/arm/mach-omap2/io.c11
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c106
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c79
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c81
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c92
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.c3
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.h1
-rw-r--r--arch/arm/mach-omap2/pm.c84
-rw-r--r--arch/arm/plat-omap/Makefile1
-rw-r--r--arch/arm/plat-omap/i2c.c12
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h130
-rw-r--r--arch/arm/plat-omap/include/plat/common.h4
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h130
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h2
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h14
-rw-r--r--arch/arm/plat-omap/omap-pm-noop.c61
-rw-r--r--arch/arm/plat-omap/omap_device.c33
24 files changed, 790 insertions, 225 deletions
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index c911cdbf886f..3b02d3b944af 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -228,6 +228,12 @@ config OMAP_ARM_120MHZ
228 help 228 help
229 Enable 120MHz clock for OMAP CPU. If unsure, say N. 229 Enable 120MHz clock for OMAP CPU. If unsure, say N.
230 230
231config OMAP_ARM_96MHZ
232 bool "OMAP ARM 96 MHz CPU"
233 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
234 help
235 Enable 96MHz clock for OMAP CPU. If unsure, say N.
236
231config OMAP_ARM_60MHZ 237config OMAP_ARM_60MHZ
232 bool "OMAP ARM 60 MHz CPU" 238 bool "OMAP ARM 60 MHz CPU"
233 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) 239 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 6bbb1b8b8294..b8c7fb9d7921 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -11,7 +11,6 @@
11 * 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
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14#include <linux/module.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/list.h> 15#include <linux/list.h>
17#include <linux/errno.h> 16#include <linux/errno.h>
@@ -34,9 +33,9 @@
34__u32 arm_idlect1_mask; 33__u32 arm_idlect1_mask;
35struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p; 34struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
36 35
37/*------------------------------------------------------------------------- 36/*
38 * Omap1 specific clock functions 37 * Omap1 specific clock functions
39 *-------------------------------------------------------------------------*/ 38 */
40 39
41unsigned long omap1_uart_recalc(struct clk *clk) 40unsigned long omap1_uart_recalc(struct clk *clk)
42{ 41{
@@ -523,7 +522,8 @@ const struct clkops clkops_dspck = {
523 .disable = omap1_clk_disable_dsp_domain, 522 .disable = omap1_clk_disable_dsp_domain,
524}; 523};
525 524
526static int omap1_clk_enable_uart_functional(struct clk *clk) 525/* XXX SYSC register handling does not belong in the clock framework */
526static int omap1_clk_enable_uart_functional_16xx(struct clk *clk)
527{ 527{
528 int ret; 528 int ret;
529 struct uart_clk *uclk; 529 struct uart_clk *uclk;
@@ -539,7 +539,8 @@ static int omap1_clk_enable_uart_functional(struct clk *clk)
539 return ret; 539 return ret;
540} 540}
541 541
542static void omap1_clk_disable_uart_functional(struct clk *clk) 542/* XXX SYSC register handling does not belong in the clock framework */
543static void omap1_clk_disable_uart_functional_16xx(struct clk *clk)
543{ 544{
544 struct uart_clk *uclk; 545 struct uart_clk *uclk;
545 546
@@ -550,9 +551,10 @@ static void omap1_clk_disable_uart_functional(struct clk *clk)
550 omap1_clk_disable_generic(clk); 551 omap1_clk_disable_generic(clk);
551} 552}
552 553
553const struct clkops clkops_uart = { 554/* XXX SYSC register handling does not belong in the clock framework */
554 .enable = omap1_clk_enable_uart_functional, 555const struct clkops clkops_uart_16xx = {
555 .disable = omap1_clk_disable_uart_functional, 556 .enable = omap1_clk_enable_uart_functional_16xx,
557 .disable = omap1_clk_disable_uart_functional_16xx,
556}; 558};
557 559
558long omap1_clk_round_rate(struct clk *clk, unsigned long rate) 560long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
@@ -572,9 +574,9 @@ int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
572 return ret; 574 return ret;
573} 575}
574 576
575/*------------------------------------------------------------------------- 577/*
576 * Omap1 clock reset and init functions 578 * Omap1 clock reset and init functions
577 *-------------------------------------------------------------------------*/ 579 */
578 580
579#ifdef CONFIG_OMAP_RESET_CLOCKS 581#ifdef CONFIG_OMAP_RESET_CLOCKS
580 582
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 75d0d7d90bff..eaf09efb91ca 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -107,7 +107,7 @@ extern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
107 107
108extern const struct clkops clkops_dspck; 108extern const struct clkops clkops_dspck;
109extern const struct clkops clkops_dummy; 109extern const struct clkops clkops_dummy;
110extern const struct clkops clkops_uart; 110extern const struct clkops clkops_uart_16xx;
111extern const struct clkops clkops_generic; 111extern const struct clkops clkops_generic;
112 112
113#endif 113#endif
diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c
index 9240bc1026a3..af54114b8f08 100644
--- a/arch/arm/mach-omap1/clock_data.c
+++ b/arch/arm/mach-omap1/clock_data.c
@@ -8,6 +8,10 @@
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 *
12 * To do:
13 * - Clocks that are only available on some chips should be marked with the
14 * chips that they are present on.
11 */ 15 */
12 16
13#include <linux/kernel.h> 17#include <linux/kernel.h>
@@ -23,9 +27,49 @@
23 27
24#include "clock.h" 28#include "clock.h"
25 29
26/*------------------------------------------------------------------------ 30/* Some ARM_IDLECT1 bit shifts - used in struct arm_idlect1_clk */
31#define IDL_CLKOUT_ARM_SHIFT 12
32#define IDLTIM_ARM_SHIFT 9
33#define IDLAPI_ARM_SHIFT 8
34#define IDLIF_ARM_SHIFT 6
35#define IDLLB_ARM_SHIFT 4 /* undocumented? */
36#define OMAP1510_IDLLCD_ARM_SHIFT 3 /* undocumented? */
37#define IDLPER_ARM_SHIFT 2
38#define IDLXORP_ARM_SHIFT 1
39#define IDLWDT_ARM_SHIFT 0
40
41/* Some MOD_CONF_CTRL_0 bit shifts - used in struct clk.enable_bit */
42#define CONF_MOD_UART3_CLK_MODE_R 31
43#define CONF_MOD_UART2_CLK_MODE_R 30
44#define CONF_MOD_UART1_CLK_MODE_R 29
45#define CONF_MOD_MMC_SD_CLK_REQ_R 23
46#define CONF_MOD_MCBSP3_AUXON 20
47
48/* Some MOD_CONF_CTRL_1 bit shifts - used in struct clk.enable_bit */
49#define CONF_MOD_SOSSI_CLK_EN_R 16
50
51/* Some OTG_SYSCON_2-specific bit fields */
52#define OTG_SYSCON_2_UHOST_EN_SHIFT 8
53
54/* Some SOFT_REQ_REG bit fields - used in struct clk.enable_bit */
55#define SOFT_MMC2_DPLL_REQ_SHIFT 13
56#define SOFT_MMC_DPLL_REQ_SHIFT 12
57#define SOFT_UART3_DPLL_REQ_SHIFT 11
58#define SOFT_UART2_DPLL_REQ_SHIFT 10
59#define SOFT_UART1_DPLL_REQ_SHIFT 9
60#define SOFT_USB_OTG_DPLL_REQ_SHIFT 8
61#define SOFT_CAM_DPLL_REQ_SHIFT 7
62#define SOFT_COM_MCKO_REQ_SHIFT 6
63#define SOFT_PERIPH_REQ_SHIFT 5 /* sys_ck gate for UART2 ? */
64#define USB_REQ_EN_SHIFT 4
65#define SOFT_USB_REQ_SHIFT 3 /* sys_ck gate for USB host? */
66#define SOFT_SDW_REQ_SHIFT 2 /* sys_ck gate for Bluetooth? */
67#define SOFT_COM_REQ_SHIFT 1 /* sys_ck gate for com proc? */
68#define SOFT_DPLL_REQ_SHIFT 0
69
70/*
27 * Omap1 clocks 71 * Omap1 clocks
28 *-------------------------------------------------------------------------*/ 72 */
29 73
30static struct clk ck_ref = { 74static struct clk ck_ref = {
31 .name = "ck_ref", 75 .name = "ck_ref",
@@ -54,7 +98,7 @@ static struct arm_idlect1_clk ck_dpll1out = {
54 .enable_bit = EN_CKOUT_ARM, 98 .enable_bit = EN_CKOUT_ARM,
55 .recalc = &followparent_recalc, 99 .recalc = &followparent_recalc,
56 }, 100 },
57 .idlect_shift = 12, 101 .idlect_shift = IDL_CLKOUT_ARM_SHIFT,
58}; 102};
59 103
60static struct clk sossi_ck = { 104static struct clk sossi_ck = {
@@ -63,7 +107,7 @@ static struct clk sossi_ck = {
63 .parent = &ck_dpll1out.clk, 107 .parent = &ck_dpll1out.clk,
64 .flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT, 108 .flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
65 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1), 109 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
66 .enable_bit = 16, 110 .enable_bit = CONF_MOD_SOSSI_CLK_EN_R,
67 .recalc = &omap1_sossi_recalc, 111 .recalc = &omap1_sossi_recalc,
68 .set_rate = &omap1_set_sossi_rate, 112 .set_rate = &omap1_set_sossi_rate,
69}; 113};
@@ -91,7 +135,7 @@ static struct arm_idlect1_clk armper_ck = {
91 .round_rate = omap1_clk_round_rate_ckctl_arm, 135 .round_rate = omap1_clk_round_rate_ckctl_arm,
92 .set_rate = omap1_clk_set_rate_ckctl_arm, 136 .set_rate = omap1_clk_set_rate_ckctl_arm,
93 }, 137 },
94 .idlect_shift = 2, 138 .idlect_shift = IDLPER_ARM_SHIFT,
95}; 139};
96 140
97/* 141/*
@@ -118,7 +162,7 @@ static struct arm_idlect1_clk armxor_ck = {
118 .enable_bit = EN_XORPCK, 162 .enable_bit = EN_XORPCK,
119 .recalc = &followparent_recalc, 163 .recalc = &followparent_recalc,
120 }, 164 },
121 .idlect_shift = 1, 165 .idlect_shift = IDLXORP_ARM_SHIFT,
122}; 166};
123 167
124static struct arm_idlect1_clk armtim_ck = { 168static struct arm_idlect1_clk armtim_ck = {
@@ -131,7 +175,7 @@ static struct arm_idlect1_clk armtim_ck = {
131 .enable_bit = EN_TIMCK, 175 .enable_bit = EN_TIMCK,
132 .recalc = &followparent_recalc, 176 .recalc = &followparent_recalc,
133 }, 177 },
134 .idlect_shift = 9, 178 .idlect_shift = IDLTIM_ARM_SHIFT,
135}; 179};
136 180
137static struct arm_idlect1_clk armwdt_ck = { 181static struct arm_idlect1_clk armwdt_ck = {
@@ -145,7 +189,7 @@ static struct arm_idlect1_clk armwdt_ck = {
145 .fixed_div = 14, 189 .fixed_div = 14,
146 .recalc = &omap_fixed_divisor_recalc, 190 .recalc = &omap_fixed_divisor_recalc,
147 }, 191 },
148 .idlect_shift = 0, 192 .idlect_shift = IDLWDT_ARM_SHIFT,
149}; 193};
150 194
151static struct clk arminth_ck16xx = { 195static struct clk arminth_ck16xx = {
@@ -212,7 +256,6 @@ static struct clk dsptim_ck = {
212 .recalc = &followparent_recalc, 256 .recalc = &followparent_recalc,
213}; 257};
214 258
215/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
216static struct arm_idlect1_clk tc_ck = { 259static struct arm_idlect1_clk tc_ck = {
217 .clk = { 260 .clk = {
218 .name = "tc_ck", 261 .name = "tc_ck",
@@ -224,7 +267,7 @@ static struct arm_idlect1_clk tc_ck = {
224 .round_rate = omap1_clk_round_rate_ckctl_arm, 267 .round_rate = omap1_clk_round_rate_ckctl_arm,
225 .set_rate = omap1_clk_set_rate_ckctl_arm, 268 .set_rate = omap1_clk_set_rate_ckctl_arm,
226 }, 269 },
227 .idlect_shift = 6, 270 .idlect_shift = IDLIF_ARM_SHIFT,
228}; 271};
229 272
230static struct clk arminth_ck1510 = { 273static struct clk arminth_ck1510 = {
@@ -304,7 +347,7 @@ static struct arm_idlect1_clk api_ck = {
304 .enable_bit = EN_APICK, 347 .enable_bit = EN_APICK,
305 .recalc = &followparent_recalc, 348 .recalc = &followparent_recalc,
306 }, 349 },
307 .idlect_shift = 8, 350 .idlect_shift = IDLAPI_ARM_SHIFT,
308}; 351};
309 352
310static struct arm_idlect1_clk lb_ck = { 353static struct arm_idlect1_clk lb_ck = {
@@ -317,7 +360,7 @@ static struct arm_idlect1_clk lb_ck = {
317 .enable_bit = EN_LBCK, 360 .enable_bit = EN_LBCK,
318 .recalc = &followparent_recalc, 361 .recalc = &followparent_recalc,
319 }, 362 },
320 .idlect_shift = 4, 363 .idlect_shift = IDLLB_ARM_SHIFT,
321}; 364};
322 365
323static struct clk rhea1_ck = { 366static struct clk rhea1_ck = {
@@ -359,9 +402,15 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
359 .round_rate = omap1_clk_round_rate_ckctl_arm, 402 .round_rate = omap1_clk_round_rate_ckctl_arm,
360 .set_rate = omap1_clk_set_rate_ckctl_arm, 403 .set_rate = omap1_clk_set_rate_ckctl_arm,
361 }, 404 },
362 .idlect_shift = 3, 405 .idlect_shift = OMAP1510_IDLLCD_ARM_SHIFT,
363}; 406};
364 407
408/*
409 * XXX The enable_bit here is misused - it simply switches between 12MHz
410 * and 48MHz. Reimplement with clksel.
411 *
412 * XXX does this need SYSC register handling?
413 */
365static struct clk uart1_1510 = { 414static struct clk uart1_1510 = {
366 .name = "uart1_ck", 415 .name = "uart1_ck",
367 .ops = &clkops_null, 416 .ops = &clkops_null,
@@ -370,25 +419,37 @@ static struct clk uart1_1510 = {
370 .rate = 12000000, 419 .rate = 12000000,
371 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 420 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
372 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), 421 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
373 .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ 422 .enable_bit = CONF_MOD_UART1_CLK_MODE_R,
374 .set_rate = &omap1_set_uart_rate, 423 .set_rate = &omap1_set_uart_rate,
375 .recalc = &omap1_uart_recalc, 424 .recalc = &omap1_uart_recalc,
376}; 425};
377 426
427/*
428 * XXX The enable_bit here is misused - it simply switches between 12MHz
429 * and 48MHz. Reimplement with clksel.
430 *
431 * XXX SYSC register handling does not belong in the clock framework
432 */
378static struct uart_clk uart1_16xx = { 433static struct uart_clk uart1_16xx = {
379 .clk = { 434 .clk = {
380 .name = "uart1_ck", 435 .name = "uart1_ck",
381 .ops = &clkops_uart, 436 .ops = &clkops_uart_16xx,
382 /* Direct from ULPD, no real parent */ 437 /* Direct from ULPD, no real parent */
383 .parent = &armper_ck.clk, 438 .parent = &armper_ck.clk,
384 .rate = 48000000, 439 .rate = 48000000,
385 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 440 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
386 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), 441 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
387 .enable_bit = 29, 442 .enable_bit = CONF_MOD_UART1_CLK_MODE_R,
388 }, 443 },
389 .sysc_addr = 0xfffb0054, 444 .sysc_addr = 0xfffb0054,
390}; 445};
391 446
447/*
448 * XXX The enable_bit here is misused - it simply switches between 12MHz
449 * and 48MHz. Reimplement with clksel.
450 *
451 * XXX does this need SYSC register handling?
452 */
392static struct clk uart2_ck = { 453static struct clk uart2_ck = {
393 .name = "uart2_ck", 454 .name = "uart2_ck",
394 .ops = &clkops_null, 455 .ops = &clkops_null,
@@ -397,11 +458,17 @@ static struct clk uart2_ck = {
397 .rate = 12000000, 458 .rate = 12000000,
398 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 459 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
399 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), 460 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
400 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ 461 .enable_bit = CONF_MOD_UART2_CLK_MODE_R,
401 .set_rate = &omap1_set_uart_rate, 462 .set_rate = &omap1_set_uart_rate,
402 .recalc = &omap1_uart_recalc, 463 .recalc = &omap1_uart_recalc,
403}; 464};
404 465
466/*
467 * XXX The enable_bit here is misused - it simply switches between 12MHz
468 * and 48MHz. Reimplement with clksel.
469 *
470 * XXX does this need SYSC register handling?
471 */
405static struct clk uart3_1510 = { 472static struct clk uart3_1510 = {
406 .name = "uart3_ck", 473 .name = "uart3_ck",
407 .ops = &clkops_null, 474 .ops = &clkops_null,
@@ -410,21 +477,27 @@ static struct clk uart3_1510 = {
410 .rate = 12000000, 477 .rate = 12000000,
411 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 478 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
412 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), 479 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
413 .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ 480 .enable_bit = CONF_MOD_UART3_CLK_MODE_R,
414 .set_rate = &omap1_set_uart_rate, 481 .set_rate = &omap1_set_uart_rate,
415 .recalc = &omap1_uart_recalc, 482 .recalc = &omap1_uart_recalc,
416}; 483};
417 484
485/*
486 * XXX The enable_bit here is misused - it simply switches between 12MHz
487 * and 48MHz. Reimplement with clksel.
488 *
489 * XXX SYSC register handling does not belong in the clock framework
490 */
418static struct uart_clk uart3_16xx = { 491static struct uart_clk uart3_16xx = {
419 .clk = { 492 .clk = {
420 .name = "uart3_ck", 493 .name = "uart3_ck",
421 .ops = &clkops_uart, 494 .ops = &clkops_uart_16xx,
422 /* Direct from ULPD, no real parent */ 495 /* Direct from ULPD, no real parent */
423 .parent = &armper_ck.clk, 496 .parent = &armper_ck.clk,
424 .rate = 48000000, 497 .rate = 48000000,
425 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 498 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
426 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), 499 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
427 .enable_bit = 31, 500 .enable_bit = CONF_MOD_UART3_CLK_MODE_R,
428 }, 501 },
429 .sysc_addr = 0xfffb9854, 502 .sysc_addr = 0xfffb9854,
430}; 503};
@@ -457,7 +530,7 @@ static struct clk usb_hhc_ck16xx = {
457 /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ 530 /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
458 .flags = ENABLE_REG_32BIT, 531 .flags = ENABLE_REG_32BIT,
459 .enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */ 532 .enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
460 .enable_bit = 8 /* UHOST_EN */, 533 .enable_bit = OTG_SYSCON_2_UHOST_EN_SHIFT
461}; 534};
462 535
463static struct clk usb_dc_ck = { 536static struct clk usb_dc_ck = {
@@ -466,7 +539,7 @@ static struct clk usb_dc_ck = {
466 /* Direct from ULPD, no parent */ 539 /* Direct from ULPD, no parent */
467 .rate = 48000000, 540 .rate = 48000000,
468 .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), 541 .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
469 .enable_bit = 4, 542 .enable_bit = USB_REQ_EN_SHIFT,
470}; 543};
471 544
472static struct clk usb_dc_ck7xx = { 545static struct clk usb_dc_ck7xx = {
@@ -475,7 +548,7 @@ static struct clk usb_dc_ck7xx = {
475 /* Direct from ULPD, no parent */ 548 /* Direct from ULPD, no parent */
476 .rate = 48000000, 549 .rate = 48000000,
477 .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), 550 .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
478 .enable_bit = 8, 551 .enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT,
479}; 552};
480 553
481static struct clk uart1_7xx = { 554static struct clk uart1_7xx = {
@@ -502,7 +575,7 @@ static struct clk mclk_1510 = {
502 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 575 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
503 .rate = 12000000, 576 .rate = 12000000,
504 .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), 577 .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
505 .enable_bit = 6, 578 .enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
506}; 579};
507 580
508static struct clk mclk_16xx = { 581static struct clk mclk_16xx = {
@@ -542,9 +615,13 @@ static struct clk mmc1_ck = {
542 .rate = 48000000, 615 .rate = 48000000,
543 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 616 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
544 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), 617 .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
545 .enable_bit = 23, 618 .enable_bit = CONF_MOD_MMC_SD_CLK_REQ_R,
546}; 619};
547 620
621/*
622 * XXX MOD_CONF_CTRL_0 bit 20 is defined in the 1510 TRM as
623 * CONF_MOD_MCBSP3_AUXON ??
624 */
548static struct clk mmc2_ck = { 625static struct clk mmc2_ck = {
549 .name = "mmc2_ck", 626 .name = "mmc2_ck",
550 .ops = &clkops_generic, 627 .ops = &clkops_generic,
@@ -564,7 +641,7 @@ static struct clk mmc3_ck = {
564 .rate = 48000000, 641 .rate = 48000000,
565 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 642 .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
566 .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), 643 .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
567 .enable_bit = 12, 644 .enable_bit = SOFT_MMC_DPLL_REQ_SHIFT,
568}; 645};
569 646
570static struct clk virtual_ck_mpu = { 647static struct clk virtual_ck_mpu = {
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index a5266fab6177..63b2d8859c3c 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o 6obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o
7 7
8omap-2-3-common = irq.o sdrc.o 8omap-2-3-common = irq.o sdrc.o
9hwmod-common = omap_hwmod.o \ 9hwmod-common = omap_hwmod.o \
@@ -15,7 +15,7 @@ clock-common = clock.o clock_common_data.o \
15 15
16obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common) 16obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
17obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(hwmod-common) 17obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
18obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) 18obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) $(hwmod-common)
19 19
20obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 20obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
21 21
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 41b155acfca7..c226798e9ac6 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -1408,7 +1408,7 @@ static struct clk ts_fck = {
1408 1408
1409static struct clk usbtll_fck = { 1409static struct clk usbtll_fck = {
1410 .name = "usbtll_fck", 1410 .name = "usbtll_fck",
1411 .ops = &clkops_omap2_dflt, 1411 .ops = &clkops_omap2_dflt_wait,
1412 .parent = &dpll5_m2_ck, 1412 .parent = &dpll5_m2_ck,
1413 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), 1413 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
1414 .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT, 1414 .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
diff --git a/arch/arm/mach-omap2/cm.c b/arch/arm/mach-omap2/cm.c
index 2d83565d2be2..721c3b66740a 100644
--- a/arch/arm/mach-omap2/cm.c
+++ b/arch/arm/mach-omap2/cm.c
@@ -50,15 +50,15 @@ int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
50 50
51 cm_idlest_reg = cm_idlest_offs[idlest_id - 1]; 51 cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
52 52
53 mask = 1 << idlest_shift;
54
53 if (cpu_is_omap24xx()) 55 if (cpu_is_omap24xx())
54 ena = idlest_shift; 56 ena = mask;
55 else if (cpu_is_omap34xx()) 57 else if (cpu_is_omap34xx())
56 ena = 0; 58 ena = 0;
57 else 59 else
58 BUG(); 60 BUG();
59 61
60 mask = 1 << idlest_shift;
61
62 /* XXX should be OMAP2 CM */ 62 /* XXX should be OMAP2 CM */
63 omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena), 63 omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
64 MAX_MODULE_READY_TIME, i); 64 MAX_MODULE_READY_TIME, i);
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index b12d715dee5b..210de9d292fb 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -44,6 +44,7 @@
44 44
45#include <plat/clockdomain.h> 45#include <plat/clockdomain.h>
46#include "clockdomains.h" 46#include "clockdomains.h"
47
47#include <plat/omap_hwmod.h> 48#include <plat/omap_hwmod.h>
48 49
49/* 50/*
@@ -315,6 +316,8 @@ static int __init _omap2_init_reprogram_sdrc(void)
315void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, 316void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
316 struct omap_sdrc_params *sdrc_cs1) 317 struct omap_sdrc_params *sdrc_cs1)
317{ 318{
319 u8 skip_setup_idle = 0;
320
318 pwrdm_init(powerdomains_omap); 321 pwrdm_init(powerdomains_omap);
319 clkdm_init(clockdomains_omap, clkdm_autodeps); 322 clkdm_init(clockdomains_omap, clkdm_autodeps);
320 if (cpu_is_omap242x()) 323 if (cpu_is_omap242x())
@@ -338,9 +341,13 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
338 pr_err("Could not init clock framework - unknown CPU\n"); 341 pr_err("Could not init clock framework - unknown CPU\n");
339 342
340 omap_serial_early_init(); 343 omap_serial_early_init();
344
345#ifndef CONFIG_PM_RUNTIME
346 skip_setup_idle = 1;
347#endif
341 if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */ 348 if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */
342 omap_hwmod_late_init(); 349 omap_hwmod_late_init(skip_setup_idle);
343 omap_pm_if_init(); 350
344 if (cpu_is_omap24xx() || cpu_is_omap34xx()) { 351 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
345 omap2_sdrc_init(sdrc_cs0, sdrc_cs1); 352 omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
346 _omap2_init_reprogram_sdrc(); 353 _omap2_init_reprogram_sdrc();
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b7a4133267d8..cb911d7d1a3c 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * omap_hwmod implementation for OMAP2/3/4 2 * omap_hwmod implementation for OMAP2/3/4
3 * 3 *
4 * Copyright (C) 2009 Nokia Corporation 4 * Copyright (C) 2009-2010 Nokia Corporation
5 * 5 *
6 * Paul Walmsley, Benoît Cousson, Kevin Hilman 6 * Paul Walmsley, Benoît Cousson, Kevin Hilman
7 * 7 *
@@ -423,7 +423,7 @@ static int _init_main_clk(struct omap_hwmod *oh)
423} 423}
424 424
425/** 425/**
426 * _init_interface_clk - get a struct clk * for the the hwmod's interface clks 426 * _init_interface_clks - get a struct clk * for the the hwmod's interface clks
427 * @oh: struct omap_hwmod * 427 * @oh: struct omap_hwmod *
428 * 428 *
429 * Called from _init_clocks(). Populates the @oh OCP slave interface 429 * Called from _init_clocks(). Populates the @oh OCP slave interface
@@ -764,6 +764,7 @@ static struct omap_hwmod *_lookup(const char *name)
764/** 764/**
765 * _init_clocks - clk_get() all clocks associated with this hwmod 765 * _init_clocks - clk_get() all clocks associated with this hwmod
766 * @oh: struct omap_hwmod * 766 * @oh: struct omap_hwmod *
767 * @data: not used; pass NULL
767 * 768 *
768 * Called by omap_hwmod_late_init() (after omap2_clk_init()). 769 * Called by omap_hwmod_late_init() (after omap2_clk_init()).
769 * Resolves all clock names embedded in the hwmod. Must be called 770 * Resolves all clock names embedded in the hwmod. Must be called
@@ -771,7 +772,7 @@ static struct omap_hwmod *_lookup(const char *name)
771 * has not yet been registered or if the clocks have already been 772 * has not yet been registered or if the clocks have already been
772 * initialized, 0 on success, or a non-zero error on failure. 773 * initialized, 0 on success, or a non-zero error on failure.
773 */ 774 */
774static int _init_clocks(struct omap_hwmod *oh) 775static int _init_clocks(struct omap_hwmod *oh, void *data)
775{ 776{
776 int ret = 0; 777 int ret = 0;
777 778
@@ -886,7 +887,7 @@ static int _reset(struct omap_hwmod *oh)
886} 887}
887 888
888/** 889/**
889 * _enable - enable an omap_hwmod 890 * _omap_hwmod_enable - enable an omap_hwmod
890 * @oh: struct omap_hwmod * 891 * @oh: struct omap_hwmod *
891 * 892 *
892 * Enables an omap_hwmod @oh such that the MPU can access the hwmod's 893 * Enables an omap_hwmod @oh such that the MPU can access the hwmod's
@@ -894,7 +895,7 @@ static int _reset(struct omap_hwmod *oh)
894 * Returns -EINVAL if the hwmod is in the wrong state or passes along 895 * Returns -EINVAL if the hwmod is in the wrong state or passes along
895 * the return value of _wait_target_ready(). 896 * the return value of _wait_target_ready().
896 */ 897 */
897static int _enable(struct omap_hwmod *oh) 898int _omap_hwmod_enable(struct omap_hwmod *oh)
898{ 899{
899 int r; 900 int r;
900 901
@@ -939,7 +940,7 @@ static int _enable(struct omap_hwmod *oh)
939 * no further work. Returns -EINVAL if the hwmod is in the wrong 940 * no further work. Returns -EINVAL if the hwmod is in the wrong
940 * state or returns 0. 941 * state or returns 0.
941 */ 942 */
942static int _idle(struct omap_hwmod *oh) 943int _omap_hwmod_idle(struct omap_hwmod *oh)
943{ 944{
944 if (oh->_state != _HWMOD_STATE_ENABLED) { 945 if (oh->_state != _HWMOD_STATE_ENABLED) {
945 WARN(1, "omap_hwmod: %s: idle state can only be entered from " 946 WARN(1, "omap_hwmod: %s: idle state can only be entered from "
@@ -996,19 +997,25 @@ static int _shutdown(struct omap_hwmod *oh)
996/** 997/**
997 * _setup - do initial configuration of omap_hwmod 998 * _setup - do initial configuration of omap_hwmod
998 * @oh: struct omap_hwmod * 999 * @oh: struct omap_hwmod *
1000 * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1
999 * 1001 *
1000 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh 1002 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
1001 * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex 1003 * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex held.
1002 * held. Returns -EINVAL if the hwmod is in the wrong state or returns 1004 * @skip_setup_idle is intended to be used on a system that will not
1003 * 0. 1005 * call omap_hwmod_enable() to enable devices (e.g., a system without
1006 * PM runtime). Returns -EINVAL if the hwmod is in the wrong state or
1007 * returns 0.
1004 */ 1008 */
1005static int _setup(struct omap_hwmod *oh) 1009static int _setup(struct omap_hwmod *oh, void *data)
1006{ 1010{
1007 int i, r; 1011 int i, r;
1012 u8 skip_setup_idle;
1008 1013
1009 if (!oh) 1014 if (!oh || !data)
1010 return -EINVAL; 1015 return -EINVAL;
1011 1016
1017 skip_setup_idle = *(u8 *)data;
1018
1012 /* Set iclk autoidle mode */ 1019 /* Set iclk autoidle mode */
1013 if (oh->slaves_cnt > 0) { 1020 if (oh->slaves_cnt > 0) {
1014 for (i = 0; i < oh->slaves_cnt; i++) { 1021 for (i = 0; i < oh->slaves_cnt; i++) {
@@ -1029,7 +1036,7 @@ static int _setup(struct omap_hwmod *oh)
1029 1036
1030 oh->_state = _HWMOD_STATE_INITIALIZED; 1037 oh->_state = _HWMOD_STATE_INITIALIZED;
1031 1038
1032 r = _enable(oh); 1039 r = _omap_hwmod_enable(oh);
1033 if (r) { 1040 if (r) {
1034 pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n", 1041 pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
1035 oh->name, oh->_state); 1042 oh->name, oh->_state);
@@ -1041,7 +1048,7 @@ static int _setup(struct omap_hwmod *oh)
1041 * XXX Do the OCP_SYSCONFIG bits need to be 1048 * XXX Do the OCP_SYSCONFIG bits need to be
1042 * reprogrammed after a reset? If not, then this can 1049 * reprogrammed after a reset? If not, then this can
1043 * be removed. If they do, then probably the 1050 * be removed. If they do, then probably the
1044 * _enable() function should be split to avoid the 1051 * _omap_hwmod_enable() function should be split to avoid the
1045 * rewrite of the OCP_SYSCONFIG register. 1052 * rewrite of the OCP_SYSCONFIG register.
1046 */ 1053 */
1047 if (oh->class->sysc) { 1054 if (oh->class->sysc) {
@@ -1050,8 +1057,8 @@ static int _setup(struct omap_hwmod *oh)
1050 } 1057 }
1051 } 1058 }
1052 1059
1053 if (!(oh->flags & HWMOD_INIT_NO_IDLE)) 1060 if (!(oh->flags & HWMOD_INIT_NO_IDLE) && !skip_setup_idle)
1054 _idle(oh); 1061 _omap_hwmod_idle(oh);
1055 1062
1056 return 0; 1063 return 0;
1057} 1064}
@@ -1062,14 +1069,29 @@ static int _setup(struct omap_hwmod *oh)
1062 1069
1063u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs) 1070u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs)
1064{ 1071{
1065 return __raw_readl(oh->_rt_va + reg_offs); 1072 return __raw_readl(oh->_mpu_rt_va + reg_offs);
1066} 1073}
1067 1074
1068void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs) 1075void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs)
1069{ 1076{
1070 __raw_writel(v, oh->_rt_va + reg_offs); 1077 __raw_writel(v, oh->_mpu_rt_va + reg_offs);
1071} 1078}
1072 1079
1080/**
1081 * omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode
1082 * @oh: struct omap_hwmod *
1083 * @idlemode: SIDLEMODE field bits (shifted to bit 0)
1084 *
1085 * Sets the IP block's OCP slave idlemode in hardware, and updates our
1086 * local copy. Intended to be used by drivers that have some erratum
1087 * that requires direct manipulation of the SIDLEMODE bits. Returns
1088 * -EINVAL if @oh is null, or passes along the return value from
1089 * _set_slave_idlemode().
1090 *
1091 * XXX Does this function have any current users? If not, we should
1092 * remove it; it is better to let the rest of the hwmod code handle this.
1093 * Any users of this function should be scrutinized carefully.
1094 */
1073int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode) 1095int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
1074{ 1096{
1075 u32 v; 1097 u32 v;
@@ -1124,7 +1146,7 @@ int omap_hwmod_register(struct omap_hwmod *oh)
1124 ms_id = _find_mpu_port_index(oh); 1146 ms_id = _find_mpu_port_index(oh);
1125 if (!IS_ERR_VALUE(ms_id)) { 1147 if (!IS_ERR_VALUE(ms_id)) {
1126 oh->_mpu_port_index = ms_id; 1148 oh->_mpu_port_index = ms_id;
1127 oh->_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index); 1149 oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
1128 } else { 1150 } else {
1129 oh->_int_flags |= _HWMOD_NO_MPU_PORT; 1151 oh->_int_flags |= _HWMOD_NO_MPU_PORT;
1130 } 1152 }
@@ -1164,6 +1186,7 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
1164/** 1186/**
1165 * omap_hwmod_for_each - call function for each registered omap_hwmod 1187 * omap_hwmod_for_each - call function for each registered omap_hwmod
1166 * @fn: pointer to a callback function 1188 * @fn: pointer to a callback function
1189 * @data: void * data to pass to callback function
1167 * 1190 *
1168 * Call @fn for each registered omap_hwmod, passing @data to each 1191 * Call @fn for each registered omap_hwmod, passing @data to each
1169 * function. @fn must return 0 for success or any other value for 1192 * function. @fn must return 0 for success or any other value for
@@ -1172,7 +1195,8 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
1172 * caller of omap_hwmod_for_each(). @fn is called with 1195 * caller of omap_hwmod_for_each(). @fn is called with
1173 * omap_hwmod_for_each() held. 1196 * omap_hwmod_for_each() held.
1174 */ 1197 */
1175int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh)) 1198int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
1199 void *data)
1176{ 1200{
1177 struct omap_hwmod *temp_oh; 1201 struct omap_hwmod *temp_oh;
1178 int ret; 1202 int ret;
@@ -1182,7 +1206,7 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh))
1182 1206
1183 mutex_lock(&omap_hwmod_mutex); 1207 mutex_lock(&omap_hwmod_mutex);
1184 list_for_each_entry(temp_oh, &omap_hwmod_list, node) { 1208 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
1185 ret = (*fn)(temp_oh); 1209 ret = (*fn)(temp_oh, data);
1186 if (ret) 1210 if (ret)
1187 break; 1211 break;
1188 } 1212 }
@@ -1229,24 +1253,28 @@ int omap_hwmod_init(struct omap_hwmod **ohs)
1229 1253
1230/** 1254/**
1231 * omap_hwmod_late_init - do some post-clock framework initialization 1255 * omap_hwmod_late_init - do some post-clock framework initialization
1256 * @skip_setup_idle: if 1, do not idle hwmods in _setup()
1232 * 1257 *
1233 * Must be called after omap2_clk_init(). Resolves the struct clk names 1258 * Must be called after omap2_clk_init(). Resolves the struct clk names
1234 * to struct clk pointers for each registered omap_hwmod. Also calls 1259 * to struct clk pointers for each registered omap_hwmod. Also calls
1235 * _setup() on each hwmod. Returns 0. 1260 * _setup() on each hwmod. Returns 0.
1236 */ 1261 */
1237int omap_hwmod_late_init(void) 1262int omap_hwmod_late_init(u8 skip_setup_idle)
1238{ 1263{
1239 int r; 1264 int r;
1240 1265
1241 /* XXX check return value */ 1266 /* XXX check return value */
1242 r = omap_hwmod_for_each(_init_clocks); 1267 r = omap_hwmod_for_each(_init_clocks, NULL);
1243 WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n"); 1268 WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n");
1244 1269
1245 mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME); 1270 mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME);
1246 WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n", 1271 WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n",
1247 MPU_INITIATOR_NAME); 1272 MPU_INITIATOR_NAME);
1248 1273
1249 omap_hwmod_for_each(_setup); 1274 if (skip_setup_idle)
1275 pr_debug("omap_hwmod: will leave hwmods enabled during setup\n");
1276
1277 omap_hwmod_for_each(_setup, &skip_setup_idle);
1250 1278
1251 return 0; 1279 return 0;
1252} 1280}
@@ -1270,7 +1298,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
1270 pr_debug("omap_hwmod: %s: unregistering\n", oh->name); 1298 pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
1271 1299
1272 mutex_lock(&omap_hwmod_mutex); 1300 mutex_lock(&omap_hwmod_mutex);
1273 iounmap(oh->_rt_va); 1301 iounmap(oh->_mpu_rt_va);
1274 list_del(&oh->node); 1302 list_del(&oh->node);
1275 mutex_unlock(&omap_hwmod_mutex); 1303 mutex_unlock(&omap_hwmod_mutex);
1276 1304
@@ -1292,12 +1320,13 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
1292 return -EINVAL; 1320 return -EINVAL;
1293 1321
1294 mutex_lock(&omap_hwmod_mutex); 1322 mutex_lock(&omap_hwmod_mutex);
1295 r = _enable(oh); 1323 r = _omap_hwmod_enable(oh);
1296 mutex_unlock(&omap_hwmod_mutex); 1324 mutex_unlock(&omap_hwmod_mutex);
1297 1325
1298 return r; 1326 return r;
1299} 1327}
1300 1328
1329
1301/** 1330/**
1302 * omap_hwmod_idle - idle an omap_hwmod 1331 * omap_hwmod_idle - idle an omap_hwmod
1303 * @oh: struct omap_hwmod * 1332 * @oh: struct omap_hwmod *
@@ -1311,7 +1340,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
1311 return -EINVAL; 1340 return -EINVAL;
1312 1341
1313 mutex_lock(&omap_hwmod_mutex); 1342 mutex_lock(&omap_hwmod_mutex);
1314 _idle(oh); 1343 _omap_hwmod_idle(oh);
1315 mutex_unlock(&omap_hwmod_mutex); 1344 mutex_unlock(&omap_hwmod_mutex);
1316 1345
1317 return 0; 1346 return 0;
@@ -1413,7 +1442,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
1413 mutex_lock(&omap_hwmod_mutex); 1442 mutex_lock(&omap_hwmod_mutex);
1414 r = _reset(oh); 1443 r = _reset(oh);
1415 if (!r) 1444 if (!r)
1416 r = _enable(oh); 1445 r = _omap_hwmod_enable(oh);
1417 mutex_unlock(&omap_hwmod_mutex); 1446 mutex_unlock(&omap_hwmod_mutex);
1418 1447
1419 return r; 1448 return r;
@@ -1530,6 +1559,29 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
1530} 1559}
1531 1560
1532/** 1561/**
1562 * omap_hwmod_get_mpu_rt_va - return the module's base address (for the MPU)
1563 * @oh: struct omap_hwmod *
1564 *
1565 * Returns the virtual address corresponding to the beginning of the
1566 * module's register target, in the address range that is intended to
1567 * be used by the MPU. Returns the virtual address upon success or NULL
1568 * upon error.
1569 */
1570void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
1571{
1572 if (!oh)
1573 return NULL;
1574
1575 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
1576 return NULL;
1577
1578 if (oh->_state == _HWMOD_STATE_UNKNOWN)
1579 return NULL;
1580
1581 return oh->_mpu_rt_va;
1582}
1583
1584/**
1533 * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh 1585 * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
1534 * @oh: struct omap_hwmod * 1586 * @oh: struct omap_hwmod *
1535 * @init_oh: struct omap_hwmod * (initiator) 1587 * @init_oh: struct omap_hwmod * (initiator)
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index e5530c51f77d..3cc768e8bc04 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -30,42 +30,44 @@
30 */ 30 */
31 31
32static struct omap_hwmod omap2420_mpu_hwmod; 32static struct omap_hwmod omap2420_mpu_hwmod;
33static struct omap_hwmod omap2420_l3_hwmod; 33static struct omap_hwmod omap2420_iva_hwmod;
34static struct omap_hwmod omap2420_l3_main_hwmod;
34static struct omap_hwmod omap2420_l4_core_hwmod; 35static struct omap_hwmod omap2420_l4_core_hwmod;
35 36
36/* L3 -> L4_CORE interface */ 37/* L3 -> L4_CORE interface */
37static struct omap_hwmod_ocp_if omap2420_l3__l4_core = { 38static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
38 .master = &omap2420_l3_hwmod, 39 .master = &omap2420_l3_main_hwmod,
39 .slave = &omap2420_l4_core_hwmod, 40 .slave = &omap2420_l4_core_hwmod,
40 .user = OCP_USER_MPU | OCP_USER_SDMA, 41 .user = OCP_USER_MPU | OCP_USER_SDMA,
41}; 42};
42 43
43/* MPU -> L3 interface */ 44/* MPU -> L3 interface */
44static struct omap_hwmod_ocp_if omap2420_mpu__l3 = { 45static struct omap_hwmod_ocp_if omap2420_mpu__l3_main = {
45 .master = &omap2420_mpu_hwmod, 46 .master = &omap2420_mpu_hwmod,
46 .slave = &omap2420_l3_hwmod, 47 .slave = &omap2420_l3_main_hwmod,
47 .user = OCP_USER_MPU, 48 .user = OCP_USER_MPU,
48}; 49};
49 50
50/* Slave interfaces on the L3 interconnect */ 51/* Slave interfaces on the L3 interconnect */
51static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = { 52static struct omap_hwmod_ocp_if *omap2420_l3_main_slaves[] = {
52 &omap2420_mpu__l3, 53 &omap2420_mpu__l3_main,
53}; 54};
54 55
55/* Master interfaces on the L3 interconnect */ 56/* Master interfaces on the L3 interconnect */
56static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = { 57static struct omap_hwmod_ocp_if *omap2420_l3_main_masters[] = {
57 &omap2420_l3__l4_core, 58 &omap2420_l3_main__l4_core,
58}; 59};
59 60
60/* L3 */ 61/* L3 */
61static struct omap_hwmod omap2420_l3_hwmod = { 62static struct omap_hwmod omap2420_l3_main_hwmod = {
62 .name = "l3_hwmod", 63 .name = "l3_main",
63 .class = &l3_hwmod_class, 64 .class = &l3_hwmod_class,
64 .masters = omap2420_l3_masters, 65 .masters = omap2420_l3_main_masters,
65 .masters_cnt = ARRAY_SIZE(omap2420_l3_masters), 66 .masters_cnt = ARRAY_SIZE(omap2420_l3_main_masters),
66 .slaves = omap2420_l3_slaves, 67 .slaves = omap2420_l3_main_slaves,
67 .slaves_cnt = ARRAY_SIZE(omap2420_l3_slaves), 68 .slaves_cnt = ARRAY_SIZE(omap2420_l3_main_slaves),
68 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) 69 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
70 .flags = HWMOD_NO_IDLEST,
69}; 71};
70 72
71static struct omap_hwmod omap2420_l4_wkup_hwmod; 73static struct omap_hwmod omap2420_l4_wkup_hwmod;
@@ -79,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
79 81
80/* Slave interfaces on the L4_CORE interconnect */ 82/* Slave interfaces on the L4_CORE interconnect */
81static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = { 83static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
82 &omap2420_l3__l4_core, 84 &omap2420_l3_main__l4_core,
83}; 85};
84 86
85/* Master interfaces on the L4_CORE interconnect */ 87/* Master interfaces on the L4_CORE interconnect */
@@ -89,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
89 91
90/* L4 CORE */ 92/* L4 CORE */
91static struct omap_hwmod omap2420_l4_core_hwmod = { 93static struct omap_hwmod omap2420_l4_core_hwmod = {
92 .name = "l4_core_hwmod", 94 .name = "l4_core",
93 .class = &l4_hwmod_class, 95 .class = &l4_hwmod_class,
94 .masters = omap2420_l4_core_masters, 96 .masters = omap2420_l4_core_masters,
95 .masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters), 97 .masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters),
96 .slaves = omap2420_l4_core_slaves, 98 .slaves = omap2420_l4_core_slaves,
97 .slaves_cnt = ARRAY_SIZE(omap2420_l4_core_slaves), 99 .slaves_cnt = ARRAY_SIZE(omap2420_l4_core_slaves),
98 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) 100 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
101 .flags = HWMOD_NO_IDLEST,
99}; 102};
100 103
101/* Slave interfaces on the L4_WKUP interconnect */ 104/* Slave interfaces on the L4_WKUP interconnect */
@@ -109,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
109 112
110/* L4 WKUP */ 113/* L4 WKUP */
111static struct omap_hwmod omap2420_l4_wkup_hwmod = { 114static struct omap_hwmod omap2420_l4_wkup_hwmod = {
112 .name = "l4_wkup_hwmod", 115 .name = "l4_wkup",
113 .class = &l4_hwmod_class, 116 .class = &l4_hwmod_class,
114 .masters = omap2420_l4_wkup_masters, 117 .masters = omap2420_l4_wkup_masters,
115 .masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters), 118 .masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters),
116 .slaves = omap2420_l4_wkup_slaves, 119 .slaves = omap2420_l4_wkup_slaves,
117 .slaves_cnt = ARRAY_SIZE(omap2420_l4_wkup_slaves), 120 .slaves_cnt = ARRAY_SIZE(omap2420_l4_wkup_slaves),
118 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) 121 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
122 .flags = HWMOD_NO_IDLEST,
119}; 123};
120 124
121/* Master interfaces on the MPU device */ 125/* Master interfaces on the MPU device */
122static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = { 126static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
123 &omap2420_mpu__l3, 127 &omap2420_mpu__l3_main,
124}; 128};
125 129
126/* MPU */ 130/* MPU */
@@ -133,11 +137,40 @@ static struct omap_hwmod omap2420_mpu_hwmod = {
133 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), 137 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
134}; 138};
135 139
140/*
141 * IVA1 interface data
142 */
143
144/* IVA <- L3 interface */
145static struct omap_hwmod_ocp_if omap2420_l3__iva = {
146 .master = &omap2420_l3_main_hwmod,
147 .slave = &omap2420_iva_hwmod,
148 .clk = "iva1_ifck",
149 .user = OCP_USER_MPU | OCP_USER_SDMA,
150};
151
152static struct omap_hwmod_ocp_if *omap2420_iva_masters[] = {
153 &omap2420_l3__iva,
154};
155
156/*
157 * IVA2 (IVA2)
158 */
159
160static struct omap_hwmod omap2420_iva_hwmod = {
161 .name = "iva",
162 .class = &iva_hwmod_class,
163 .masters = omap2420_iva_masters,
164 .masters_cnt = ARRAY_SIZE(omap2420_iva_masters),
165 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
166};
167
136static __initdata struct omap_hwmod *omap2420_hwmods[] = { 168static __initdata struct omap_hwmod *omap2420_hwmods[] = {
137 &omap2420_l3_hwmod, 169 &omap2420_l3_main_hwmod,
138 &omap2420_l4_core_hwmod, 170 &omap2420_l4_core_hwmod,
139 &omap2420_l4_wkup_hwmod, 171 &omap2420_l4_wkup_hwmod,
140 &omap2420_mpu_hwmod, 172 &omap2420_mpu_hwmod,
173 &omap2420_iva_hwmod,
141 NULL, 174 NULL,
142}; 175};
143 176
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 0852d954da40..4526628ed287 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -30,47 +30,47 @@
30 */ 30 */
31 31
32static struct omap_hwmod omap2430_mpu_hwmod; 32static struct omap_hwmod omap2430_mpu_hwmod;
33static struct omap_hwmod omap2430_l3_hwmod; 33static struct omap_hwmod omap2430_iva_hwmod;
34static struct omap_hwmod omap2430_l3_main_hwmod;
34static struct omap_hwmod omap2430_l4_core_hwmod; 35static struct omap_hwmod omap2430_l4_core_hwmod;
35 36
36/* L3 -> L4_CORE interface */ 37/* L3 -> L4_CORE interface */
37static struct omap_hwmod_ocp_if omap2430_l3__l4_core = { 38static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
38 .master = &omap2430_l3_hwmod, 39 .master = &omap2430_l3_main_hwmod,
39 .slave = &omap2430_l4_core_hwmod, 40 .slave = &omap2430_l4_core_hwmod,
40 .user = OCP_USER_MPU | OCP_USER_SDMA, 41 .user = OCP_USER_MPU | OCP_USER_SDMA,
41}; 42};
42 43
43/* MPU -> L3 interface */ 44/* MPU -> L3 interface */
44static struct omap_hwmod_ocp_if omap2430_mpu__l3 = { 45static struct omap_hwmod_ocp_if omap2430_mpu__l3_main = {
45 .master = &omap2430_mpu_hwmod, 46 .master = &omap2430_mpu_hwmod,
46 .slave = &omap2430_l3_hwmod, 47 .slave = &omap2430_l3_main_hwmod,
47 .user = OCP_USER_MPU, 48 .user = OCP_USER_MPU,
48}; 49};
49 50
50/* Slave interfaces on the L3 interconnect */ 51/* Slave interfaces on the L3 interconnect */
51static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = { 52static struct omap_hwmod_ocp_if *omap2430_l3_main_slaves[] = {
52 &omap2430_mpu__l3, 53 &omap2430_mpu__l3_main,
53}; 54};
54 55
55/* Master interfaces on the L3 interconnect */ 56/* Master interfaces on the L3 interconnect */
56static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = { 57static struct omap_hwmod_ocp_if *omap2430_l3_main_masters[] = {
57 &omap2430_l3__l4_core, 58 &omap2430_l3_main__l4_core,
58}; 59};
59 60
60/* L3 */ 61/* L3 */
61static struct omap_hwmod omap2430_l3_hwmod = { 62static struct omap_hwmod omap2430_l3_main_hwmod = {
62 .name = "l3_hwmod", 63 .name = "l3_main",
63 .class = &l3_hwmod_class, 64 .class = &l3_hwmod_class,
64 .masters = omap2430_l3_masters, 65 .masters = omap2430_l3_main_masters,
65 .masters_cnt = ARRAY_SIZE(omap2430_l3_masters), 66 .masters_cnt = ARRAY_SIZE(omap2430_l3_main_masters),
66 .slaves = omap2430_l3_slaves, 67 .slaves = omap2430_l3_main_slaves,
67 .slaves_cnt = ARRAY_SIZE(omap2430_l3_slaves), 68 .slaves_cnt = ARRAY_SIZE(omap2430_l3_main_slaves),
68 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) 69 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
70 .flags = HWMOD_NO_IDLEST,
69}; 71};
70 72
71static struct omap_hwmod omap2430_l4_wkup_hwmod; 73static struct omap_hwmod omap2430_l4_wkup_hwmod;
72static struct omap_hwmod omap2430_mmc1_hwmod;
73static struct omap_hwmod omap2430_mmc2_hwmod;
74 74
75/* L4_CORE -> L4_WKUP interface */ 75/* L4_CORE -> L4_WKUP interface */
76static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = { 76static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
@@ -81,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
81 81
82/* Slave interfaces on the L4_CORE interconnect */ 82/* Slave interfaces on the L4_CORE interconnect */
83static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = { 83static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
84 &omap2430_l3__l4_core, 84 &omap2430_l3_main__l4_core,
85}; 85};
86 86
87/* Master interfaces on the L4_CORE interconnect */ 87/* Master interfaces on the L4_CORE interconnect */
@@ -91,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
91 91
92/* L4 CORE */ 92/* L4 CORE */
93static struct omap_hwmod omap2430_l4_core_hwmod = { 93static struct omap_hwmod omap2430_l4_core_hwmod = {
94 .name = "l4_core_hwmod", 94 .name = "l4_core",
95 .class = &l4_hwmod_class, 95 .class = &l4_hwmod_class,
96 .masters = omap2430_l4_core_masters, 96 .masters = omap2430_l4_core_masters,
97 .masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters), 97 .masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters),
98 .slaves = omap2430_l4_core_slaves, 98 .slaves = omap2430_l4_core_slaves,
99 .slaves_cnt = ARRAY_SIZE(omap2430_l4_core_slaves), 99 .slaves_cnt = ARRAY_SIZE(omap2430_l4_core_slaves),
100 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) 100 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
101 .flags = HWMOD_NO_IDLEST,
101}; 102};
102 103
103/* Slave interfaces on the L4_WKUP interconnect */ 104/* Slave interfaces on the L4_WKUP interconnect */
@@ -111,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
111 112
112/* L4 WKUP */ 113/* L4 WKUP */
113static struct omap_hwmod omap2430_l4_wkup_hwmod = { 114static struct omap_hwmod omap2430_l4_wkup_hwmod = {
114 .name = "l4_wkup_hwmod", 115 .name = "l4_wkup",
115 .class = &l4_hwmod_class, 116 .class = &l4_hwmod_class,
116 .masters = omap2430_l4_wkup_masters, 117 .masters = omap2430_l4_wkup_masters,
117 .masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters), 118 .masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters),
118 .slaves = omap2430_l4_wkup_slaves, 119 .slaves = omap2430_l4_wkup_slaves,
119 .slaves_cnt = ARRAY_SIZE(omap2430_l4_wkup_slaves), 120 .slaves_cnt = ARRAY_SIZE(omap2430_l4_wkup_slaves),
120 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) 121 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
122 .flags = HWMOD_NO_IDLEST,
121}; 123};
122 124
123/* Master interfaces on the MPU device */ 125/* Master interfaces on the MPU device */
124static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = { 126static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
125 &omap2430_mpu__l3, 127 &omap2430_mpu__l3_main,
126}; 128};
127 129
128/* MPU */ 130/* MPU */
@@ -135,11 +137,40 @@ static struct omap_hwmod omap2430_mpu_hwmod = {
135 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), 137 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
136}; 138};
137 139
140/*
141 * IVA2_1 interface data
142 */
143
144/* IVA2 <- L3 interface */
145static struct omap_hwmod_ocp_if omap2430_l3__iva = {
146 .master = &omap2430_l3_main_hwmod,
147 .slave = &omap2430_iva_hwmod,
148 .clk = "dsp_fck",
149 .user = OCP_USER_MPU | OCP_USER_SDMA,
150};
151
152static struct omap_hwmod_ocp_if *omap2430_iva_masters[] = {
153 &omap2430_l3__iva,
154};
155
156/*
157 * IVA2 (IVA2)
158 */
159
160static struct omap_hwmod omap2430_iva_hwmod = {
161 .name = "iva",
162 .class = &iva_hwmod_class,
163 .masters = omap2430_iva_masters,
164 .masters_cnt = ARRAY_SIZE(omap2430_iva_masters),
165 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
166};
167
138static __initdata struct omap_hwmod *omap2430_hwmods[] = { 168static __initdata struct omap_hwmod *omap2430_hwmods[] = {
139 &omap2430_l3_hwmod, 169 &omap2430_l3_main_hwmod,
140 &omap2430_l4_core_hwmod, 170 &omap2430_l4_core_hwmod,
141 &omap2430_l4_wkup_hwmod, 171 &omap2430_l4_wkup_hwmod,
142 &omap2430_mpu_hwmod, 172 &omap2430_mpu_hwmod,
173 &omap2430_iva_hwmod,
143 NULL, 174 NULL,
144}; 175};
145 176
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 39b0c0eaa37d..5d8eb58ba5e3 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -32,51 +32,53 @@
32 */ 32 */
33 33
34static struct omap_hwmod omap3xxx_mpu_hwmod; 34static struct omap_hwmod omap3xxx_mpu_hwmod;
35static struct omap_hwmod omap3xxx_l3_hwmod; 35static struct omap_hwmod omap3xxx_iva_hwmod;
36static struct omap_hwmod omap3xxx_l3_main_hwmod;
36static struct omap_hwmod omap3xxx_l4_core_hwmod; 37static struct omap_hwmod omap3xxx_l4_core_hwmod;
37static struct omap_hwmod omap3xxx_l4_per_hwmod; 38static struct omap_hwmod omap3xxx_l4_per_hwmod;
38 39
39/* L3 -> L4_CORE interface */ 40/* L3 -> L4_CORE interface */
40static struct omap_hwmod_ocp_if omap3xxx_l3__l4_core = { 41static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
41 .master = &omap3xxx_l3_hwmod, 42 .master = &omap3xxx_l3_main_hwmod,
42 .slave = &omap3xxx_l4_core_hwmod, 43 .slave = &omap3xxx_l4_core_hwmod,
43 .user = OCP_USER_MPU | OCP_USER_SDMA, 44 .user = OCP_USER_MPU | OCP_USER_SDMA,
44}; 45};
45 46
46/* L3 -> L4_PER interface */ 47/* L3 -> L4_PER interface */
47static struct omap_hwmod_ocp_if omap3xxx_l3__l4_per = { 48static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_per = {
48 .master = &omap3xxx_l3_hwmod, 49 .master = &omap3xxx_l3_main_hwmod,
49 .slave = &omap3xxx_l4_per_hwmod, 50 .slave = &omap3xxx_l4_per_hwmod,
50 .user = OCP_USER_MPU | OCP_USER_SDMA, 51 .user = OCP_USER_MPU | OCP_USER_SDMA,
51}; 52};
52 53
53/* MPU -> L3 interface */ 54/* MPU -> L3 interface */
54static struct omap_hwmod_ocp_if omap3xxx_mpu__l3 = { 55static struct omap_hwmod_ocp_if omap3xxx_mpu__l3_main = {
55 .master = &omap3xxx_mpu_hwmod, 56 .master = &omap3xxx_mpu_hwmod,
56 .slave = &omap3xxx_l3_hwmod, 57 .slave = &omap3xxx_l3_main_hwmod,
57 .user = OCP_USER_MPU, 58 .user = OCP_USER_MPU,
58}; 59};
59 60
60/* Slave interfaces on the L3 interconnect */ 61/* Slave interfaces on the L3 interconnect */
61static struct omap_hwmod_ocp_if *omap3xxx_l3_slaves[] = { 62static struct omap_hwmod_ocp_if *omap3xxx_l3_main_slaves[] = {
62 &omap3xxx_mpu__l3, 63 &omap3xxx_mpu__l3_main,
63}; 64};
64 65
65/* Master interfaces on the L3 interconnect */ 66/* Master interfaces on the L3 interconnect */
66static struct omap_hwmod_ocp_if *omap3xxx_l3_masters[] = { 67static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = {
67 &omap3xxx_l3__l4_core, 68 &omap3xxx_l3_main__l4_core,
68 &omap3xxx_l3__l4_per, 69 &omap3xxx_l3_main__l4_per,
69}; 70};
70 71
71/* L3 */ 72/* L3 */
72static struct omap_hwmod omap3xxx_l3_hwmod = { 73static struct omap_hwmod omap3xxx_l3_main_hwmod = {
73 .name = "l3_hwmod", 74 .name = "l3_main",
74 .class = &l3_hwmod_class, 75 .class = &l3_hwmod_class,
75 .masters = omap3xxx_l3_masters, 76 .masters = omap3xxx_l3_main_masters,
76 .masters_cnt = ARRAY_SIZE(omap3xxx_l3_masters), 77 .masters_cnt = ARRAY_SIZE(omap3xxx_l3_main_masters),
77 .slaves = omap3xxx_l3_slaves, 78 .slaves = omap3xxx_l3_main_slaves,
78 .slaves_cnt = ARRAY_SIZE(omap3xxx_l3_slaves), 79 .slaves_cnt = ARRAY_SIZE(omap3xxx_l3_main_slaves),
79 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) 80 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
81 .flags = HWMOD_NO_IDLEST,
80}; 82};
81 83
82static struct omap_hwmod omap3xxx_l4_wkup_hwmod; 84static struct omap_hwmod omap3xxx_l4_wkup_hwmod;
@@ -90,7 +92,7 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
90 92
91/* Slave interfaces on the L4_CORE interconnect */ 93/* Slave interfaces on the L4_CORE interconnect */
92static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = { 94static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
93 &omap3xxx_l3__l4_core, 95 &omap3xxx_l3_main__l4_core,
94}; 96};
95 97
96/* Master interfaces on the L4_CORE interconnect */ 98/* Master interfaces on the L4_CORE interconnect */
@@ -100,18 +102,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = {
100 102
101/* L4 CORE */ 103/* L4 CORE */
102static struct omap_hwmod omap3xxx_l4_core_hwmod = { 104static struct omap_hwmod omap3xxx_l4_core_hwmod = {
103 .name = "l4_core_hwmod", 105 .name = "l4_core",
104 .class = &l4_hwmod_class, 106 .class = &l4_hwmod_class,
105 .masters = omap3xxx_l4_core_masters, 107 .masters = omap3xxx_l4_core_masters,
106 .masters_cnt = ARRAY_SIZE(omap3xxx_l4_core_masters), 108 .masters_cnt = ARRAY_SIZE(omap3xxx_l4_core_masters),
107 .slaves = omap3xxx_l4_core_slaves, 109 .slaves = omap3xxx_l4_core_slaves,
108 .slaves_cnt = ARRAY_SIZE(omap3xxx_l4_core_slaves), 110 .slaves_cnt = ARRAY_SIZE(omap3xxx_l4_core_slaves),
109 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) 111 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
112 .flags = HWMOD_NO_IDLEST,
110}; 113};
111 114
112/* Slave interfaces on the L4_PER interconnect */ 115/* Slave interfaces on the L4_PER interconnect */
113static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = { 116static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = {
114 &omap3xxx_l3__l4_per, 117 &omap3xxx_l3_main__l4_per,
115}; 118};
116 119
117/* Master interfaces on the L4_PER interconnect */ 120/* Master interfaces on the L4_PER interconnect */
@@ -120,13 +123,14 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = {
120 123
121/* L4 PER */ 124/* L4 PER */
122static struct omap_hwmod omap3xxx_l4_per_hwmod = { 125static struct omap_hwmod omap3xxx_l4_per_hwmod = {
123 .name = "l4_per_hwmod", 126 .name = "l4_per",
124 .class = &l4_hwmod_class, 127 .class = &l4_hwmod_class,
125 .masters = omap3xxx_l4_per_masters, 128 .masters = omap3xxx_l4_per_masters,
126 .masters_cnt = ARRAY_SIZE(omap3xxx_l4_per_masters), 129 .masters_cnt = ARRAY_SIZE(omap3xxx_l4_per_masters),
127 .slaves = omap3xxx_l4_per_slaves, 130 .slaves = omap3xxx_l4_per_slaves,
128 .slaves_cnt = ARRAY_SIZE(omap3xxx_l4_per_slaves), 131 .slaves_cnt = ARRAY_SIZE(omap3xxx_l4_per_slaves),
129 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) 132 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
133 .flags = HWMOD_NO_IDLEST,
130}; 134};
131 135
132/* Slave interfaces on the L4_WKUP interconnect */ 136/* Slave interfaces on the L4_WKUP interconnect */
@@ -140,18 +144,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_masters[] = {
140 144
141/* L4 WKUP */ 145/* L4 WKUP */
142static struct omap_hwmod omap3xxx_l4_wkup_hwmod = { 146static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
143 .name = "l4_wkup_hwmod", 147 .name = "l4_wkup",
144 .class = &l4_hwmod_class, 148 .class = &l4_hwmod_class,
145 .masters = omap3xxx_l4_wkup_masters, 149 .masters = omap3xxx_l4_wkup_masters,
146 .masters_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_masters), 150 .masters_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_masters),
147 .slaves = omap3xxx_l4_wkup_slaves, 151 .slaves = omap3xxx_l4_wkup_slaves,
148 .slaves_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_slaves), 152 .slaves_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_slaves),
149 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) 153 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
154 .flags = HWMOD_NO_IDLEST,
150}; 155};
151 156
152/* Master interfaces on the MPU device */ 157/* Master interfaces on the MPU device */
153static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = { 158static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = {
154 &omap3xxx_mpu__l3, 159 &omap3xxx_mpu__l3_main,
155}; 160};
156 161
157/* MPU */ 162/* MPU */
@@ -164,12 +169,41 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
164 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), 169 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
165}; 170};
166 171
172/*
173 * IVA2_2 interface data
174 */
175
176/* IVA2 <- L3 interface */
177static struct omap_hwmod_ocp_if omap3xxx_l3__iva = {
178 .master = &omap3xxx_l3_main_hwmod,
179 .slave = &omap3xxx_iva_hwmod,
180 .clk = "iva2_ck",
181 .user = OCP_USER_MPU | OCP_USER_SDMA,
182};
183
184static struct omap_hwmod_ocp_if *omap3xxx_iva_masters[] = {
185 &omap3xxx_l3__iva,
186};
187
188/*
189 * IVA2 (IVA2)
190 */
191
192static struct omap_hwmod omap3xxx_iva_hwmod = {
193 .name = "iva",
194 .class = &iva_hwmod_class,
195 .masters = omap3xxx_iva_masters,
196 .masters_cnt = ARRAY_SIZE(omap3xxx_iva_masters),
197 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
198};
199
167static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { 200static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
168 &omap3xxx_l3_hwmod, 201 &omap3xxx_l3_main_hwmod,
169 &omap3xxx_l4_core_hwmod, 202 &omap3xxx_l4_core_hwmod,
170 &omap3xxx_l4_per_hwmod, 203 &omap3xxx_l4_per_hwmod,
171 &omap3xxx_l4_wkup_hwmod, 204 &omap3xxx_l4_wkup_hwmod,
172 &omap3xxx_mpu_hwmod, 205 &omap3xxx_mpu_hwmod,
206 &omap3xxx_iva_hwmod,
173 NULL, 207 NULL,
174}; 208};
175 209
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.c b/arch/arm/mach-omap2/omap_hwmod_common_data.c
index 1e80b914fa1a..08a134243ecb 100644
--- a/arch/arm/mach-omap2/omap_hwmod_common_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.c
@@ -66,3 +66,6 @@ struct omap_hwmod_class mpu_hwmod_class = {
66 .name = "mpu" 66 .name = "mpu"
67}; 67};
68 68
69struct omap_hwmod_class iva_hwmod_class = {
70 .name = "iva"
71};
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h
index 3645a28c7c27..c34e98bf1242 100644
--- a/arch/arm/mach-omap2/omap_hwmod_common_data.h
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h
@@ -20,5 +20,6 @@
20extern struct omap_hwmod_class l3_hwmod_class; 20extern struct omap_hwmod_class l3_hwmod_class;
21extern struct omap_hwmod_class l4_hwmod_class; 21extern struct omap_hwmod_class l4_hwmod_class;
22extern struct omap_hwmod_class mpu_hwmod_class; 22extern struct omap_hwmod_class mpu_hwmod_class;
23extern struct omap_hwmod_class iva_hwmod_class;
23 24
24#endif 25#endif
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
new file mode 100644
index 000000000000..68f9f2e95891
--- /dev/null
+++ b/arch/arm/mach-omap2/pm.c
@@ -0,0 +1,84 @@
1/*
2 * pm.c - Common OMAP2+ power management-related code
3 *
4 * Copyright (C) 2010 Texas Instruments, Inc.
5 * Copyright (C) 2010 Nokia Corporation
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/err.h>
16
17#include <plat/omap-pm.h>
18#include <plat/omap_device.h>
19#include <plat/common.h>
20
21static struct omap_device_pm_latency *pm_lats;
22
23static struct device *mpu_dev;
24static struct device *dsp_dev;
25static struct device *l3_dev;
26
27struct device *omap2_get_mpuss_device(void)
28{
29 WARN_ON_ONCE(!mpu_dev);
30 return mpu_dev;
31}
32
33struct device *omap2_get_dsp_device(void)
34{
35 WARN_ON_ONCE(!dsp_dev);
36 return dsp_dev;
37}
38
39struct device *omap2_get_l3_device(void)
40{
41 WARN_ON_ONCE(!l3_dev);
42 return l3_dev;
43}
44
45/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
46static int _init_omap_device(char *name, struct device **new_dev)
47{
48 struct omap_hwmod *oh;
49 struct omap_device *od;
50
51 oh = omap_hwmod_lookup(name);
52 if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
53 __func__, name))
54 return -ENODEV;
55
56 od = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false);
57 if (WARN(IS_ERR(od), "%s: could not build omap_device for %s\n",
58 __func__, name))
59 return -ENODEV;
60
61 *new_dev = &od->pdev.dev;
62
63 return 0;
64}
65
66/*
67 * Build omap_devices for processors and bus.
68 */
69static void omap2_init_processor_devices(void)
70{
71 _init_omap_device("mpu", &mpu_dev);
72 _init_omap_device("iva", &dsp_dev);
73 _init_omap_device("l3_main", &l3_dev);
74}
75
76static int __init omap2_common_pm_init(void)
77{
78 omap2_init_processor_devices();
79 omap_pm_if_init();
80
81 return 0;
82}
83device_initcall(omap2_common_pm_init);
84
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 98f01910c2cf..9405831b746a 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
15# omap_device support (OMAP2+ only at the moment) 15# omap_device support (OMAP2+ only at the moment)
16obj-$(CONFIG_ARCH_OMAP2) += omap_device.o 16obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
17obj-$(CONFIG_ARCH_OMAP3) += omap_device.o 17obj-$(CONFIG_ARCH_OMAP3) += omap_device.o
18obj-$(CONFIG_ARCH_OMAP4) += omap_device.o
18 19
19obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 20obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
20obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o 21obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index eec2b4993c69..a5ce4f0aad35 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -138,6 +138,16 @@ static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id)
138 return platform_device_register(pdev); 138 return platform_device_register(pdev);
139} 139}
140 140
141/*
142 * XXX This function is a temporary compatibility wrapper - only
143 * needed until the I2C driver can be converted to call
144 * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
145 */
146static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
147{
148 omap_pm_set_max_mpu_wakeup_lat(dev, t);
149}
150
141static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id) 151static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
142{ 152{
143 struct resource *res; 153 struct resource *res;
@@ -168,7 +178,7 @@ static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
168 struct omap_i2c_bus_platform_data *pd; 178 struct omap_i2c_bus_platform_data *pd;
169 179
170 pd = pdev->dev.platform_data; 180 pd = pdev->dev.platform_data;
171 pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat; 181 pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
172 } 182 }
173 183
174 return platform_device_register(pdev); 184 return platform_device_register(pdev);
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index dfc472ca0cc4..fef4696dcf67 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -19,6 +19,22 @@ struct module;
19struct clk; 19struct clk;
20struct clockdomain; 20struct clockdomain;
21 21
22/**
23 * struct clkops - some clock function pointers
24 * @enable: fn ptr that enables the current clock in hardware
25 * @disable: fn ptr that enables the current clock in hardware
26 * @find_idlest: function returning the IDLEST register for the clock's IP blk
27 * @find_companion: function returning the "companion" clk reg for the clock
28 *
29 * A "companion" clk is an accompanying clock to the one being queried
30 * that must be enabled for the IP module connected to the clock to
31 * become accessible by the hardware. Neither @find_idlest nor
32 * @find_companion should be needed; that information is IP
33 * block-specific; the hwmod code has been created to handle this, but
34 * until hwmod data is ready and drivers have been converted to use PM
35 * runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
36 * @find_companion must, unfortunately, remain.
37 */
22struct clkops { 38struct clkops {
23 int (*enable)(struct clk *); 39 int (*enable)(struct clk *);
24 void (*disable)(struct clk *); 40 void (*disable)(struct clk *);
@@ -30,12 +46,45 @@ struct clkops {
30 46
31#ifdef CONFIG_ARCH_OMAP2PLUS 47#ifdef CONFIG_ARCH_OMAP2PLUS
32 48
49/* struct clksel_rate.flags possibilities */
50#define RATE_IN_242X (1 << 0)
51#define RATE_IN_243X (1 << 1)
52#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */
53#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */
54#define RATE_IN_36XX (1 << 4)
55#define RATE_IN_4430 (1 << 5)
56
57#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
58#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX)
59
60/**
61 * struct clksel_rate - register bitfield values corresponding to clk divisors
62 * @val: register bitfield value (shifted to bit 0)
63 * @div: clock divisor corresponding to @val
64 * @flags: (see "struct clksel_rate.flags possibilities" above)
65 *
66 * @val should match the value of a read from struct clk.clksel_reg
67 * AND'ed with struct clk.clksel_mask, shifted right to bit 0.
68 *
69 * @div is the divisor that should be applied to the parent clock's rate
70 * to produce the current clock's rate.
71 *
72 * XXX @flags probably should be replaced with an struct omap_chip.
73 */
33struct clksel_rate { 74struct clksel_rate {
34 u32 val; 75 u32 val;
35 u8 div; 76 u8 div;
36 u8 flags; 77 u8 flags;
37}; 78};
38 79
80/**
81 * struct clksel - available parent clocks, and a pointer to their divisors
82 * @parent: struct clk * to a possible parent clock
83 * @rates: available divisors for this parent clock
84 *
85 * A struct clksel is always associated with one or more struct clks
86 * and one or more struct clksel_rates.
87 */
39struct clksel { 88struct clksel {
40 struct clk *parent; 89 struct clk *parent;
41 const struct clksel_rate *rates; 90 const struct clksel_rate *rates;
@@ -116,6 +165,60 @@ struct dpll_data {
116 165
117#endif 166#endif
118 167
168/* struct clk.flags possibilities */
169#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */
170#define CLOCK_IDLE_CONTROL (1 << 1)
171#define CLOCK_NO_IDLE_PARENT (1 << 2)
172#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */
173#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */
174
175/**
176 * struct clk - OMAP struct clk
177 * @node: list_head connecting this clock into the full clock list
178 * @ops: struct clkops * for this clock
179 * @name: the name of the clock in the hardware (used in hwmod data and debug)
180 * @parent: pointer to this clock's parent struct clk
181 * @children: list_head connecting to the child clks' @sibling list_heads
182 * @sibling: list_head connecting this clk to its parent clk's @children
183 * @rate: current clock rate
184 * @enable_reg: register to write to enable the clock (see @enable_bit)
185 * @recalc: fn ptr that returns the clock's current rate
186 * @set_rate: fn ptr that can change the clock's current rate
187 * @round_rate: fn ptr that can round the clock's current rate
188 * @init: fn ptr to do clock-specific initialization
189 * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
190 * @usecount: number of users that have requested this clock to be enabled
191 * @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
192 * @flags: see "struct clk.flags possibilities" above
193 * @clksel_reg: for clksel clks, register va containing src/divisor select
194 * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
195 * @clksel: for clksel clks, pointer to struct clksel for this clock
196 * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
197 * @clkdm_name: clockdomain name that this clock is contained in
198 * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
199 * @rate_offset: bitshift for rate selection bitfield (OMAP1 only)
200 * @src_offset: bitshift for source selection bitfield (OMAP1 only)
201 *
202 * XXX @rate_offset, @src_offset should probably be removed and OMAP1
203 * clock code converted to use clksel.
204 *
205 * XXX @usecount is poorly named. It should be "enable_count" or
206 * something similar. "users" in the description refers to kernel
207 * code (core code or drivers) that have called clk_enable() and not
208 * yet called clk_disable(); the usecount of parent clocks is also
209 * incremented by the clock code when clk_enable() is called on child
210 * clocks and decremented by the clock code when clk_disable() is
211 * called on child clocks.
212 *
213 * XXX @clkdm, @usecount, @children, @sibling should be marked for
214 * internal use only.
215 *
216 * @children and @sibling are used to optimize parent-to-child clock
217 * tree traversals. (child-to-parent traversals use @parent.)
218 *
219 * XXX The notion of the clock's current rate probably needs to be
220 * separated from the clock's target rate.
221 */
119struct clk { 222struct clk {
120 struct list_head node; 223 struct list_head node;
121 const struct clkops *ops; 224 const struct clkops *ops;
@@ -129,8 +232,8 @@ struct clk {
129 int (*set_rate)(struct clk *, unsigned long); 232 int (*set_rate)(struct clk *, unsigned long);
130 long (*round_rate)(struct clk *, unsigned long); 233 long (*round_rate)(struct clk *, unsigned long);
131 void (*init)(struct clk *); 234 void (*init)(struct clk *);
132 __u8 enable_bit; 235 u8 enable_bit;
133 __s8 usecount; 236 s8 usecount;
134 u8 fixed_div; 237 u8 fixed_div;
135 u8 flags; 238 u8 flags;
136#ifdef CONFIG_ARCH_OMAP2PLUS 239#ifdef CONFIG_ARCH_OMAP2PLUS
@@ -141,8 +244,8 @@ struct clk {
141 const char *clkdm_name; 244 const char *clkdm_name;
142 struct clockdomain *clkdm; 245 struct clockdomain *clkdm;
143#else 246#else
144 __u8 rate_offset; 247 u8 rate_offset;
145 __u8 src_offset; 248 u8 src_offset;
146#endif 249#endif
147#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) 250#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
148 struct dentry *dent; /* For visible tree hierarchy */ 251 struct dentry *dent; /* For visible tree hierarchy */
@@ -188,23 +291,4 @@ extern const struct clkops clkops_null;
188 291
189extern struct clk dummy_ck; 292extern struct clk dummy_ck;
190 293
191/* Clock flags */
192#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */
193#define CLOCK_IDLE_CONTROL (1 << 1)
194#define CLOCK_NO_IDLE_PARENT (1 << 2)
195#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */
196#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */
197
198/* Clksel_rate flags */
199#define RATE_IN_242X (1 << 0)
200#define RATE_IN_243X (1 << 1)
201#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */
202#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */
203#define RATE_IN_36XX (1 << 4)
204#define RATE_IN_4430 (1 << 5)
205
206#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
207
208#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX)
209
210#endif 294#endif
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index d265018f5e6b..fe83e901ba6c 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -87,4 +87,8 @@ void omap2_set_globals_uart(struct omap_globals *);
87 } \ 87 } \
88}) 88})
89 89
90extern struct device *omap2_get_mpuss_device(void);
91extern struct device *omap2_get_dsp_device(void);
92extern struct device *omap2_get_l3_device(void);
93
90#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ 94#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index 3ee41d711492..728fbb9dd549 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * omap-pm.h - OMAP power management interface 2 * omap-pm.h - OMAP power management interface
3 * 3 *
4 * Copyright (C) 2008-2009 Texas Instruments, Inc. 4 * Copyright (C) 2008-2010 Texas Instruments, Inc.
5 * Copyright (C) 2008-2009 Nokia Corporation 5 * Copyright (C) 2008-2010 Nokia Corporation
6 * Paul Walmsley 6 * Paul Walmsley
7 * 7 *
8 * Interface developed by (in alphabetical order): Karthik Dasu, Jouni 8 * Interface developed by (in alphabetical order): Karthik Dasu, Jouni
@@ -16,6 +16,7 @@
16 16
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/cpufreq.h> 18#include <linux/cpufreq.h>
19#include <linux/clk.h>
19 20
20#include "powerdomain.h" 21#include "powerdomain.h"
21 22
@@ -89,7 +90,7 @@ void omap_pm_if_exit(void);
89 * @t: maximum MPU wakeup latency in microseconds 90 * @t: maximum MPU wakeup latency in microseconds
90 * 91 *
91 * Request that the maximum interrupt latency for the MPU to be no 92 * Request that the maximum interrupt latency for the MPU to be no
92 * greater than 't' microseconds. "Interrupt latency" in this case is 93 * greater than @t microseconds. "Interrupt latency" in this case is
93 * defined as the elapsed time from the occurrence of a hardware or 94 * defined as the elapsed time from the occurrence of a hardware or
94 * timer interrupt to the time when the device driver's interrupt 95 * timer interrupt to the time when the device driver's interrupt
95 * service routine has been entered by the MPU. 96 * service routine has been entered by the MPU.
@@ -105,15 +106,19 @@ void omap_pm_if_exit(void);
105 * elapsed from when a device driver enables a hardware device with 106 * elapsed from when a device driver enables a hardware device with
106 * clk_enable(), to when the device is ready for register access or 107 * clk_enable(), to when the device is ready for register access or
107 * other use. To control this device wakeup latency, use 108 * other use. To control this device wakeup latency, use
108 * set_max_dev_wakeup_lat() 109 * omap_pm_set_max_dev_wakeup_lat()
109 * 110 *
110 * Multiple calls to set_max_mpu_wakeup_lat() will replace the 111 * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
111 * previous t value. To remove the latency target for the MPU, call 112 * previous t value. To remove the latency target for the MPU, call
112 * with t = -1. 113 * with t = -1.
113 * 114 *
114 * No return value. 115 * XXX This constraint will be deprecated soon in favor of the more
116 * general omap_pm_set_max_dev_wakeup_lat()
117 *
118 * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
119 * is not satisfiable, or 0 upon success.
115 */ 120 */
116void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t); 121int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
117 122
118 123
119/** 124/**
@@ -123,8 +128,8 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
123 * @r: minimum throughput (in KiB/s) 128 * @r: minimum throughput (in KiB/s)
124 * 129 *
125 * Request that the minimum data throughput on the OCP interconnect 130 * Request that the minimum data throughput on the OCP interconnect
126 * attached to device 'dev' interconnect agent 'tbus_id' be no less 131 * attached to device @dev interconnect agent @tbus_id be no less
127 * than 'r' KiB/s. 132 * than @r KiB/s.
128 * 133 *
129 * It is expected that the OMAP PM or bus code will use this 134 * It is expected that the OMAP PM or bus code will use this
130 * information to set the interconnect clock to run at the lowest 135 * information to set the interconnect clock to run at the lowest
@@ -138,40 +143,44 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
138 * code will also need to add an minimum L3 interconnect speed 143 * code will also need to add an minimum L3 interconnect speed
139 * constraint, 144 * constraint,
140 * 145 *
141 * Multiple calls to set_min_bus_tput() will replace the previous rate 146 * Multiple calls to omap_pm_set_min_bus_tput() will replace the
142 * value for this device. To remove the interconnect throughput 147 * previous rate value for this device. To remove the interconnect
143 * restriction for this device, call with r = 0. 148 * throughput restriction for this device, call with r = 0.
144 * 149 *
145 * No return value. 150 * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
151 * is not satisfiable, or 0 upon success.
146 */ 152 */
147void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r); 153int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
148 154
149 155
150/** 156/**
151 * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency 157 * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
152 * @dev: struct device * 158 * @req_dev: struct device * requesting the constraint, or NULL if none
159 * @dev: struct device * to set the constraint one
153 * @t: maximum device wakeup latency in microseconds 160 * @t: maximum device wakeup latency in microseconds
154 * 161 *
155 * Request that the maximum amount of time necessary for a device to 162 * Request that the maximum amount of time necessary for a device @dev
156 * become accessible after its clocks are enabled should be no greater 163 * to become accessible after its clocks are enabled should be no
157 * than 't' microseconds. Specifically, this represents the time from 164 * greater than @t microseconds. Specifically, this represents the
158 * when a device driver enables device clocks with clk_enable(), to 165 * time from when a device driver enables device clocks with
159 * when the register reads and writes on the device will succeed. 166 * clk_enable(), to when the register reads and writes on the device
160 * This function should be called before clk_disable() is called, 167 * will succeed. This function should be called before clk_disable()
161 * since the power state transition decision may be made during 168 * is called, since the power state transition decision may be made
162 * clk_disable(). 169 * during clk_disable().
163 * 170 *
164 * It is intended that underlying PM code will use this information to 171 * It is intended that underlying PM code will use this information to
165 * determine what power state to put the powerdomain enclosing this 172 * determine what power state to put the powerdomain enclosing this
166 * device into. 173 * device into.
167 * 174 *
168 * Multiple calls to set_max_dev_wakeup_lat() will replace the 175 * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the
169 * previous wakeup latency values for this device. To remove the wakeup 176 * previous wakeup latency values for this device. To remove the
170 * latency restriction for this device, call with t = -1. 177 * wakeup latency restriction for this device, call with t = -1.
171 * 178 *
172 * No return value. 179 * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
180 * is not satisfiable, or 0 upon success.
173 */ 181 */
174void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t); 182int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
183 long t);
175 184
176 185
177/** 186/**
@@ -198,10 +207,71 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
198 * value for this device. To remove the maximum DMA latency for this 207 * value for this device. To remove the maximum DMA latency for this
199 * device, call with t = -1. 208 * device, call with t = -1.
200 * 209 *
201 * No return value. 210 * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
211 * is not satisfiable, or 0 upon success.
202 */ 212 */
203void omap_pm_set_max_sdma_lat(struct device *dev, long t); 213int omap_pm_set_max_sdma_lat(struct device *dev, long t);
214
204 215
216/**
217 * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
218 * @dev: struct device * requesting the constraint
219 * @clk: struct clk * to set the minimum rate constraint on
220 * @r: minimum rate in Hz
221 *
222 * Request that the minimum clock rate on the device @dev's clk @clk
223 * be no less than @r Hz.
224 *
225 * It is expected that the OMAP PM code will use this information to
226 * find an OPP or clock setting that will satisfy this clock rate
227 * constraint, along with any other applicable system constraints on
228 * the clock rate or corresponding voltage, etc.
229 *
230 * omap_pm_set_min_clk_rate() differs from the clock code's
231 * clk_set_rate() in that it considers other constraints before taking
232 * any hardware action, and may change a system OPP rather than just a
233 * clock rate. clk_set_rate() is intended to be a low-level
234 * interface.
235 *
236 * omap_pm_set_min_clk_rate() is easily open to abuse. A better API
237 * would be something like "omap_pm_set_min_dev_performance()";
238 * however, there is no easily-generalizable concept of performance
239 * that applies to all devices. Only a device (and possibly the
240 * device subsystem) has both the subsystem-specific knowledge, and
241 * the hardware IP block-specific knowledge, to translate a constraint
242 * on "touchscreen sampling accuracy" or "number of pixels or polygons
243 * rendered per second" to a clock rate. This translation can be
244 * dependent on the hardware IP block's revision, or firmware version,
245 * and the driver is the only code on the system that has this
246 * information and can know how to translate that into a clock rate.
247 *
248 * The intended use-case for this function is for userspace or other
249 * kernel code to communicate a particular performance requirement to
250 * a subsystem; then for the subsystem to communicate that requirement
251 * to something that is meaningful to the device driver; then for the
252 * device driver to convert that requirement to a clock rate, and to
253 * then call omap_pm_set_min_clk_rate().
254 *
255 * Users of this function (such as device drivers) should not simply
256 * call this function with some high clock rate to ensure "high
257 * performance." Rather, the device driver should take a performance
258 * constraint from its subsystem, such as "render at least X polygons
259 * per second," and use some formula or table to convert that into a
260 * clock rate constraint given the hardware type and hardware
261 * revision. Device drivers or subsystems should not assume that they
262 * know how to make a power/performance tradeoff - some device use
263 * cases may tolerate a lower-fidelity device function for lower power
264 * consumption; others may demand a higher-fidelity device function,
265 * no matter what the power consumption.
266 *
267 * Multiple calls to omap_pm_set_min_clk_rate() will replace the
268 * previous rate value for the device @dev. To remove the minimum clock
269 * rate constraint for the device, call with r = 0.
270 *
271 * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
272 * is not satisfiable, or 0 upon success.
273 */
274int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r);
205 275
206/* 276/*
207 * DSP Bridge-specific constraints 277 * DSP Bridge-specific constraints
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 3694b622c4ac..25cd9ac3b095 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -101,6 +101,8 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
101int omap_device_register(struct omap_device *od); 101int omap_device_register(struct omap_device *od);
102int omap_early_device_register(struct omap_device *od); 102int omap_early_device_register(struct omap_device *od);
103 103
104void __iomem *omap_device_get_rt_va(struct omap_device *od);
105
104/* OMAP PM interface */ 106/* OMAP PM interface */
105int omap_device_align_pm_lat(struct platform_device *pdev, 107int omap_device_align_pm_lat(struct platform_device *pdev,
106 u32 new_wakeup_lat_limit); 108 u32 new_wakeup_lat_limit);
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 0eccc09ac4a9..a4e508dfaba2 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * omap_hwmod macros, structures 2 * omap_hwmod macros, structures
3 * 3 *
4 * Copyright (C) 2009 Nokia Corporation 4 * Copyright (C) 2009-2010 Nokia Corporation
5 * Paul Walmsley 5 * Paul Walmsley
6 * 6 *
7 * Created in collaboration with (alphabetical order): Benoît Cousson, 7 * Created in collaboration with (alphabetical order): Benoît Cousson,
@@ -419,7 +419,7 @@ struct omap_hwmod_class {
419 * @slaves: ptr to array of OCP ifs that this hwmod can respond on 419 * @slaves: ptr to array of OCP ifs that this hwmod can respond on
420 * @dev_attr: arbitrary device attributes that can be passed to the driver 420 * @dev_attr: arbitrary device attributes that can be passed to the driver
421 * @_sysc_cache: internal-use hwmod flags 421 * @_sysc_cache: internal-use hwmod flags
422 * @_rt_va: cached register target start address (internal use) 422 * @_mpu_rt_va: cached register target start address (internal use)
423 * @_mpu_port_index: cached MPU register target slave ID (internal use) 423 * @_mpu_port_index: cached MPU register target slave ID (internal use)
424 * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6) 424 * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
425 * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift 425 * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
@@ -460,7 +460,7 @@ struct omap_hwmod {
460 struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */ 460 struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
461 void *dev_attr; 461 void *dev_attr;
462 u32 _sysc_cache; 462 u32 _sysc_cache;
463 void __iomem *_rt_va; 463 void __iomem *_mpu_rt_va;
464 struct list_head node; 464 struct list_head node;
465 u16 flags; 465 u16 flags;
466 u8 _mpu_port_index; 466 u8 _mpu_port_index;
@@ -482,11 +482,14 @@ int omap_hwmod_init(struct omap_hwmod **ohs);
482int omap_hwmod_register(struct omap_hwmod *oh); 482int omap_hwmod_register(struct omap_hwmod *oh);
483int omap_hwmod_unregister(struct omap_hwmod *oh); 483int omap_hwmod_unregister(struct omap_hwmod *oh);
484struct omap_hwmod *omap_hwmod_lookup(const char *name); 484struct omap_hwmod *omap_hwmod_lookup(const char *name);
485int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh)); 485int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
486int omap_hwmod_late_init(void); 486 void *data);
487int omap_hwmod_late_init(u8 skip_setup_idle);
487 488
488int omap_hwmod_enable(struct omap_hwmod *oh); 489int omap_hwmod_enable(struct omap_hwmod *oh);
490int _omap_hwmod_enable(struct omap_hwmod *oh);
489int omap_hwmod_idle(struct omap_hwmod *oh); 491int omap_hwmod_idle(struct omap_hwmod *oh);
492int _omap_hwmod_idle(struct omap_hwmod *oh);
490int omap_hwmod_shutdown(struct omap_hwmod *oh); 493int omap_hwmod_shutdown(struct omap_hwmod *oh);
491 494
492int omap_hwmod_enable_clocks(struct omap_hwmod *oh); 495int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
@@ -504,6 +507,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh);
504int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); 507int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
505 508
506struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh); 509struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
510void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
507 511
508int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh, 512int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
509 struct omap_hwmod *init_oh); 513 struct omap_hwmod *init_oh);
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index 186bca82cfab..e129ce80c53b 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -34,11 +34,11 @@ struct omap_opp *l3_opps;
34 * Device-driver-originated constraints (via board-*.c files) 34 * Device-driver-originated constraints (via board-*.c files)
35 */ 35 */
36 36
37void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t) 37int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
38{ 38{
39 if (!dev || t < -1) { 39 if (!dev || t < -1) {
40 WARN_ON(1); 40 WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
41 return; 41 return -EINVAL;
42 }; 42 };
43 43
44 if (t == -1) 44 if (t == -1)
@@ -58,14 +58,16 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
58 * 58 *
59 * TI CDP code can call constraint_set here. 59 * TI CDP code can call constraint_set here.
60 */ 60 */
61
62 return 0;
61} 63}
62 64
63void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r) 65int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
64{ 66{
65 if (!dev || (agent_id != OCP_INITIATOR_AGENT && 67 if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
66 agent_id != OCP_TARGET_AGENT)) { 68 agent_id != OCP_TARGET_AGENT)) {
67 WARN_ON(1); 69 WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
68 return; 70 return -EINVAL;
69 }; 71 };
70 72
71 if (r == 0) 73 if (r == 0)
@@ -83,13 +85,16 @@ void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
83 * 85 *
84 * TI CDP code can call constraint_set here on the VDD2 OPP. 86 * TI CDP code can call constraint_set here on the VDD2 OPP.
85 */ 87 */
88
89 return 0;
86} 90}
87 91
88void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t) 92int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
93 long t)
89{ 94{
90 if (!dev || t < -1) { 95 if (!req_dev || !dev || t < -1) {
91 WARN_ON(1); 96 WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
92 return; 97 return -EINVAL;
93 }; 98 };
94 99
95 if (t == -1) 100 if (t == -1)
@@ -111,13 +116,15 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t)
111 * 116 *
112 * TI CDP code can call constraint_set here. 117 * TI CDP code can call constraint_set here.
113 */ 118 */
119
120 return 0;
114} 121}
115 122
116void omap_pm_set_max_sdma_lat(struct device *dev, long t) 123int omap_pm_set_max_sdma_lat(struct device *dev, long t)
117{ 124{
118 if (!dev || t < -1) { 125 if (!dev || t < -1) {
119 WARN_ON(1); 126 WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
120 return; 127 return -EINVAL;
121 }; 128 };
122 129
123 if (t == -1) 130 if (t == -1)
@@ -139,8 +146,36 @@ void omap_pm_set_max_sdma_lat(struct device *dev, long t)
139 * TI CDP code can call constraint_set here. 146 * TI CDP code can call constraint_set here.
140 */ 147 */
141 148
149 return 0;
142} 150}
143 151
152int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
153{
154 if (!dev || !c || r < 0) {
155 WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
156 return -EINVAL;
157 }
158
159 if (r == 0)
160 pr_debug("OMAP PM: remove min clk rate constraint: "
161 "dev %s\n", dev_name(dev));
162 else
163 pr_debug("OMAP PM: add min clk rate constraint: "
164 "dev %s, rate = %ld Hz\n", dev_name(dev), r);
165
166 /*
167 * Code in a real implementation should keep track of these
168 * constraints on the clock, and determine the highest minimum
169 * clock rate. It should iterate over each OPP and determine
170 * whether the OPP will result in a clock rate that would
171 * satisfy this constraint (and any other PM constraint in effect
172 * at that time). Once it finds the lowest-voltage OPP that
173 * meets those conditions, it should switch to it, or return
174 * an error if the code is not capable of doing so.
175 */
176
177 return 0;
178}
144 179
145/* 180/*
146 * DSP Bridge-specific constraints 181 * DSP Bridge-specific constraints
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index f899603051ac..ea0d659fcb1c 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * omap_device implementation 2 * omap_device implementation
3 * 3 *
4 * Copyright (C) 2009 Nokia Corporation 4 * Copyright (C) 2009-2010 Nokia Corporation
5 * Paul Walmsley, Kevin Hilman 5 * Paul Walmsley, Kevin Hilman
6 * 6 *
7 * Developed in collaboration with (alphabetical order): Benoit 7 * Developed in collaboration with (alphabetical order): Benoit
@@ -90,8 +90,11 @@
90#define USE_WAKEUP_LAT 0 90#define USE_WAKEUP_LAT 0
91#define IGNORE_WAKEUP_LAT 1 91#define IGNORE_WAKEUP_LAT 1
92 92
93 93/*
94#define OMAP_DEVICE_MAGIC 0xf00dcafe 94 * OMAP_DEVICE_MAGIC: used to determine whether a struct omap_device
95 * obtained via container_of() is in fact a struct omap_device
96 */
97#define OMAP_DEVICE_MAGIC 0xf00dcafe
95 98
96/* Private functions */ 99/* Private functions */
97 100
@@ -359,7 +362,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
359 struct omap_device *od; 362 struct omap_device *od;
360 char *pdev_name2; 363 char *pdev_name2;
361 struct resource *res = NULL; 364 struct resource *res = NULL;
362 int res_count; 365 int i, res_count;
363 struct omap_hwmod **hwmods; 366 struct omap_hwmod **hwmods;
364 367
365 if (!ohs || oh_cnt == 0 || !pdev_name) 368 if (!ohs || oh_cnt == 0 || !pdev_name)
@@ -416,6 +419,9 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
416 else 419 else
417 ret = omap_device_register(od); 420 ret = omap_device_register(od);
418 421
422 for (i = 0; i < oh_cnt; i++)
423 hwmods[i]->od = od;
424
419 if (ret) 425 if (ret)
420 goto odbs_exit4; 426 goto odbs_exit4;
421 427
@@ -652,6 +658,25 @@ struct powerdomain *omap_device_get_pwrdm(struct omap_device *od)
652 return omap_hwmod_get_pwrdm(od->hwmods[0]); 658 return omap_hwmod_get_pwrdm(od->hwmods[0]);
653} 659}
654 660
661/**
662 * omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base
663 * @od: struct omap_device *
664 *
665 * Return the MPU's virtual address for the base of the hwmod, from
666 * the ioremap() that the hwmod code does. Only valid if there is one
667 * hwmod associated with this device. Returns NULL if there are zero
668 * or more than one hwmods associated with this omap_device;
669 * otherwise, passes along the return value from
670 * omap_hwmod_get_mpu_rt_va().
671 */
672void __iomem *omap_device_get_rt_va(struct omap_device *od)
673{
674 if (od->hwmods_cnt != 1)
675 return NULL;
676
677 return omap_hwmod_get_mpu_rt_va(od->hwmods[0]);
678}
679
655/* 680/*
656 * Public functions intended for use in omap_device_pm_latency 681 * Public functions intended for use in omap_device_pm_latency
657 * .activate_func and .deactivate_func function pointers 682 * .activate_func and .deactivate_func function pointers