diff options
author | Kevin Hilman <khilman@ti.com> | 2012-06-18 14:12:23 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2012-06-18 14:12:23 -0400 |
commit | 9ebfd285371835b1c0243d15aaacd72d5def76f8 (patch) | |
tree | ff0f3674a11b5a8e23c9eb4e800ca294bd5a7fcc /arch/arm/mach-omap2/omap_hwmod.c | |
parent | 3d9f032724e72851c6de38d026b2417501a2f240 (diff) |
ARM: OMAP2+: hwmod: use init-time function ptrs for enable/disable module
The enable/disable module functions are specific to SoCs with
OMAP4-class PRCM. Rather than use cpu_is* checks at runtime inside
the enable/disable module functions, use cpu_is at init time to
initialize function pointers only for SoCs that need them.
NOTE: the cpu_is* check for _enable_module was different than
the one for _disable_module, and this patch uses
cpu_is_omap44xx() for both.
Signed-off-by: Kevin Hilman <khilman@ti.com>
[paul@pwsan.com: moved soc_ops function pointers to be per-kernel rather than
per-hwmod since they do not vary by hwmod; added kerneldoc]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 939032a427fd..634a79836c64 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -166,6 +166,23 @@ | |||
166 | */ | 166 | */ |
167 | #define LINKS_PER_OCP_IF 2 | 167 | #define LINKS_PER_OCP_IF 2 |
168 | 168 | ||
169 | /** | ||
170 | * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations | ||
171 | * @enable_module: function to enable a module (via MODULEMODE) | ||
172 | * @disable_module: function to disable a module (via MODULEMODE) | ||
173 | * | ||
174 | * XXX Eventually this functionality will be hidden inside the PRM/CM | ||
175 | * device drivers. Until then, this should avoid huge blocks of cpu_is_*() | ||
176 | * conditionals in this code. | ||
177 | */ | ||
178 | struct omap_hwmod_soc_ops { | ||
179 | void (*enable_module)(struct omap_hwmod *oh); | ||
180 | int (*disable_module)(struct omap_hwmod *oh); | ||
181 | }; | ||
182 | |||
183 | /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ | ||
184 | static struct omap_hwmod_soc_ops soc_ops; | ||
185 | |||
169 | /* omap_hwmod_list contains all registered struct omap_hwmods */ | 186 | /* omap_hwmod_list contains all registered struct omap_hwmods */ |
170 | static LIST_HEAD(omap_hwmod_list); | 187 | static LIST_HEAD(omap_hwmod_list); |
171 | 188 | ||
@@ -186,6 +203,9 @@ static struct omap_hwmod_link *linkspace; | |||
186 | */ | 203 | */ |
187 | static unsigned short free_ls, max_ls, ls_supp; | 204 | static unsigned short free_ls, max_ls, ls_supp; |
188 | 205 | ||
206 | /* inited: set to true once the hwmod code is initialized */ | ||
207 | static bool inited; | ||
208 | |||
189 | /* Private functions */ | 209 | /* Private functions */ |
190 | 210 | ||
191 | /** | 211 | /** |
@@ -779,10 +799,6 @@ static void _disable_optional_clocks(struct omap_hwmod *oh) | |||
779 | */ | 799 | */ |
780 | static void _omap4_enable_module(struct omap_hwmod *oh) | 800 | static void _omap4_enable_module(struct omap_hwmod *oh) |
781 | { | 801 | { |
782 | /* The module mode does not exist prior OMAP4 */ | ||
783 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | ||
784 | return; | ||
785 | |||
786 | if (!oh->clkdm || !oh->prcm.omap4.modulemode) | 802 | if (!oh->clkdm || !oh->prcm.omap4.modulemode) |
787 | return; | 803 | return; |
788 | 804 | ||
@@ -1571,10 +1587,6 @@ static int _omap4_disable_module(struct omap_hwmod *oh) | |||
1571 | { | 1587 | { |
1572 | int v; | 1588 | int v; |
1573 | 1589 | ||
1574 | /* The module mode does not exist prior OMAP4 */ | ||
1575 | if (!cpu_is_omap44xx()) | ||
1576 | return -EINVAL; | ||
1577 | |||
1578 | if (!oh->clkdm || !oh->prcm.omap4.modulemode) | 1590 | if (!oh->clkdm || !oh->prcm.omap4.modulemode) |
1579 | return -EINVAL; | 1591 | return -EINVAL; |
1580 | 1592 | ||
@@ -1814,7 +1826,8 @@ static int _enable(struct omap_hwmod *oh) | |||
1814 | } | 1826 | } |
1815 | 1827 | ||
1816 | _enable_clocks(oh); | 1828 | _enable_clocks(oh); |
1817 | _omap4_enable_module(oh); | 1829 | if (soc_ops.enable_module) |
1830 | soc_ops.enable_module(oh); | ||
1818 | 1831 | ||
1819 | r = _wait_target_ready(oh); | 1832 | r = _wait_target_ready(oh); |
1820 | if (!r) { | 1833 | if (!r) { |
@@ -1870,7 +1883,8 @@ static int _idle(struct omap_hwmod *oh) | |||
1870 | _idle_sysc(oh); | 1883 | _idle_sysc(oh); |
1871 | _del_initiator_dep(oh, mpu_oh); | 1884 | _del_initiator_dep(oh, mpu_oh); |
1872 | 1885 | ||
1873 | _omap4_disable_module(oh); | 1886 | if (soc_ops.disable_module) |
1887 | soc_ops.disable_module(oh); | ||
1874 | 1888 | ||
1875 | /* | 1889 | /* |
1876 | * The module must be in idle mode before disabling any parents | 1890 | * The module must be in idle mode before disabling any parents |
@@ -1975,7 +1989,8 @@ static int _shutdown(struct omap_hwmod *oh) | |||
1975 | if (oh->_state == _HWMOD_STATE_ENABLED) { | 1989 | if (oh->_state == _HWMOD_STATE_ENABLED) { |
1976 | _del_initiator_dep(oh, mpu_oh); | 1990 | _del_initiator_dep(oh, mpu_oh); |
1977 | /* XXX what about the other system initiators here? dma, dsp */ | 1991 | /* XXX what about the other system initiators here? dma, dsp */ |
1978 | _omap4_disable_module(oh); | 1992 | if (soc_ops.disable_module) |
1993 | soc_ops.disable_module(oh); | ||
1979 | _disable_clocks(oh); | 1994 | _disable_clocks(oh); |
1980 | if (oh->clkdm) | 1995 | if (oh->clkdm) |
1981 | clkdm_hwmod_disable(oh->clkdm, oh); | 1996 | clkdm_hwmod_disable(oh->clkdm, oh); |
@@ -2563,12 +2578,18 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), | |||
2563 | * | 2578 | * |
2564 | * Intended to be called early in boot before the clock framework is | 2579 | * Intended to be called early in boot before the clock framework is |
2565 | * initialized. If @ois is not null, will register all omap_hwmods | 2580 | * initialized. If @ois is not null, will register all omap_hwmods |
2566 | * listed in @ois that are valid for this chip. Returns 0. | 2581 | * listed in @ois that are valid for this chip. Returns -EINVAL if |
2582 | * omap_hwmod_init() hasn't been called before calling this function, | ||
2583 | * -ENOMEM if the link memory area can't be allocated, or 0 upon | ||
2584 | * success. | ||
2567 | */ | 2585 | */ |
2568 | int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois) | 2586 | int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois) |
2569 | { | 2587 | { |
2570 | int r, i; | 2588 | int r, i; |
2571 | 2589 | ||
2590 | if (!inited) | ||
2591 | return -EINVAL; | ||
2592 | |||
2572 | if (!ois) | 2593 | if (!ois) |
2573 | return 0; | 2594 | return 0; |
2574 | 2595 | ||
@@ -3401,3 +3422,20 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx) | |||
3401 | 3422 | ||
3402 | return 0; | 3423 | return 0; |
3403 | } | 3424 | } |
3425 | |||
3426 | /** | ||
3427 | * omap_hwmod_init - initialize the hwmod code | ||
3428 | * | ||
3429 | * Sets up some function pointers needed by the hwmod code to operate on the | ||
3430 | * currently-booted SoC. Intended to be called once during kernel init | ||
3431 | * before any hwmods are registered. No return value. | ||
3432 | */ | ||
3433 | void __init omap_hwmod_init(void) | ||
3434 | { | ||
3435 | if (cpu_is_omap44xx()) { | ||
3436 | soc_ops.enable_module = _omap4_enable_module; | ||
3437 | soc_ops.disable_module = _omap4_disable_module; | ||
3438 | } | ||
3439 | |||
3440 | inited = true; | ||
3441 | } | ||