aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-09-23 14:05:25 -0400
committerTony Lindgren <tony@atomide.com>2010-09-23 14:05:25 -0400
commit9af2ebbd09e01bd2711617dcafce5f608cace6ec (patch)
tree637af612e07c98a0fd998e558a56382a52eeab36
parent493c32a0de2bfbcc33d52f32a39f3c301c6ffd62 (diff)
parent74ff3a68ed11f1e9eede4fe301f42cc3cdf7396a (diff)
Merge branch 'hwmod_2.6.37' of git://git.pwsan.com/linux-2.6 into omap-for-linus
-rw-r--r--arch/arm/mach-omap2/Makefile4
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c562
-rw-r--r--arch/arm/mach-omap2/prcm.c29
-rw-r--r--arch/arm/mach-omap2/prm.h18
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c110
-rw-r--r--arch/arm/mach-omap2/prm44xx.c116
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h55
-rw-r--r--arch/arm/plat-omap/include/plat/prcm.h2
-rw-r--r--arch/arm/plat-omap/omap_device.c43
9 files changed, 829 insertions, 110 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 88d3a1e920f5..eb2504a300c2 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -5,7 +5,7 @@
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 pm.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 prm2xxx_3xxx.o
9hwmod-common = omap_hwmod.o \ 9hwmod-common = omap_hwmod.o \
10 omap_hwmod_common_data.o 10 omap_hwmod_common_data.o
11prcm-common = prcm.o powerdomain.o 11prcm-common = prcm.o powerdomain.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) $(hwmod-common) 18obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) prm44xx.o $(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/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index cb911d7d1a3c..c3a5889d8add 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -13,10 +13,102 @@
13 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation. 14 * published by the Free Software Foundation.
15 * 15 *
16 * This code manages "OMAP modules" (on-chip devices) and their 16 * Introduction
17 * integration with Linux device driver and bus code. 17 * ------------
18 * 18 * One way to view an OMAP SoC is as a collection of largely unrelated
19 * References: 19 * IP blocks connected by interconnects. The IP blocks include
20 * devices such as ARM processors, audio serial interfaces, UARTs,
21 * etc. Some of these devices, like the DSP, are created by TI;
22 * others, like the SGX, largely originate from external vendors. In
23 * TI's documentation, on-chip devices are referred to as "OMAP
24 * modules." Some of these IP blocks are identical across several
25 * OMAP versions. Others are revised frequently.
26 *
27 * These OMAP modules are tied together by various interconnects.
28 * Most of the address and data flow between modules is via OCP-based
29 * interconnects such as the L3 and L4 buses; but there are other
30 * interconnects that distribute the hardware clock tree, handle idle
31 * and reset signaling, supply power, and connect the modules to
32 * various pads or balls on the OMAP package.
33 *
34 * OMAP hwmod provides a consistent way to describe the on-chip
35 * hardware blocks and their integration into the rest of the chip.
36 * This description can be automatically generated from the TI
37 * hardware database. OMAP hwmod provides a standard, consistent API
38 * to reset, enable, idle, and disable these hardware blocks. And
39 * hwmod provides a way for other core code, such as the Linux device
40 * code or the OMAP power management and address space mapping code,
41 * to query the hardware database.
42 *
43 * Using hwmod
44 * -----------
45 * Drivers won't call hwmod functions directly. That is done by the
46 * omap_device code, and in rare occasions, by custom integration code
47 * in arch/arm/ *omap*. The omap_device code includes functions to
48 * build a struct platform_device using omap_hwmod data, and that is
49 * currently how hwmod data is communicated to drivers and to the
50 * Linux driver model. Most drivers will call omap_hwmod functions only
51 * indirectly, via pm_runtime*() functions.
52 *
53 * From a layering perspective, here is where the OMAP hwmod code
54 * fits into the kernel software stack:
55 *
56 * +-------------------------------+
57 * | Device driver code |
58 * | (e.g., drivers/) |
59 * +-------------------------------+
60 * | Linux driver model |
61 * | (platform_device / |
62 * | platform_driver data/code) |
63 * +-------------------------------+
64 * | OMAP core-driver integration |
65 * |(arch/arm/mach-omap2/devices.c)|
66 * +-------------------------------+
67 * | omap_device code |
68 * | (../plat-omap/omap_device.c) |
69 * +-------------------------------+
70 * ----> | omap_hwmod code/data | <-----
71 * | (../mach-omap2/omap_hwmod*) |
72 * +-------------------------------+
73 * | OMAP clock/PRCM/register fns |
74 * | (__raw_{read,write}l, clk*) |
75 * +-------------------------------+
76 *
77 * Device drivers should not contain any OMAP-specific code or data in
78 * them. They should only contain code to operate the IP block that
79 * the driver is responsible for. This is because these IP blocks can
80 * also appear in other SoCs, either from TI (such as DaVinci) or from
81 * other manufacturers; and drivers should be reusable across other
82 * platforms.
83 *
84 * The OMAP hwmod code also will attempt to reset and idle all on-chip
85 * devices upon boot. The goal here is for the kernel to be
86 * completely self-reliant and independent from bootloaders. This is
87 * to ensure a repeatable configuration, both to ensure consistent
88 * runtime behavior, and to make it easier for others to reproduce
89 * bugs.
90 *
91 * OMAP module activity states
92 * ---------------------------
93 * The hwmod code considers modules to be in one of several activity
94 * states. IP blocks start out in an UNKNOWN state, then once they
95 * are registered via the hwmod code, proceed to the REGISTERED state.
96 * Once their clock names are resolved to clock pointers, the module
97 * enters the CLKS_INITED state; and finally, once the module has been
98 * reset and the integration registers programmed, the INITIALIZED state
99 * is entered. The hwmod code will then place the module into either
100 * the IDLE state to save power, or in the case of a critical system
101 * module, the ENABLED state.
102 *
103 * OMAP core integration code can then call omap_hwmod*() functions
104 * directly to move the module between the IDLE, ENABLED, and DISABLED
105 * states, as needed. This is done during both the PM idle loop, and
106 * in the OMAP core integration code's implementation of the PM runtime
107 * functions.
108 *
109 * References
110 * ----------
111 * This is a partial list.
20 * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064) 112 * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
21 * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090) 113 * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
22 * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108) 114 * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
@@ -50,11 +142,13 @@
50#include <plat/powerdomain.h> 142#include <plat/powerdomain.h>
51#include <plat/clock.h> 143#include <plat/clock.h>
52#include <plat/omap_hwmod.h> 144#include <plat/omap_hwmod.h>
145#include <plat/prcm.h>
53 146
54#include "cm.h" 147#include "cm.h"
148#include "prm.h"
55 149
56/* Maximum microseconds to wait for OMAP module to reset */ 150/* Maximum microseconds to wait for OMAP module to softreset */
57#define MAX_MODULE_RESET_WAIT 10000 151#define MAX_MODULE_SOFTRESET_WAIT 10000
58 152
59/* Name of the OMAP hwmod for the MPU */ 153/* Name of the OMAP hwmod for the MPU */
60#define MPU_INITIATOR_NAME "mpu" 154#define MPU_INITIATOR_NAME "mpu"
@@ -544,6 +638,36 @@ static int _disable_clocks(struct omap_hwmod *oh)
544 return 0; 638 return 0;
545} 639}
546 640
641static void _enable_optional_clocks(struct omap_hwmod *oh)
642{
643 struct omap_hwmod_opt_clk *oc;
644 int i;
645
646 pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name);
647
648 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
649 if (oc->_clk) {
650 pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
651 oc->_clk->name);
652 clk_enable(oc->_clk);
653 }
654}
655
656static void _disable_optional_clocks(struct omap_hwmod *oh)
657{
658 struct omap_hwmod_opt_clk *oc;
659 int i;
660
661 pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name);
662
663 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
664 if (oc->_clk) {
665 pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
666 oc->_clk->name);
667 clk_disable(oc->_clk);
668 }
669}
670
547/** 671/**
548 * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use 672 * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use
549 * @oh: struct omap_hwmod * 673 * @oh: struct omap_hwmod *
@@ -622,7 +746,7 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
622} 746}
623 747
624/** 748/**
625 * _sysc_enable - try to bring a module out of idle via OCP_SYSCONFIG 749 * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG
626 * @oh: struct omap_hwmod * 750 * @oh: struct omap_hwmod *
627 * 751 *
628 * If module is marked as SWSUP_SIDLE, force the module out of slave 752 * If module is marked as SWSUP_SIDLE, force the module out of slave
@@ -630,7 +754,7 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
630 * as SWSUP_MSUSPEND, force the module out of master standby; 754 * as SWSUP_MSUSPEND, force the module out of master standby;
631 * otherwise, configure it for smart-standby. No return value. 755 * otherwise, configure it for smart-standby. No return value.
632 */ 756 */
633static void _sysc_enable(struct omap_hwmod *oh) 757static void _enable_sysc(struct omap_hwmod *oh)
634{ 758{
635 u8 idlemode, sf; 759 u8 idlemode, sf;
636 u32 v; 760 u32 v;
@@ -659,8 +783,6 @@ static void _sysc_enable(struct omap_hwmod *oh)
659 _set_module_autoidle(oh, idlemode, &v); 783 _set_module_autoidle(oh, idlemode, &v);
660 } 784 }
661 785
662 /* XXX OCP ENAWAKEUP bit? */
663
664 /* 786 /*
665 * XXX The clock framework should handle this, by 787 * XXX The clock framework should handle this, by
666 * calling into this code. But this must wait until the 788 * calling into this code. But this must wait until the
@@ -671,10 +793,14 @@ static void _sysc_enable(struct omap_hwmod *oh)
671 _set_clockactivity(oh, oh->class->sysc->clockact, &v); 793 _set_clockactivity(oh, oh->class->sysc->clockact, &v);
672 794
673 _write_sysconfig(v, oh); 795 _write_sysconfig(v, oh);
796
797 /* If slave is in SMARTIDLE, also enable wakeup */
798 if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
799 _enable_wakeup(oh);
674} 800}
675 801
676/** 802/**
677 * _sysc_idle - try to put a module into idle via OCP_SYSCONFIG 803 * _idle_sysc - try to put a module into idle via OCP_SYSCONFIG
678 * @oh: struct omap_hwmod * 804 * @oh: struct omap_hwmod *
679 * 805 *
680 * If module is marked as SWSUP_SIDLE, force the module into slave 806 * If module is marked as SWSUP_SIDLE, force the module into slave
@@ -682,7 +808,7 @@ static void _sysc_enable(struct omap_hwmod *oh)
682 * as SWSUP_MSUSPEND, force the module into master standby; otherwise, 808 * as SWSUP_MSUSPEND, force the module into master standby; otherwise,
683 * configure it for smart-standby. No return value. 809 * configure it for smart-standby. No return value.
684 */ 810 */
685static void _sysc_idle(struct omap_hwmod *oh) 811static void _idle_sysc(struct omap_hwmod *oh)
686{ 812{
687 u8 idlemode, sf; 813 u8 idlemode, sf;
688 u32 v; 814 u32 v;
@@ -709,13 +835,13 @@ static void _sysc_idle(struct omap_hwmod *oh)
709} 835}
710 836
711/** 837/**
712 * _sysc_shutdown - force a module into idle via OCP_SYSCONFIG 838 * _shutdown_sysc - force a module into idle via OCP_SYSCONFIG
713 * @oh: struct omap_hwmod * 839 * @oh: struct omap_hwmod *
714 * 840 *
715 * Force the module into slave idle and master suspend. No return 841 * Force the module into slave idle and master suspend. No return
716 * value. 842 * value.
717 */ 843 */
718static void _sysc_shutdown(struct omap_hwmod *oh) 844static void _shutdown_sysc(struct omap_hwmod *oh)
719{ 845{
720 u32 v; 846 u32 v;
721 u8 sf; 847 u8 sf;
@@ -767,10 +893,10 @@ static struct omap_hwmod *_lookup(const char *name)
767 * @data: not used; pass NULL 893 * @data: not used; pass NULL
768 * 894 *
769 * Called by omap_hwmod_late_init() (after omap2_clk_init()). 895 * Called by omap_hwmod_late_init() (after omap2_clk_init()).
770 * Resolves all clock names embedded in the hwmod. Must be called 896 * Resolves all clock names embedded in the hwmod. Returns -EINVAL if
771 * with omap_hwmod_mutex held. Returns -EINVAL if the omap_hwmod 897 * the omap_hwmod has not yet been registered or if the clocks have
772 * has not yet been registered or if the clocks have already been 898 * already been initialized, 0 on success, or a non-zero error on
773 * initialized, 0 on success, or a non-zero error on failure. 899 * failure.
774 */ 900 */
775static int _init_clocks(struct omap_hwmod *oh, void *data) 901static int _init_clocks(struct omap_hwmod *oh, void *data)
776{ 902{
@@ -834,56 +960,202 @@ static int _wait_target_ready(struct omap_hwmod *oh)
834} 960}
835 961
836/** 962/**
963 * _lookup_hardreset - return the register bit shift for this hwmod/reset line
964 * @oh: struct omap_hwmod *
965 * @name: name of the reset line in the context of this hwmod
966 *
967 * Return the bit position of the reset line that match the
968 * input name. Return -ENOENT if not found.
969 */
970static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name)
971{
972 int i;
973
974 for (i = 0; i < oh->rst_lines_cnt; i++) {
975 const char *rst_line = oh->rst_lines[i].name;
976 if (!strcmp(rst_line, name)) {
977 u8 shift = oh->rst_lines[i].rst_shift;
978 pr_debug("omap_hwmod: %s: _lookup_hardreset: %s: %d\n",
979 oh->name, rst_line, shift);
980
981 return shift;
982 }
983 }
984
985 return -ENOENT;
986}
987
988/**
989 * _assert_hardreset - assert the HW reset line of submodules
990 * contained in the hwmod module.
991 * @oh: struct omap_hwmod *
992 * @name: name of the reset line to lookup and assert
993 *
994 * Some IP like dsp, ipu or iva contain processor that require
995 * an HW reset line to be assert / deassert in order to enable fully
996 * the IP.
997 */
998static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
999{
1000 u8 shift;
1001
1002 if (!oh)
1003 return -EINVAL;
1004
1005 shift = _lookup_hardreset(oh, name);
1006 if (IS_ERR_VALUE(shift))
1007 return shift;
1008
1009 if (cpu_is_omap24xx() || cpu_is_omap34xx())
1010 return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
1011 shift);
1012 else if (cpu_is_omap44xx())
1013 return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg,
1014 shift);
1015 else
1016 return -EINVAL;
1017}
1018
1019/**
1020 * _deassert_hardreset - deassert the HW reset line of submodules contained
1021 * in the hwmod module.
1022 * @oh: struct omap_hwmod *
1023 * @name: name of the reset line to look up and deassert
1024 *
1025 * Some IP like dsp, ipu or iva contain processor that require
1026 * an HW reset line to be assert / deassert in order to enable fully
1027 * the IP.
1028 */
1029static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
1030{
1031 u8 shift;
1032 int r;
1033
1034 if (!oh)
1035 return -EINVAL;
1036
1037 shift = _lookup_hardreset(oh, name);
1038 if (IS_ERR_VALUE(shift))
1039 return shift;
1040
1041 if (cpu_is_omap24xx() || cpu_is_omap34xx())
1042 r = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
1043 shift);
1044 else if (cpu_is_omap44xx())
1045 r = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg,
1046 shift);
1047 else
1048 return -EINVAL;
1049
1050 if (r == -EBUSY)
1051 pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name);
1052
1053 return r;
1054}
1055
1056/**
1057 * _read_hardreset - read the HW reset line state of submodules
1058 * contained in the hwmod module
1059 * @oh: struct omap_hwmod *
1060 * @name: name of the reset line to look up and read
1061 *
1062 * Return the state of the reset line.
1063 */
1064static int _read_hardreset(struct omap_hwmod *oh, const char *name)
1065{
1066 u8 shift;
1067
1068 if (!oh)
1069 return -EINVAL;
1070
1071 shift = _lookup_hardreset(oh, name);
1072 if (IS_ERR_VALUE(shift))
1073 return shift;
1074
1075 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1076 return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
1077 shift);
1078 } else if (cpu_is_omap44xx()) {
1079 return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg,
1080 shift);
1081 } else {
1082 return -EINVAL;
1083 }
1084}
1085
1086/**
837 * _reset - reset an omap_hwmod 1087 * _reset - reset an omap_hwmod
838 * @oh: struct omap_hwmod * 1088 * @oh: struct omap_hwmod *
839 * 1089 *
840 * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be 1090 * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be
841 * enabled for this to work. Must be called with omap_hwmod_mutex 1091 * enabled for this to work. Returns -EINVAL if the hwmod cannot be
842 * held. Returns -EINVAL if the hwmod cannot be reset this way or if 1092 * reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
843 * the hwmod is in the wrong state, -ETIMEDOUT if the module did not 1093 * the module did not reset in time, or 0 upon success.
844 * reset in time, or 0 upon success. 1094 *
1095 * In OMAP3 a specific SYSSTATUS register is used to get the reset status.
1096 * Starting in OMAP4, some IPs does not have SYSSTATUS register and instead
1097 * use the SYSCONFIG softreset bit to provide the status.
1098 *
1099 * Note that some IP like McBSP does have a reset control but no reset status.
845 */ 1100 */
846static int _reset(struct omap_hwmod *oh) 1101static int _reset(struct omap_hwmod *oh)
847{ 1102{
848 u32 r, v; 1103 u32 v;
849 int c = 0; 1104 int c = 0;
1105 int ret = 0;
850 1106
851 if (!oh->class->sysc || 1107 if (!oh->class->sysc ||
852 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET) || 1108 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
853 (oh->class->sysc->sysc_flags & SYSS_MISSING))
854 return -EINVAL; 1109 return -EINVAL;
855 1110
856 /* clocks must be on for this operation */ 1111 /* clocks must be on for this operation */
857 if (oh->_state != _HWMOD_STATE_ENABLED) { 1112 if (oh->_state != _HWMOD_STATE_ENABLED) {
858 WARN(1, "omap_hwmod: %s: reset can only be entered from " 1113 pr_warning("omap_hwmod: %s: reset can only be entered from "
859 "enabled state\n", oh->name); 1114 "enabled state\n", oh->name);
860 return -EINVAL; 1115 return -EINVAL;
861 } 1116 }
862 1117
1118 /* For some modules, all optionnal clocks need to be enabled as well */
1119 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1120 _enable_optional_clocks(oh);
1121
863 pr_debug("omap_hwmod: %s: resetting\n", oh->name); 1122 pr_debug("omap_hwmod: %s: resetting\n", oh->name);
864 1123
865 v = oh->_sysc_cache; 1124 v = oh->_sysc_cache;
866 r = _set_softreset(oh, &v); 1125 ret = _set_softreset(oh, &v);
867 if (r) 1126 if (ret)
868 return r; 1127 goto dis_opt_clks;
869 _write_sysconfig(v, oh); 1128 _write_sysconfig(v, oh);
870 1129
871 omap_test_timeout((omap_hwmod_readl(oh, oh->class->sysc->syss_offs) & 1130 if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
872 SYSS_RESETDONE_MASK), 1131 omap_test_timeout((omap_hwmod_readl(oh,
873 MAX_MODULE_RESET_WAIT, c); 1132 oh->class->sysc->syss_offs)
874 1133 & SYSS_RESETDONE_MASK),
875 if (c == MAX_MODULE_RESET_WAIT) 1134 MAX_MODULE_SOFTRESET_WAIT, c);
876 WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n", 1135 else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS)
877 oh->name, MAX_MODULE_RESET_WAIT); 1136 omap_test_timeout(!(omap_hwmod_readl(oh,
1137 oh->class->sysc->sysc_offs)
1138 & SYSC_TYPE2_SOFTRESET_MASK),
1139 MAX_MODULE_SOFTRESET_WAIT, c);
1140
1141 if (c == MAX_MODULE_SOFTRESET_WAIT)
1142 pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
1143 oh->name, MAX_MODULE_SOFTRESET_WAIT);
878 else 1144 else
879 pr_debug("omap_hwmod: %s: reset in %d usec\n", oh->name, c); 1145 pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c);
880 1146
881 /* 1147 /*
882 * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from 1148 * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
883 * _wait_target_ready() or _reset() 1149 * _wait_target_ready() or _reset()
884 */ 1150 */
885 1151
886 return (c == MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0; 1152 ret = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
1153
1154dis_opt_clks:
1155 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1156 _disable_optional_clocks(oh);
1157
1158 return ret;
887} 1159}
888 1160
889/** 1161/**
@@ -891,9 +1163,11 @@ static int _reset(struct omap_hwmod *oh)
891 * @oh: struct omap_hwmod * 1163 * @oh: struct omap_hwmod *
892 * 1164 *
893 * Enables an omap_hwmod @oh such that the MPU can access the hwmod's 1165 * Enables an omap_hwmod @oh such that the MPU can access the hwmod's
894 * register target. Must be called with omap_hwmod_mutex held. 1166 * register target. (This function has a full name --
895 * Returns -EINVAL if the hwmod is in the wrong state or passes along 1167 * _omap_hwmod_enable() rather than simply _enable() -- because it is
896 * the return value of _wait_target_ready(). 1168 * currently required by the pm34xx.c idle loop.) Returns -EINVAL if
1169 * the hwmod is in the wrong state or passes along the return value of
1170 * _wait_target_ready().
897 */ 1171 */
898int _omap_hwmod_enable(struct omap_hwmod *oh) 1172int _omap_hwmod_enable(struct omap_hwmod *oh)
899{ 1173{
@@ -909,6 +1183,15 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
909 1183
910 pr_debug("omap_hwmod: %s: enabling\n", oh->name); 1184 pr_debug("omap_hwmod: %s: enabling\n", oh->name);
911 1185
1186 /*
1187 * If an IP contains only one HW reset line, then de-assert it in order
1188 * to allow to enable the clocks. Otherwise the PRCM will return
1189 * Intransition status, and the init will failed.
1190 */
1191 if ((oh->_state == _HWMOD_STATE_INITIALIZED ||
1192 oh->_state == _HWMOD_STATE_DISABLED) && oh->rst_lines_cnt == 1)
1193 _deassert_hardreset(oh, oh->rst_lines[0].name);
1194
912 /* XXX mux balls */ 1195 /* XXX mux balls */
913 1196
914 _add_initiator_dep(oh, mpu_oh); 1197 _add_initiator_dep(oh, mpu_oh);
@@ -922,7 +1205,7 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
922 if (oh->class->sysc) { 1205 if (oh->class->sysc) {
923 if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) 1206 if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
924 _update_sysc_cache(oh); 1207 _update_sysc_cache(oh);
925 _sysc_enable(oh); 1208 _enable_sysc(oh);
926 } 1209 }
927 } else { 1210 } else {
928 pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", 1211 pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
@@ -933,12 +1216,14 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
933} 1216}
934 1217
935/** 1218/**
936 * _idle - idle an omap_hwmod 1219 * _omap_hwmod_idle - idle an omap_hwmod
937 * @oh: struct omap_hwmod * 1220 * @oh: struct omap_hwmod *
938 * 1221 *
939 * Idles an omap_hwmod @oh. This should be called once the hwmod has 1222 * Idles an omap_hwmod @oh. This should be called once the hwmod has
940 * no further work. Returns -EINVAL if the hwmod is in the wrong 1223 * no further work. (This function has a full name --
941 * state or returns 0. 1224 * _omap_hwmod_idle() rather than simply _idle() -- because it is
1225 * currently required by the pm34xx.c idle loop.) Returns -EINVAL if
1226 * the hwmod is in the wrong state or returns 0.
942 */ 1227 */
943int _omap_hwmod_idle(struct omap_hwmod *oh) 1228int _omap_hwmod_idle(struct omap_hwmod *oh)
944{ 1229{
@@ -951,7 +1236,7 @@ int _omap_hwmod_idle(struct omap_hwmod *oh)
951 pr_debug("omap_hwmod: %s: idling\n", oh->name); 1236 pr_debug("omap_hwmod: %s: idling\n", oh->name);
952 1237
953 if (oh->class->sysc) 1238 if (oh->class->sysc)
954 _sysc_idle(oh); 1239 _idle_sysc(oh);
955 _del_initiator_dep(oh, mpu_oh); 1240 _del_initiator_dep(oh, mpu_oh);
956 _disable_clocks(oh); 1241 _disable_clocks(oh);
957 1242
@@ -981,10 +1266,21 @@ static int _shutdown(struct omap_hwmod *oh)
981 pr_debug("omap_hwmod: %s: disabling\n", oh->name); 1266 pr_debug("omap_hwmod: %s: disabling\n", oh->name);
982 1267
983 if (oh->class->sysc) 1268 if (oh->class->sysc)
984 _sysc_shutdown(oh); 1269 _shutdown_sysc(oh);
985 _del_initiator_dep(oh, mpu_oh); 1270
986 /* XXX what about the other system initiators here? DMA, tesla, d2d */ 1271 /*
987 _disable_clocks(oh); 1272 * If an IP contains only one HW reset line, then assert it
1273 * before disabling the clocks and shutting down the IP.
1274 */
1275 if (oh->rst_lines_cnt == 1)
1276 _assert_hardreset(oh, oh->rst_lines[0].name);
1277
1278 /* clocks and deps are already disabled in idle */
1279 if (oh->_state == _HWMOD_STATE_ENABLED) {
1280 _del_initiator_dep(oh, mpu_oh);
1281 /* XXX what about the other system initiators here? dma, dsp */
1282 _disable_clocks(oh);
1283 }
988 /* XXX Should this code also force-disable the optional clocks? */ 1284 /* XXX Should this code also force-disable the optional clocks? */
989 1285
990 /* XXX mux any associated balls to safe mode */ 1286 /* XXX mux any associated balls to safe mode */
@@ -1000,11 +1296,10 @@ static int _shutdown(struct omap_hwmod *oh)
1000 * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1 1296 * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1
1001 * 1297 *
1002 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh 1298 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
1003 * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex held. 1299 * OCP_SYSCONFIG register. @skip_setup_idle is intended to be used on
1004 * @skip_setup_idle is intended to be used on a system that will not 1300 * a system that will not call omap_hwmod_enable() to enable devices
1005 * call omap_hwmod_enable() to enable devices (e.g., a system without 1301 * (e.g., a system without PM runtime). Returns -EINVAL if the hwmod
1006 * PM runtime). Returns -EINVAL if the hwmod is in the wrong state or 1302 * is in the wrong state or returns 0.
1007 * returns 0.
1008 */ 1303 */
1009static int _setup(struct omap_hwmod *oh, void *data) 1304static int _setup(struct omap_hwmod *oh, void *data)
1010{ 1305{
@@ -1034,8 +1329,19 @@ static int _setup(struct omap_hwmod *oh, void *data)
1034 } 1329 }
1035 } 1330 }
1036 1331
1332 mutex_init(&oh->_mutex);
1037 oh->_state = _HWMOD_STATE_INITIALIZED; 1333 oh->_state = _HWMOD_STATE_INITIALIZED;
1038 1334
1335 /*
1336 * In the case of hwmod with hardreset that should not be
1337 * de-assert at boot time, we have to keep the module
1338 * initialized, because we cannot enable it properly with the
1339 * reset asserted. Exit without warning because that behavior is
1340 * expected.
1341 */
1342 if ((oh->flags & HWMOD_INIT_NO_RESET) && oh->rst_lines_cnt == 1)
1343 return 0;
1344
1039 r = _omap_hwmod_enable(oh); 1345 r = _omap_hwmod_enable(oh);
1040 if (r) { 1346 if (r) {
1041 pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n", 1347 pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
@@ -1044,16 +1350,16 @@ static int _setup(struct omap_hwmod *oh, void *data)
1044 } 1350 }
1045 1351
1046 if (!(oh->flags & HWMOD_INIT_NO_RESET)) { 1352 if (!(oh->flags & HWMOD_INIT_NO_RESET)) {
1353 _reset(oh);
1354
1047 /* 1355 /*
1048 * XXX Do the OCP_SYSCONFIG bits need to be 1356 * OCP_SYSCONFIG bits need to be reprogrammed after a softreset.
1049 * reprogrammed after a reset? If not, then this can 1357 * The _omap_hwmod_enable() function should be split to
1050 * be removed. If they do, then probably the 1358 * avoid the rewrite of the OCP_SYSCONFIG register.
1051 * _omap_hwmod_enable() function should be split to avoid the
1052 * rewrite of the OCP_SYSCONFIG register.
1053 */ 1359 */
1054 if (oh->class->sysc) { 1360 if (oh->class->sysc) {
1055 _update_sysc_cache(oh); 1361 _update_sysc_cache(oh);
1056 _sysc_enable(oh); 1362 _enable_sysc(oh);
1057 } 1363 }
1058 } 1364 }
1059 1365
@@ -1309,7 +1615,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
1309 * omap_hwmod_enable - enable an omap_hwmod 1615 * omap_hwmod_enable - enable an omap_hwmod
1310 * @oh: struct omap_hwmod * 1616 * @oh: struct omap_hwmod *
1311 * 1617 *
1312 * Enable an omap_hwomd @oh. Intended to be called by omap_device_enable(). 1618 * Enable an omap_hwmod @oh. Intended to be called by omap_device_enable().
1313 * Returns -EINVAL on error or passes along the return value from _enable(). 1619 * Returns -EINVAL on error or passes along the return value from _enable().
1314 */ 1620 */
1315int omap_hwmod_enable(struct omap_hwmod *oh) 1621int omap_hwmod_enable(struct omap_hwmod *oh)
@@ -1319,9 +1625,9 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
1319 if (!oh) 1625 if (!oh)
1320 return -EINVAL; 1626 return -EINVAL;
1321 1627
1322 mutex_lock(&omap_hwmod_mutex); 1628 mutex_lock(&oh->_mutex);
1323 r = _omap_hwmod_enable(oh); 1629 r = _omap_hwmod_enable(oh);
1324 mutex_unlock(&omap_hwmod_mutex); 1630 mutex_unlock(&oh->_mutex);
1325 1631
1326 return r; 1632 return r;
1327} 1633}
@@ -1331,7 +1637,7 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
1331 * omap_hwmod_idle - idle an omap_hwmod 1637 * omap_hwmod_idle - idle an omap_hwmod
1332 * @oh: struct omap_hwmod * 1638 * @oh: struct omap_hwmod *
1333 * 1639 *
1334 * Idle an omap_hwomd @oh. Intended to be called by omap_device_idle(). 1640 * Idle an omap_hwmod @oh. Intended to be called by omap_device_idle().
1335 * Returns -EINVAL on error or passes along the return value from _idle(). 1641 * Returns -EINVAL on error or passes along the return value from _idle().
1336 */ 1642 */
1337int omap_hwmod_idle(struct omap_hwmod *oh) 1643int omap_hwmod_idle(struct omap_hwmod *oh)
@@ -1339,9 +1645,9 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
1339 if (!oh) 1645 if (!oh)
1340 return -EINVAL; 1646 return -EINVAL;
1341 1647
1342 mutex_lock(&omap_hwmod_mutex); 1648 mutex_lock(&oh->_mutex);
1343 _omap_hwmod_idle(oh); 1649 _omap_hwmod_idle(oh);
1344 mutex_unlock(&omap_hwmod_mutex); 1650 mutex_unlock(&oh->_mutex);
1345 1651
1346 return 0; 1652 return 0;
1347} 1653}
@@ -1350,7 +1656,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
1350 * omap_hwmod_shutdown - shutdown an omap_hwmod 1656 * omap_hwmod_shutdown - shutdown an omap_hwmod
1351 * @oh: struct omap_hwmod * 1657 * @oh: struct omap_hwmod *
1352 * 1658 *
1353 * Shutdown an omap_hwomd @oh. Intended to be called by 1659 * Shutdown an omap_hwmod @oh. Intended to be called by
1354 * omap_device_shutdown(). Returns -EINVAL on error or passes along 1660 * omap_device_shutdown(). Returns -EINVAL on error or passes along
1355 * the return value from _shutdown(). 1661 * the return value from _shutdown().
1356 */ 1662 */
@@ -1359,9 +1665,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
1359 if (!oh) 1665 if (!oh)
1360 return -EINVAL; 1666 return -EINVAL;
1361 1667
1362 mutex_lock(&omap_hwmod_mutex); 1668 mutex_lock(&oh->_mutex);
1363 _shutdown(oh); 1669 _shutdown(oh);
1364 mutex_unlock(&omap_hwmod_mutex); 1670 mutex_unlock(&oh->_mutex);
1365 1671
1366 return 0; 1672 return 0;
1367} 1673}
@@ -1374,9 +1680,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
1374 */ 1680 */
1375int omap_hwmod_enable_clocks(struct omap_hwmod *oh) 1681int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
1376{ 1682{
1377 mutex_lock(&omap_hwmod_mutex); 1683 mutex_lock(&oh->_mutex);
1378 _enable_clocks(oh); 1684 _enable_clocks(oh);
1379 mutex_unlock(&omap_hwmod_mutex); 1685 mutex_unlock(&oh->_mutex);
1380 1686
1381 return 0; 1687 return 0;
1382} 1688}
@@ -1389,9 +1695,9 @@ int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
1389 */ 1695 */
1390int omap_hwmod_disable_clocks(struct omap_hwmod *oh) 1696int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
1391{ 1697{
1392 mutex_lock(&omap_hwmod_mutex); 1698 mutex_lock(&oh->_mutex);
1393 _disable_clocks(oh); 1699 _disable_clocks(oh);
1394 mutex_unlock(&omap_hwmod_mutex); 1700 mutex_unlock(&oh->_mutex);
1395 1701
1396 return 0; 1702 return 0;
1397} 1703}
@@ -1430,20 +1736,18 @@ void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
1430 * 1736 *
1431 * Under some conditions, a driver may wish to reset the entire device. 1737 * Under some conditions, a driver may wish to reset the entire device.
1432 * Called from omap_device code. Returns -EINVAL on error or passes along 1738 * Called from omap_device code. Returns -EINVAL on error or passes along
1433 * the return value from _reset()/_enable(). 1739 * the return value from _reset().
1434 */ 1740 */
1435int omap_hwmod_reset(struct omap_hwmod *oh) 1741int omap_hwmod_reset(struct omap_hwmod *oh)
1436{ 1742{
1437 int r; 1743 int r;
1438 1744
1439 if (!oh || !(oh->_state & _HWMOD_STATE_ENABLED)) 1745 if (!oh)
1440 return -EINVAL; 1746 return -EINVAL;
1441 1747
1442 mutex_lock(&omap_hwmod_mutex); 1748 mutex_lock(&oh->_mutex);
1443 r = _reset(oh); 1749 r = _reset(oh);
1444 if (!r) 1750 mutex_unlock(&oh->_mutex);
1445 r = _omap_hwmod_enable(oh);
1446 mutex_unlock(&omap_hwmod_mutex);
1447 1751
1448 return r; 1752 return r;
1449} 1753}
@@ -1468,7 +1772,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh)
1468{ 1772{
1469 int ret, i; 1773 int ret, i;
1470 1774
1471 ret = oh->mpu_irqs_cnt + oh->sdma_chs_cnt; 1775 ret = oh->mpu_irqs_cnt + oh->sdma_reqs_cnt;
1472 1776
1473 for (i = 0; i < oh->slaves_cnt; i++) 1777 for (i = 0; i < oh->slaves_cnt; i++)
1474 ret += oh->slaves[i]->addr_cnt; 1778 ret += oh->slaves[i]->addr_cnt;
@@ -1501,10 +1805,10 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
1501 r++; 1805 r++;
1502 } 1806 }
1503 1807
1504 for (i = 0; i < oh->sdma_chs_cnt; i++) { 1808 for (i = 0; i < oh->sdma_reqs_cnt; i++) {
1505 (res + r)->name = (oh->sdma_chs + i)->name; 1809 (res + r)->name = (oh->sdma_reqs + i)->name;
1506 (res + r)->start = (oh->sdma_chs + i)->dma_ch; 1810 (res + r)->start = (oh->sdma_reqs + i)->dma_req;
1507 (res + r)->end = (oh->sdma_chs + i)->dma_ch; 1811 (res + r)->end = (oh->sdma_reqs + i)->dma_req;
1508 (res + r)->flags = IORESOURCE_DMA; 1812 (res + r)->flags = IORESOURCE_DMA;
1509 r++; 1813 r++;
1510 } 1814 }
@@ -1644,9 +1948,9 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
1644 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) 1948 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
1645 return -EINVAL; 1949 return -EINVAL;
1646 1950
1647 mutex_lock(&omap_hwmod_mutex); 1951 mutex_lock(&oh->_mutex);
1648 _enable_wakeup(oh); 1952 _enable_wakeup(oh);
1649 mutex_unlock(&omap_hwmod_mutex); 1953 mutex_unlock(&oh->_mutex);
1650 1954
1651 return 0; 1955 return 0;
1652} 1956}
@@ -1669,14 +1973,92 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
1669 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) 1973 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
1670 return -EINVAL; 1974 return -EINVAL;
1671 1975
1672 mutex_lock(&omap_hwmod_mutex); 1976 mutex_lock(&oh->_mutex);
1673 _disable_wakeup(oh); 1977 _disable_wakeup(oh);
1674 mutex_unlock(&omap_hwmod_mutex); 1978 mutex_unlock(&oh->_mutex);
1675 1979
1676 return 0; 1980 return 0;
1677} 1981}
1678 1982
1679/** 1983/**
1984 * omap_hwmod_assert_hardreset - assert the HW reset line of submodules
1985 * contained in the hwmod module.
1986 * @oh: struct omap_hwmod *
1987 * @name: name of the reset line to lookup and assert
1988 *
1989 * Some IP like dsp, ipu or iva contain processor that require
1990 * an HW reset line to be assert / deassert in order to enable fully
1991 * the IP. Returns -EINVAL if @oh is null or if the operation is not
1992 * yet supported on this OMAP; otherwise, passes along the return value
1993 * from _assert_hardreset().
1994 */
1995int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name)
1996{
1997 int ret;
1998
1999 if (!oh)
2000 return -EINVAL;
2001
2002 mutex_lock(&oh->_mutex);
2003 ret = _assert_hardreset(oh, name);
2004 mutex_unlock(&oh->_mutex);
2005
2006 return ret;
2007}
2008
2009/**
2010 * omap_hwmod_deassert_hardreset - deassert the HW reset line of submodules
2011 * contained in the hwmod module.
2012 * @oh: struct omap_hwmod *
2013 * @name: name of the reset line to look up and deassert
2014 *
2015 * Some IP like dsp, ipu or iva contain processor that require
2016 * an HW reset line to be assert / deassert in order to enable fully
2017 * the IP. Returns -EINVAL if @oh is null or if the operation is not
2018 * yet supported on this OMAP; otherwise, passes along the return value
2019 * from _deassert_hardreset().
2020 */
2021int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
2022{
2023 int ret;
2024
2025 if (!oh)
2026 return -EINVAL;
2027
2028 mutex_lock(&oh->_mutex);
2029 ret = _deassert_hardreset(oh, name);
2030 mutex_unlock(&oh->_mutex);
2031
2032 return ret;
2033}
2034
2035/**
2036 * omap_hwmod_read_hardreset - read the HW reset line state of submodules
2037 * contained in the hwmod module
2038 * @oh: struct omap_hwmod *
2039 * @name: name of the reset line to look up and read
2040 *
2041 * Return the current state of the hwmod @oh's reset line named @name:
2042 * returns -EINVAL upon parameter error or if this operation
2043 * is unsupported on the current OMAP; otherwise, passes along the return
2044 * value from _read_hardreset().
2045 */
2046int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name)
2047{
2048 int ret;
2049
2050 if (!oh)
2051 return -EINVAL;
2052
2053 mutex_lock(&oh->_mutex);
2054 ret = _read_hardreset(oh, name);
2055 mutex_unlock(&oh->_mutex);
2056
2057 return ret;
2058}
2059
2060
2061/**
1680 * omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname 2062 * omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname
1681 * @classname: struct omap_hwmod_class name to search for 2063 * @classname: struct omap_hwmod_class name to search for
1682 * @fn: callback function pointer to call for each hwmod in class @classname 2064 * @fn: callback function pointer to call for each hwmod in class @classname
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index c20137497c92..d4388d34c26a 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -33,6 +33,7 @@
33#include "cm.h" 33#include "cm.h"
34#include "prm.h" 34#include "prm.h"
35#include "prm-regbits-24xx.h" 35#include "prm-regbits-24xx.h"
36#include "prm-regbits-44xx.h"
36 37
37static void __iomem *prm_base; 38static void __iomem *prm_base;
38static void __iomem *cm_base; 39static void __iomem *cm_base;
@@ -161,8 +162,8 @@ void omap_prcm_arch_reset(char mode, const char *cmd)
161 prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs, 162 prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs,
162 OMAP2_RM_RSTCTRL); 163 OMAP2_RM_RSTCTRL);
163 if (cpu_is_omap44xx()) 164 if (cpu_is_omap44xx())
164 prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs, 165 prm_set_mod_reg_bits(OMAP4430_RST_GLOBAL_WARM_SW_MASK,
165 OMAP4_RM_RSTCTRL); 166 prcm_offs, OMAP4_RM_RSTCTRL);
166} 167}
167 168
168static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg) 169static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg)
@@ -215,6 +216,30 @@ u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
215 return v; 216 return v;
216} 217}
217 218
219/* Read a PRM register, AND it, and shift the result down to bit 0 */
220u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask)
221{
222 u32 v;
223
224 v = __raw_readl(reg);
225 v &= mask;
226 v >>= __ffs(mask);
227
228 return v;
229}
230
231/* Read-modify-write a register in a PRM module. Caller must lock */
232u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg)
233{
234 u32 v;
235
236 v = __raw_readl(reg);
237 v &= ~mask;
238 v |= bits;
239 __raw_writel(v, reg);
240
241 return v;
242}
218/* Read a register in a CM module */ 243/* Read a register in a CM module */
219u32 cm_read_mod_reg(s16 module, u16 idx) 244u32 cm_read_mod_reg(s16 module, u16 idx)
220{ 245{
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 588873b9303a..7be040b2fdab 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -5,7 +5,7 @@
5 * OMAP2/3 Power/Reset Management (PRM) register definitions 5 * OMAP2/3 Power/Reset Management (PRM) register definitions
6 * 6 *
7 * Copyright (C) 2007-2009 Texas Instruments, Inc. 7 * Copyright (C) 2007-2009 Texas Instruments, Inc.
8 * Copyright (C) 2009 Nokia Corporation 8 * Copyright (C) 2010 Nokia Corporation
9 * 9 *
10 * Written by Paul Walmsley 10 * Written by Paul Walmsley
11 * 11 *
@@ -246,6 +246,15 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
246 return prm_rmw_mod_reg_bits(bits, 0x0, module, idx); 246 return prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
247} 247}
248 248
249/* These omap2_ PRM functions apply to both OMAP2 and 3 */
250int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
251int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
252int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift);
253
254int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift);
255int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift);
256int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
257
249#endif 258#endif
250 259
251/* 260/*
@@ -398,4 +407,11 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
398#define OMAP_POWERSTATE_MASK (0x3 << 0) 407#define OMAP_POWERSTATE_MASK (0x3 << 0)
399 408
400 409
410/*
411 * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
412 * submodule to exit hardreset
413 */
414#define MAX_MODULE_HARDRESET_WAIT 10000
415
416
401#endif 417#endif
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
new file mode 100644
index 000000000000..421771eee450
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -0,0 +1,110 @@
1/*
2 * OMAP2/3 PRM module functions
3 *
4 * Copyright (C) 2010 Texas Instruments, Inc.
5 * Copyright (C) 2010 Nokia Corporation
6 * Benoît Cousson
7 * Paul Walmsley
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/delay.h>
16#include <linux/errno.h>
17#include <linux/err.h>
18
19#include <plat/common.h>
20#include <plat/cpu.h>
21#include <plat/prcm.h>
22
23#include "prm.h"
24#include "prm-regbits-24xx.h"
25#include "prm-regbits-34xx.h"
26
27/**
28 * omap2_prm_is_hardreset_asserted - read the HW reset line state of
29 * submodules contained in the hwmod module
30 * @prm_mod: PRM submodule base (e.g. CORE_MOD)
31 * @shift: register bit shift corresponding to the reset line to check
32 *
33 * Returns 1 if the (sub)module hardreset line is currently asserted,
34 * 0 if the (sub)module hardreset line is not currently asserted, or
35 * -EINVAL if called while running on a non-OMAP2/3 chip.
36 */
37int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
38{
39 if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
40 return -EINVAL;
41
42 return prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL,
43 (1 << shift));
44}
45
46/**
47 * omap2_prm_assert_hardreset - assert the HW reset line of a submodule
48 * @prm_mod: PRM submodule base (e.g. CORE_MOD)
49 * @shift: register bit shift corresponding to the reset line to assert
50 *
51 * Some IPs like dsp or iva contain processors that require an HW
52 * reset line to be asserted / deasserted in order to fully enable the
53 * IP. These modules may have multiple hard-reset lines that reset
54 * different 'submodules' inside the IP block. This function will
55 * place the submodule into reset. Returns 0 upon success or -EINVAL
56 * upon an argument error.
57 */
58int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
59{
60 u32 mask;
61
62 if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
63 return -EINVAL;
64
65 mask = 1 << shift;
66 prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL);
67
68 return 0;
69}
70
71/**
72 * omap2_prm_deassert_hardreset - deassert a submodule hardreset line and wait
73 * @prm_mod: PRM submodule base (e.g. CORE_MOD)
74 * @shift: register bit shift corresponding to the reset line to deassert
75 *
76 * Some IPs like dsp or iva contain processors that require an HW
77 * reset line to be asserted / deasserted in order to fully enable the
78 * IP. These modules may have multiple hard-reset lines that reset
79 * different 'submodules' inside the IP block. This function will
80 * take the submodule out of reset and wait until the PRCM indicates
81 * that the reset has completed before returning. Returns 0 upon success or
82 * -EINVAL upon an argument error, -EEXIST if the submodule was already out
83 * of reset, or -EBUSY if the submodule did not exit reset promptly.
84 */
85int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift)
86{
87 u32 mask;
88 int c;
89
90 if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
91 return -EINVAL;
92
93 mask = 1 << shift;
94
95 /* Check the current status to avoid de-asserting the line twice */
96 if (prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, mask) == 0)
97 return -EEXIST;
98
99 /* Clear the reset status by writing 1 to the status bit */
100 prm_rmw_mod_reg_bits(0xffffffff, mask, prm_mod, OMAP2_RM_RSTST);
101 /* de-assert the reset control line */
102 prm_rmw_mod_reg_bits(mask, 0, prm_mod, OMAP2_RM_RSTCTRL);
103 /* wait the status to be set */
104 omap_test_timeout(prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST,
105 mask),
106 MAX_MODULE_HARDRESET_WAIT, c);
107
108 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
109}
110
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
new file mode 100644
index 000000000000..a1ff918d9bed
--- /dev/null
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -0,0 +1,116 @@
1/*
2 * OMAP4 PRM module functions
3 *
4 * Copyright (C) 2010 Texas Instruments, Inc.
5 * Copyright (C) 2010 Nokia Corporation
6 * Benoît Cousson
7 * Paul Walmsley
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/delay.h>
16#include <linux/errno.h>
17#include <linux/err.h>
18
19#include <plat/common.h>
20#include <plat/cpu.h>
21#include <plat/prcm.h>
22
23#include "prm.h"
24#include "prm-regbits-44xx.h"
25
26/*
27 * Address offset (in bytes) between the reset control and the reset
28 * status registers: 4 bytes on OMAP4
29 */
30#define OMAP4_RST_CTRL_ST_OFFSET 4
31
32/**
33 * omap4_prm_is_hardreset_asserted - read the HW reset line state of
34 * submodules contained in the hwmod module
35 * @rstctrl_reg: RM_RSTCTRL register address for this module
36 * @shift: register bit shift corresponding to the reset line to check
37 *
38 * Returns 1 if the (sub)module hardreset line is currently asserted,
39 * 0 if the (sub)module hardreset line is not currently asserted, or
40 * -EINVAL upon parameter error.
41 */
42int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift)
43{
44 if (!cpu_is_omap44xx() || !rstctrl_reg)
45 return -EINVAL;
46
47 return omap4_prm_read_bits_shift(rstctrl_reg, (1 << shift));
48}
49
50/**
51 * omap4_prm_assert_hardreset - assert the HW reset line of a submodule
52 * @rstctrl_reg: RM_RSTCTRL register address for this module
53 * @shift: register bit shift corresponding to the reset line to assert
54 *
55 * Some IPs like dsp, ipu or iva contain processors that require an HW
56 * reset line to be asserted / deasserted in order to fully enable the
57 * IP. These modules may have multiple hard-reset lines that reset
58 * different 'submodules' inside the IP block. This function will
59 * place the submodule into reset. Returns 0 upon success or -EINVAL
60 * upon an argument error.
61 */
62int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift)
63{
64 u32 mask;
65
66 if (!cpu_is_omap44xx() || !rstctrl_reg)
67 return -EINVAL;
68
69 mask = 1 << shift;
70 omap4_prm_rmw_reg_bits(mask, mask, rstctrl_reg);
71
72 return 0;
73}
74
75/**
76 * omap4_prm_deassert_hardreset - deassert a submodule hardreset line and wait
77 * @rstctrl_reg: RM_RSTCTRL register address for this module
78 * @shift: register bit shift corresponding to the reset line to deassert
79 *
80 * Some IPs like dsp, ipu or iva contain processors that require an HW
81 * reset line to be asserted / deasserted in order to fully enable the
82 * IP. These modules may have multiple hard-reset lines that reset
83 * different 'submodules' inside the IP block. This function will
84 * take the submodule out of reset and wait until the PRCM indicates
85 * that the reset has completed before returning. Returns 0 upon success or
86 * -EINVAL upon an argument error, -EEXIST if the submodule was already out
87 * of reset, or -EBUSY if the submodule did not exit reset promptly.
88 */
89int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift)
90{
91 u32 mask;
92 void __iomem *rstst_reg;
93 int c;
94
95 if (!cpu_is_omap44xx() || !rstctrl_reg)
96 return -EINVAL;
97
98 rstst_reg = rstctrl_reg + OMAP4_RST_CTRL_ST_OFFSET;
99
100 mask = 1 << shift;
101
102 /* Check the current status to avoid de-asserting the line twice */
103 if (omap4_prm_read_bits_shift(rstctrl_reg, mask) == 0)
104 return -EEXIST;
105
106 /* Clear the reset status by writing 1 to the status bit */
107 omap4_prm_rmw_reg_bits(0xffffffff, mask, rstst_reg);
108 /* de-assert the reset control line */
109 omap4_prm_rmw_reg_bits(mask, 0, rstctrl_reg);
110 /* wait the status to be set */
111 omap_test_timeout(omap4_prm_read_bits_shift(rstst_reg, mask),
112 MAX_MODULE_HARDRESET_WAIT, c);
113
114 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
115}
116
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index a4e508dfaba2..72902814c3ca 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -14,19 +14,16 @@
14 * 14 *
15 * These headers and macros are used to define OMAP on-chip module 15 * These headers and macros are used to define OMAP on-chip module
16 * data and their integration with other OMAP modules and Linux. 16 * data and their integration with other OMAP modules and Linux.
17 * 17 * Copious documentation and references can also be found in the
18 * References: 18 * omap_hwmod code, in arch/arm/mach-omap2/omap_hwmod.c (as of this
19 * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064) 19 * writing).
20 * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
21 * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
22 * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
23 * - Open Core Protocol Specification 2.2
24 * 20 *
25 * To do: 21 * To do:
26 * - add interconnect error log structures 22 * - add interconnect error log structures
27 * - add pinmuxing 23 * - add pinmuxing
28 * - init_conn_id_bit (CONNID_BIT_VECTOR) 24 * - init_conn_id_bit (CONNID_BIT_VECTOR)
29 * - implement default hwmod SMS/SDRC flags? 25 * - implement default hwmod SMS/SDRC flags?
26 * - remove unused fields
30 * 27 *
31 */ 28 */
32#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H 29#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
@@ -35,6 +32,7 @@
35#include <linux/kernel.h> 32#include <linux/kernel.h>
36#include <linux/list.h> 33#include <linux/list.h>
37#include <linux/ioport.h> 34#include <linux/ioport.h>
35#include <linux/mutex.h>
38#include <plat/cpu.h> 36#include <plat/cpu.h>
39 37
40struct omap_device; 38struct omap_device;
@@ -96,7 +94,7 @@ struct omap_hwmod_irq_info {
96/** 94/**
97 * struct omap_hwmod_dma_info - DMA channels used by the hwmod 95 * struct omap_hwmod_dma_info - DMA channels used by the hwmod
98 * @name: name of the DMA channel (module local name) 96 * @name: name of the DMA channel (module local name)
99 * @dma_ch: DMA channel ID 97 * @dma_req: DMA request ID
100 * 98 *
101 * @name should be something short, e.g., "tx" or "rx". It is for use 99 * @name should be something short, e.g., "tx" or "rx". It is for use
102 * by platform_get_resource_byname(). It is defined locally to the 100 * by platform_get_resource_byname(). It is defined locally to the
@@ -104,7 +102,20 @@ struct omap_hwmod_irq_info {
104 */ 102 */
105struct omap_hwmod_dma_info { 103struct omap_hwmod_dma_info {
106 const char *name; 104 const char *name;
107 u16 dma_ch; 105 u16 dma_req;
106};
107
108/**
109 * struct omap_hwmod_rst_info - IPs reset lines use by hwmod
110 * @name: name of the reset line (module local name)
111 * @rst_shift: Offset of the reset bit
112 *
113 * @name should be something short, e.g., "cpu0" or "rst". It is defined
114 * locally to the hwmod.
115 */
116struct omap_hwmod_rst_info {
117 const char *name;
118 u8 rst_shift;
108}; 119};
109 120
110/** 121/**
@@ -237,8 +248,9 @@ struct omap_hwmod_ocp_if {
237#define SYSC_HAS_CLOCKACTIVITY (1 << 4) 248#define SYSC_HAS_CLOCKACTIVITY (1 << 4)
238#define SYSC_HAS_SIDLEMODE (1 << 5) 249#define SYSC_HAS_SIDLEMODE (1 << 5)
239#define SYSC_HAS_MIDLEMODE (1 << 6) 250#define SYSC_HAS_MIDLEMODE (1 << 6)
240#define SYSS_MISSING (1 << 7) 251#define SYSS_HAS_RESET_STATUS (1 << 7)
241#define SYSC_NO_CACHE (1 << 8) /* XXX SW flag, belongs elsewhere */ 252#define SYSC_NO_CACHE (1 << 8) /* XXX SW flag, belongs elsewhere */
253#define SYSC_HAS_RESET_STATUS (1 << 9)
242 254
243/* omap_hwmod_sysconfig.clockact flags */ 255/* omap_hwmod_sysconfig.clockact flags */
244#define CLOCKACT_TEST_BOTH 0x0 256#define CLOCKACT_TEST_BOTH 0x0
@@ -327,10 +339,12 @@ struct omap_hwmod_omap2_prcm {
327/** 339/**
328 * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data 340 * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
329 * @clkctrl_reg: PRCM address of the clock control register 341 * @clkctrl_reg: PRCM address of the clock control register
342 * @rstctrl_reg: adress of the XXX_RSTCTRL register located in the PRM
330 * @submodule_wkdep_bit: bit shift of the WKDEP range 343 * @submodule_wkdep_bit: bit shift of the WKDEP range
331 */ 344 */
332struct omap_hwmod_omap4_prcm { 345struct omap_hwmod_omap4_prcm {
333 void __iomem *clkctrl_reg; 346 void __iomem *clkctrl_reg;
347 void __iomem *rstctrl_reg;
334 u8 submodule_wkdep_bit; 348 u8 submodule_wkdep_bit;
335}; 349};
336 350
@@ -352,6 +366,10 @@ struct omap_hwmod_omap4_prcm {
352 * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup 366 * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
353 * HWMOD_NO_IDLEST : this module does not have idle status - this is the case 367 * HWMOD_NO_IDLEST : this module does not have idle status - this is the case
354 * only for few initiator modules on OMAP2 & 3. 368 * only for few initiator modules on OMAP2 & 3.
369 * HWMOD_CONTROL_OPT_CLKS_IN_RESET: Enable all optional clocks during reset.
370 * This is needed for devices like DSS that require optional clocks enabled
371 * in order to complete the reset. Optional clocks will be disabled
372 * again after the reset.
355 */ 373 */
356#define HWMOD_SWSUP_SIDLE (1 << 0) 374#define HWMOD_SWSUP_SIDLE (1 << 0)
357#define HWMOD_SWSUP_MSTANDBY (1 << 1) 375#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -360,6 +378,7 @@ struct omap_hwmod_omap4_prcm {
360#define HWMOD_NO_OCP_AUTOIDLE (1 << 4) 378#define HWMOD_NO_OCP_AUTOIDLE (1 << 4)
361#define HWMOD_SET_DEFAULT_CLOCKACT (1 << 5) 379#define HWMOD_SET_DEFAULT_CLOCKACT (1 << 5)
362#define HWMOD_NO_IDLEST (1 << 6) 380#define HWMOD_NO_IDLEST (1 << 6)
381#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
363 382
364/* 383/*
365 * omap_hwmod._int_flags definitions 384 * omap_hwmod._int_flags definitions
@@ -410,7 +429,7 @@ struct omap_hwmod_class {
410 * @class: struct omap_hwmod_class * to the class of this hwmod 429 * @class: struct omap_hwmod_class * to the class of this hwmod
411 * @od: struct omap_device currently associated with this hwmod (internal use) 430 * @od: struct omap_device currently associated with this hwmod (internal use)
412 * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt) 431 * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
413 * @sdma_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt) 432 * @sdma_reqs: ptr to an array of System DMA request IDs (see sdma_reqs_cnt)
414 * @prcm: PRCM data pertaining to this hwmod 433 * @prcm: PRCM data pertaining to this hwmod
415 * @main_clk: main clock: OMAP clock name 434 * @main_clk: main clock: OMAP clock name
416 * @_clk: pointer to the main struct clk (filled in at runtime) 435 * @_clk: pointer to the main struct clk (filled in at runtime)
@@ -424,7 +443,7 @@ struct omap_hwmod_class {
424 * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6) 443 * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
425 * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift 444 * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
426 * @mpu_irqs_cnt: number of @mpu_irqs 445 * @mpu_irqs_cnt: number of @mpu_irqs
427 * @sdma_chs_cnt: number of @sdma_chs 446 * @sdma_reqs_cnt: number of @sdma_reqs
428 * @opt_clks_cnt: number of @opt_clks 447 * @opt_clks_cnt: number of @opt_clks
429 * @master_cnt: number of @master entries 448 * @master_cnt: number of @master entries
430 * @slaves_cnt: number of @slave entries 449 * @slaves_cnt: number of @slave entries
@@ -433,6 +452,7 @@ struct omap_hwmod_class {
433 * @_state: internal-use hwmod state 452 * @_state: internal-use hwmod state
434 * @flags: hwmod flags (documented below) 453 * @flags: hwmod flags (documented below)
435 * @omap_chip: OMAP chips this hwmod is present on 454 * @omap_chip: OMAP chips this hwmod is present on
455 * @_mutex: mutex serializing operations on this hwmod
436 * @node: list node for hwmod list (internal use) 456 * @node: list node for hwmod list (internal use)
437 * 457 *
438 * @main_clk refers to this module's "main clock," which for our 458 * @main_clk refers to this module's "main clock," which for our
@@ -448,7 +468,8 @@ struct omap_hwmod {
448 struct omap_hwmod_class *class; 468 struct omap_hwmod_class *class;
449 struct omap_device *od; 469 struct omap_device *od;
450 struct omap_hwmod_irq_info *mpu_irqs; 470 struct omap_hwmod_irq_info *mpu_irqs;
451 struct omap_hwmod_dma_info *sdma_chs; 471 struct omap_hwmod_dma_info *sdma_reqs;
472 struct omap_hwmod_rst_info *rst_lines;
452 union { 473 union {
453 struct omap_hwmod_omap2_prcm omap2; 474 struct omap_hwmod_omap2_prcm omap2;
454 struct omap_hwmod_omap4_prcm omap4; 475 struct omap_hwmod_omap4_prcm omap4;
@@ -461,6 +482,7 @@ struct omap_hwmod {
461 void *dev_attr; 482 void *dev_attr;
462 u32 _sysc_cache; 483 u32 _sysc_cache;
463 void __iomem *_mpu_rt_va; 484 void __iomem *_mpu_rt_va;
485 struct mutex _mutex;
464 struct list_head node; 486 struct list_head node;
465 u16 flags; 487 u16 flags;
466 u8 _mpu_port_index; 488 u8 _mpu_port_index;
@@ -468,7 +490,8 @@ struct omap_hwmod {
468 u8 msuspendmux_shift; 490 u8 msuspendmux_shift;
469 u8 response_lat; 491 u8 response_lat;
470 u8 mpu_irqs_cnt; 492 u8 mpu_irqs_cnt;
471 u8 sdma_chs_cnt; 493 u8 sdma_reqs_cnt;
494 u8 rst_lines_cnt;
472 u8 opt_clks_cnt; 495 u8 opt_clks_cnt;
473 u8 masters_cnt; 496 u8 masters_cnt;
474 u8 slaves_cnt; 497 u8 slaves_cnt;
@@ -492,6 +515,10 @@ int omap_hwmod_idle(struct omap_hwmod *oh);
492int _omap_hwmod_idle(struct omap_hwmod *oh); 515int _omap_hwmod_idle(struct omap_hwmod *oh);
493int omap_hwmod_shutdown(struct omap_hwmod *oh); 516int omap_hwmod_shutdown(struct omap_hwmod *oh);
494 517
518int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name);
519int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name);
520int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name);
521
495int omap_hwmod_enable_clocks(struct omap_hwmod *oh); 522int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
496int omap_hwmod_disable_clocks(struct omap_hwmod *oh); 523int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
497 524
diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h
index 9fbd91419cd1..ab77442e42ab 100644
--- a/arch/arm/plat-omap/include/plat/prcm.h
+++ b/arch/arm/plat-omap/include/plat/prcm.h
@@ -38,6 +38,8 @@ u32 prm_read_mod_reg(s16 module, u16 idx);
38void prm_write_mod_reg(u32 val, s16 module, u16 idx); 38void prm_write_mod_reg(u32 val, s16 module, u16 idx);
39u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); 39u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
40u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask); 40u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
41u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask);
42u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg);
41u32 cm_read_mod_reg(s16 module, u16 idx); 43u32 cm_read_mod_reg(s16 module, u16 idx);
42void cm_write_mod_reg(u32 val, s16 module, u16 idx); 44void cm_write_mod_reg(u32 val, s16 module, u16 idx);
43u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); 45u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index d2b160942ccc..ceba58a47595 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -82,6 +82,7 @@
82#include <linux/slab.h> 82#include <linux/slab.h>
83#include <linux/err.h> 83#include <linux/err.h>
84#include <linux/io.h> 84#include <linux/io.h>
85#include <linux/clk.h>
85 86
86#include <plat/omap_device.h> 87#include <plat/omap_device.h>
87#include <plat/omap_hwmod.h> 88#include <plat/omap_hwmod.h>
@@ -243,6 +244,44 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
243 return container_of(pdev, struct omap_device, pdev); 244 return container_of(pdev, struct omap_device, pdev);
244} 245}
245 246
247/**
248 * _add_optional_clock_alias - Add clock alias for hwmod optional clocks
249 * @od: struct omap_device *od
250 *
251 * For every optional clock present per hwmod per omap_device, this function
252 * adds an entry in the clocks list of the form <dev-id=dev_name, con-id=role>
253 * if an entry is already present in it with the form <dev-id=NULL, con-id=role>
254 *
255 * The function is called from inside omap_device_build_ss(), after
256 * omap_device_register.
257 *
258 * This allows drivers to get a pointer to its optional clocks based on its role
259 * by calling clk_get(<dev*>, <role>).
260 *
261 * No return value.
262 */
263static void _add_optional_clock_alias(struct omap_device *od,
264 struct omap_hwmod *oh)
265{
266 int i;
267
268 for (i = 0; i < oh->opt_clks_cnt; i++) {
269 struct omap_hwmod_opt_clk *oc;
270 int r;
271
272 oc = &oh->opt_clks[i];
273
274 if (!oc->_clk)
275 continue;
276
277 r = clk_add_alias(oc->role, dev_name(&od->pdev.dev),
278 (char *)oc->clk, &od->pdev.dev);
279 if (r)
280 pr_err("omap_device: %s: clk_add_alias for %s failed\n",
281 dev_name(&od->pdev.dev), oc->role);
282 }
283}
284
246 285
247/* Public functions for use by core code */ 286/* Public functions for use by core code */
248 287
@@ -421,8 +460,10 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
421 else 460 else
422 ret = omap_device_register(od); 461 ret = omap_device_register(od);
423 462
424 for (i = 0; i < oh_cnt; i++) 463 for (i = 0; i < oh_cnt; i++) {
425 hwmods[i]->od = od; 464 hwmods[i]->od = od;
465 _add_optional_clock_alias(od, hwmods[i]);
466 }
426 467
427 if (ret) 468 if (ret)
428 goto odbs_exit4; 469 goto odbs_exit4;