diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 4653efb87a27..c2c798c08c2b 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -139,6 +139,8 @@ | |||
139 | #include <linux/slab.h> | 139 | #include <linux/slab.h> |
140 | #include <linux/bootmem.h> | 140 | #include <linux/bootmem.h> |
141 | 141 | ||
142 | #include <asm/system_misc.h> | ||
143 | |||
142 | #include "clock.h" | 144 | #include "clock.h" |
143 | #include "omap_hwmod.h" | 145 | #include "omap_hwmod.h" |
144 | 146 | ||
@@ -2053,6 +2055,23 @@ static int _omap4_get_context_lost(struct omap_hwmod *oh) | |||
2053 | } | 2055 | } |
2054 | 2056 | ||
2055 | /** | 2057 | /** |
2058 | * _enable_preprogram - Pre-program an IP block during the _enable() process | ||
2059 | * @oh: struct omap_hwmod * | ||
2060 | * | ||
2061 | * Some IP blocks (such as AESS) require some additional programming | ||
2062 | * after enable before they can enter idle. If a function pointer to | ||
2063 | * do so is present in the hwmod data, then call it and pass along the | ||
2064 | * return value; otherwise, return 0. | ||
2065 | */ | ||
2066 | static int __init _enable_preprogram(struct omap_hwmod *oh) | ||
2067 | { | ||
2068 | if (!oh->class->enable_preprogram) | ||
2069 | return 0; | ||
2070 | |||
2071 | return oh->class->enable_preprogram(oh); | ||
2072 | } | ||
2073 | |||
2074 | /** | ||
2056 | * _enable - enable an omap_hwmod | 2075 | * _enable - enable an omap_hwmod |
2057 | * @oh: struct omap_hwmod * | 2076 | * @oh: struct omap_hwmod * |
2058 | * | 2077 | * |
@@ -2134,6 +2153,8 @@ static int _enable(struct omap_hwmod *oh) | |||
2134 | _enable_clocks(oh); | 2153 | _enable_clocks(oh); |
2135 | if (soc_ops.enable_module) | 2154 | if (soc_ops.enable_module) |
2136 | soc_ops.enable_module(oh); | 2155 | soc_ops.enable_module(oh); |
2156 | if (oh->flags & HWMOD_BLOCK_WFI) | ||
2157 | disable_hlt(); | ||
2137 | 2158 | ||
2138 | if (soc_ops.update_context_lost) | 2159 | if (soc_ops.update_context_lost) |
2139 | soc_ops.update_context_lost(oh); | 2160 | soc_ops.update_context_lost(oh); |
@@ -2156,6 +2177,7 @@ static int _enable(struct omap_hwmod *oh) | |||
2156 | _update_sysc_cache(oh); | 2177 | _update_sysc_cache(oh); |
2157 | _enable_sysc(oh); | 2178 | _enable_sysc(oh); |
2158 | } | 2179 | } |
2180 | r = _enable_preprogram(oh); | ||
2159 | } else { | 2181 | } else { |
2160 | if (soc_ops.disable_module) | 2182 | if (soc_ops.disable_module) |
2161 | soc_ops.disable_module(oh); | 2183 | soc_ops.disable_module(oh); |
@@ -2195,6 +2217,8 @@ static int _idle(struct omap_hwmod *oh) | |||
2195 | _idle_sysc(oh); | 2217 | _idle_sysc(oh); |
2196 | _del_initiator_dep(oh, mpu_oh); | 2218 | _del_initiator_dep(oh, mpu_oh); |
2197 | 2219 | ||
2220 | if (oh->flags & HWMOD_BLOCK_WFI) | ||
2221 | enable_hlt(); | ||
2198 | if (soc_ops.disable_module) | 2222 | if (soc_ops.disable_module) |
2199 | soc_ops.disable_module(oh); | 2223 | soc_ops.disable_module(oh); |
2200 | 2224 | ||
@@ -2303,6 +2327,8 @@ static int _shutdown(struct omap_hwmod *oh) | |||
2303 | if (oh->_state == _HWMOD_STATE_ENABLED) { | 2327 | if (oh->_state == _HWMOD_STATE_ENABLED) { |
2304 | _del_initiator_dep(oh, mpu_oh); | 2328 | _del_initiator_dep(oh, mpu_oh); |
2305 | /* XXX what about the other system initiators here? dma, dsp */ | 2329 | /* XXX what about the other system initiators here? dma, dsp */ |
2330 | if (oh->flags & HWMOD_BLOCK_WFI) | ||
2331 | enable_hlt(); | ||
2306 | if (soc_ops.disable_module) | 2332 | if (soc_ops.disable_module) |
2307 | soc_ops.disable_module(oh); | 2333 | soc_ops.disable_module(oh); |
2308 | _disable_clocks(oh); | 2334 | _disable_clocks(oh); |
@@ -3041,11 +3067,8 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh, | |||
3041 | static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, | 3067 | static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, |
3042 | struct omap_hwmod_rst_info *ohri) | 3068 | struct omap_hwmod_rst_info *ohri) |
3043 | { | 3069 | { |
3044 | if (ohri->st_shift) | ||
3045 | pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", | ||
3046 | oh->name, ohri->name); | ||
3047 | |||
3048 | return am33xx_prm_deassert_hardreset(ohri->rst_shift, | 3070 | return am33xx_prm_deassert_hardreset(ohri->rst_shift, |
3071 | ohri->st_shift, | ||
3049 | oh->clkdm->pwrdm.ptr->prcm_offs, | 3072 | oh->clkdm->pwrdm.ptr->prcm_offs, |
3050 | oh->prcm.omap4.rstctrl_offs, | 3073 | oh->prcm.omap4.rstctrl_offs, |
3051 | oh->prcm.omap4.rstst_offs); | 3074 | oh->prcm.omap4.rstst_offs); |
@@ -3303,7 +3326,7 @@ static int __init omap_hwmod_setup_all(void) | |||
3303 | 3326 | ||
3304 | return 0; | 3327 | return 0; |
3305 | } | 3328 | } |
3306 | core_initcall(omap_hwmod_setup_all); | 3329 | omap_core_initcall(omap_hwmod_setup_all); |
3307 | 3330 | ||
3308 | /** | 3331 | /** |
3309 | * omap_hwmod_enable - enable an omap_hwmod | 3332 | * omap_hwmod_enable - enable an omap_hwmod |