diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-23 17:43:53 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-23 17:43:53 -0700 |
commit | a5ebba6b54bc8038a38d3eacac3a79bbeaf3ee24 (patch) | |
tree | d36eb26a7efd4e00381bc9f6474ea3ec31340585 /arch/arm | |
parent | e81218f5f0fd219bd75768d845159ba4810bdd48 (diff) | |
parent | 6b21a9ce0402e0c5fd2adfa3d41328fdd8f55a9a (diff) |
Merge tag 'pm' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull arm-soc power management changes from Arnd Bergmann:
"These are various power management related changes, mainly concerning
cpuidle on i.MX and OMAP, as well as a the move of the omap
smartreflex driver to live in the power subsystem."
Fix up conflicts in arch/arm/mach-{imx/mach-imx6q.c,omap2/prm2xxx_3xxx.h}
* tag 'pm' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (37 commits)
ARM: OMAP2+: PM: fix IRQ_NOAUTOEN removal by mis-merge
ARM: OMAP2+: do not allow SmartReflex to be built as a module
ARM: OMAP2: Use hwmod to initialize mmc for 2420
ARM: OMAP3: PM: cpuidle: optimize the clkdm idle latency in C1 state
ARM: OMAP3: PM: cpuidle: optimize the PER latency in C1 state
ARM: OMAP3: PM: cpuidle: default to C1 in next_valid_state
ARM: OMAP3: PM: cleanup cam_pwrdm leftovers
ARM: OMAP3: PM: call pre/post transition per powerdomain
ARM: OMAP2+: powerdomain: allow pre/post transtion to be per pwrdm
ARM: OMAP3: PM: Remove IO Daisychain control from cpuidle
ARM: OMAP3PLUS: hwmod: reconfigure IO Daisychain during hwmod mux
ARM: OMAP3+: PRM: Enable IO wake up
ARM: OMAP4: PRM: Add IO Daisychain support
ARM: OMAP3: PM: Move IO Daisychain function to omap3 prm file
ARM: OMAP3: PM: correct enable/disable of daisy io chain
ARM: OMAP2+: PRM: fix compile for OMAP4-only build
W1: OMAP HDQ1W: use runtime PM
ARM: OMAP2+: HDQ1W: use omap_device
W1: OMAP HDQ1W: use 32-bit register accesses
W1: OMAP HDQ1W: allow driver to be built on all OMAP2+
...
Diffstat (limited to 'arch/arm')
40 files changed, 652 insertions, 1762 deletions
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index a2200c77bf7..4b89fae14a5 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -279,6 +279,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk_register_clkdev(clk[dummy], NULL, "imx-keypad"); clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0"); clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0"); + clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); /* Set SDHC parents to be PLL2 */ clk_set_parent(clk[esdhc_a_sel], clk[pll2_sw]); @@ -336,7 +337,6 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk_register_clkdev(clk[mx51_mipi], "mipi_hsp", NULL); clk_register_clkdev(clk[vpu_gate], NULL, "imx51-vpu.0"); clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0"); - clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); clk_register_clkdev(clk[ipu_gate], "bus", "imx51-ipu"); clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx51-ipu"); clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx51-ipu"); diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c index fdd90805d98..1b7a2fc3659 100644 --- a/arch/arm/mach-imx/imx53-dt.c +++ b/arch/arm/mach-imx/imx53-dt.c @@ -120,6 +120,7 @@ DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)") .handle_irq = imx53_handle_irq, .timer = &imx53_timer, .init_machine = imx53_dt_init, + .init_late = imx53_init_late, .dt_compat = imx53_dt_board_compat, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 426d2087c46..5ec0608f2a7 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -12,7 +12,9 @@ #include <linux/clk.h> #include <linux/clkdev.h> +#include <linux/cpuidle.h> #include <linux/delay.h> +#include <linux/export.h> #include <linux/init.h> #include <linux/io.h> #include <linux/irq.h> @@ -24,6 +26,7 @@ #include <linux/phy.h> #include <linux/micrel_phy.h> #include <linux/mfd/anatop.h> +#include <asm/cpuidle.h> #include <asm/smp_twd.h> #include <asm/hardware/cache-l2x0.h> #include <asm/hardware/gic.h> @@ -31,8 +34,10 @@ #include <asm/mach/time.h> #include <asm/system_misc.h> #include <mach/common.h> +#include <mach/cpuidle.h> #include <mach/hardware.h> + void imx6q_restart(char mode, const char *cmd) { struct device_node *np; @@ -169,6 +174,19 @@ static void __init imx6q_init_machine(void) imx6q_usb_init(); } +static struct cpuidle_driver imx6q_cpuidle_driver = { + .name = "imx6q_cpuidle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states[0] = ARM_CPUIDLE_WFI_STATE, + .state_count = 1, +}; + +static void __init imx6q_init_late(void) +{ + imx_cpuidle_init(&imx6q_cpuidle_driver); +} + static void __init imx6q_map_io(void) { imx_lluart_map_io(); @@ -213,6 +231,7 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") .handle_irq = imx6q_handle_irq, .timer = &imx6q_timer, .init_machine = imx6q_init_machine, + .init_late = imx6q_init_late, .dt_compat = imx6q_dt_compat, .restart = imx6q_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx53_ard.c b/arch/arm/mach-imx/mach-mx53_ard.c index f641a175869..6c28e65f424 100644 --- a/arch/arm/mach-imx/mach-mx53_ard.c +++ b/arch/arm/mach-imx/mach-mx53_ard.c @@ -267,5 +267,6 @@ MACHINE_START(MX53_ARD, "Freescale MX53 ARD Board") .handle_irq = imx53_handle_irq, .timer = &mx53_ard_timer, .init_machine = mx53_ard_board_init, + .init_late = imx53_init_late, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx53_evk.c b/arch/arm/mach-imx/mach-mx53_evk.c index a1060b26fb2..09fe2197b49 100644 --- a/arch/arm/mach-imx/mach-mx53_evk.c +++ b/arch/arm/mach-imx/mach-mx53_evk.c @@ -174,5 +174,6 @@ MACHINE_START(MX53_EVK, "Freescale MX53 EVK Board") .handle_irq = imx53_handle_irq, .timer = &mx53_evk_timer, .init_machine = mx53_evk_board_init, + .init_late = imx53_init_late, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx53_loco.c b/arch/arm/mach-imx/mach-mx53_loco.c index 388c415d6b6..8abe23c1d3c 100644 --- a/arch/arm/mach-imx/mach-mx53_loco.c +++ b/arch/arm/mach-imx/mach-mx53_loco.c @@ -316,5 +316,6 @@ MACHINE_START(MX53_LOCO, "Freescale MX53 LOCO Board") .handle_irq = imx53_handle_irq, .timer = &mx53_loco_timer, .init_machine = mx53_loco_board_init, + .init_late = imx53_init_late, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx53_smd.c b/arch/arm/mach-imx/mach-mx53_smd.c index f297df7ccb3..b15d6a6d3b6 100644 --- a/arch/arm/mach-imx/mach-mx53_smd.c +++ b/arch/arm/mach-imx/mach-mx53_smd.c @@ -163,5 +163,6 @@ MACHINE_START(MX53_SMD, "Freescale MX53 SMD Board") .handle_irq = imx53_handle_irq, .timer = &mx53_smd_timer, .init_machine = mx53_smd_board_init, + .init_late = imx53_init_late, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index 1d003053d56..f19d604e1b2 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -16,7 +16,6 @@ #include <linux/clk.h> #include <linux/pinctrl/machine.h> -#include <asm/system_misc.h> #include <asm/mach/map.h> #include <mach/hardware.h> @@ -24,24 +23,6 @@ #include <mach/devices-common.h> #include <mach/iomux-v3.h> -static struct clk *gpc_dvfs_clk; - -static void imx5_idle(void) -{ - /* gpc clock is needed for SRPG */ - if (gpc_dvfs_clk == NULL) { - gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); - if (IS_ERR(gpc_dvfs_clk)) - return; - clk_prepare(gpc_dvfs_clk); - } - clk_enable(gpc_dvfs_clk); - mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); - if (!tzic_enable_wake()) - cpu_do_idle(); - clk_disable(gpc_dvfs_clk); -} - /* * Define the MX50 memory map. */ @@ -105,7 +86,6 @@ void __init imx51_init_early(void) mxc_set_cpu_type(MXC_CPU_MX51); mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR)); - arm_pm_idle = imx5_idle; } void __init imx53_init_early(void) @@ -243,4 +223,10 @@ void __init imx53_soc_init(void) void __init imx51_init_late(void) { mx51_neon_fixup(); + imx51_pm_init(); +} + +void __init imx53_init_late(void) +{ + imx53_pm_init(); } diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index e26a9cb05ed..19621ed1ffa 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -12,19 +12,30 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/err.h> +#include <linux/export.h> #include <asm/cacheflush.h> +#include <asm/system_misc.h> #include <asm/tlbflush.h> #include <mach/common.h> +#include <mach/cpuidle.h> #include <mach/hardware.h> #include "crm-regs-imx5.h" -static struct clk *gpc_dvfs_clk; +/* + * The WAIT_UNCLOCKED_POWER_OFF state only requires <= 500ns to exit. + * This is also the lowest power state possible without affecting + * non-cpu parts of the system. For these reasons, imx5 should default + * to always using this state for cpu idling. The PM_SUSPEND_STANDBY also + * uses this state and needs to take no action when registers remain confgiured + * for this state. + */ +#define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF /* * set cpu low power mode before WFI instruction. This function is called * mx5 because it can be used for mx50, mx51, and mx53. */ -void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) +static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) { u32 plat_lpc, arm_srpgcr, ccm_clpcr; u32 empgc0, empgc1; @@ -87,11 +98,6 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) } } -static int mx5_suspend_prepare(void) -{ - return clk_prepare_enable(gpc_dvfs_clk); -} - static int mx5_suspend_enter(suspend_state_t state) { switch (state) { @@ -99,7 +105,7 @@ static int mx5_suspend_enter(suspend_state_t state) mx5_cpu_lp_set(STOP_POWER_OFF); break; case PM_SUSPEND_STANDBY: - mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); + /* DEFAULT_IDLE_STATE already configured */ break; default: return -EINVAL; @@ -114,12 +120,10 @@ static int mx5_suspend_enter(suspend_state_t state) __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); } cpu_do_idle(); - return 0; -} -static void mx5_suspend_finish(void) -{ - clk_disable_unprepare(gpc_dvfs_clk); + /* return registers to default idle state */ + mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); + return 0; } static int mx5_pm_valid(suspend_state_t state) @@ -129,25 +133,80 @@ static int mx5_pm_valid(suspend_state_t state) static const struct platform_suspend_ops mx5_suspend_ops = { .valid = mx5_pm_valid, - .prepare = mx5_suspend_prepare, .enter = mx5_suspend_enter, - .finish = mx5_suspend_finish, }; -static int __init mx5_pm_init(void) +static inline int imx5_cpu_do_idle(void) +{ + int ret = tzic_enable_wake(); + + if (likely(!ret)) + cpu_do_idle(); + + return ret; +} + +static void imx5_pm_idle(void) +{ + imx5_cpu_do_idle(); +} + +static int imx5_cpuidle_enter(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int idx) +{ + int ret; + + ret = imx5_cpu_do_idle(); + if (ret < 0) + return ret; + + return idx; +} + +static struct cpuidle_driver imx5_cpuidle_driver = { + .name = "imx5_cpuidle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states[0] = { + .enter = imx5_cpuidle_enter, + .exit_latency = 2, + .target_residency = 1, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "IMX5 SRPG", + .desc = "CPU state retained,powered off", + }, + .state_count = 1, +}; + +static int __init imx5_pm_common_init(void) { - if (!cpu_is_mx51() && !cpu_is_mx53()) - return 0; + int ret; + struct clk *gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); - if (gpc_dvfs_clk == NULL) - gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); + if (IS_ERR(gpc_dvfs_clk)) + return PTR_ERR(gpc_dvfs_clk); - if (!IS_ERR(gpc_dvfs_clk)) { - if (cpu_is_mx51()) - suspend_set_ops(&mx5_suspend_ops); - } else - return -EPERM; + ret = clk_prepare_enable(gpc_dvfs_clk); + if (ret) + return ret; + arm_pm_idle = imx5_pm_idle; + + /* Set the registers to the default cpu idle state. */ + mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); + + imx_cpuidle_init(&imx5_cpuidle_driver); return 0; } -device_initcall(mx5_pm_init); + +void __init imx51_pm_init(void) +{ + int ret = imx5_pm_common_init(); + if (!ret) + suspend_set_ops(&mx5_suspend_ops); +} + +void __init imx53_pm_init(void) +{ + imx5_pm_common_init(); +} diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 19b771d0c0d..b7a4ab65fac 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -74,8 +74,9 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o -obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o -obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o + +obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o +obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 31344528eb5..f2a49a48ef5 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -75,20 +75,6 @@ static struct omap3_idle_statedata omap3_idle_data[] = { static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; -static int _cpuidle_allow_idle(struct powerdomain *pwrdm, - struct clockdomain *clkdm) -{ - clkdm_allow_idle(clkdm); - return 0; -} - -static int _cpuidle_deny_idle(struct powerdomain *pwrdm, - struct clockdomain *clkdm) -{ - clkdm_deny_idle(clkdm); - return 0; -} - static int __omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) @@ -106,8 +92,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev, /* Deny idle for C1 */ if (index == 0) { - pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); - pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); + clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]); + clkdm_deny_idle(core_pd->pwrdm_clkdms[0]); } /* @@ -129,8 +115,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev, /* Re-allow idle for C1 */ if (index == 0) { - pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); - pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); + clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); + clkdm_allow_idle(core_pd->pwrdm_clkdms[0]); } return_sleep_time: @@ -176,7 +162,7 @@ static int next_valid_state(struct cpuidle_device *dev, u32 mpu_deepest_state = PWRDM_POWER_RET; u32 core_deepest_state = PWRDM_POWER_RET; int idx; - int next_index = -1; + int next_index = 0; /* C1 is the default value */ if (enable_off_mode) { mpu_deepest_state = PWRDM_POWER_OFF; @@ -207,12 +193,6 @@ static int next_valid_state(struct cpuidle_device *dev, } } - /* - * C1 is always valid. - * So, no need to check for 'next_index == -1' outside - * this loop. - */ - return next_index; } @@ -226,23 +206,22 @@ static int next_valid_state(struct cpuidle_device *dev, * the device to the specified or a safer state. */ static int omap3_enter_idle_bm(struct cpuidle_device *dev, - struct cpuidle_driver *drv, + struct cpuidle_driver *drv, int index) { int new_state_idx; - u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state; + u32 core_next_state, per_next_state = 0, per_saved_state = 0; struct omap3_idle_statedata *cx; int ret; /* - * Prevent idle completely if CAM is active. + * Use only C1 if CAM is active. * CAM does not have wakeup capability in OMAP3. */ - cam_state = pwrdm_read_pwrst(cam_pd); - if (cam_state == PWRDM_POWER_ON) { + if (pwrdm_read_pwrst(cam_pd) == PWRDM_POWER_ON) new_state_idx = drv->safe_state_index; - goto select_state; - } + else + new_state_idx = next_valid_state(dev, drv, index); /* * FIXME: we currently manage device-specific idle states @@ -252,24 +231,28 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, * its own code. */ - /* - * Prevent PER off if CORE is not in retention or off as this - * would disable PER wakeups completely. - */ - cx = &omap3_idle_data[index]; + /* Program PER state */ + cx = &omap3_idle_data[new_state_idx]; core_next_state = cx->core_state; per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); - if ((per_next_state == PWRDM_POWER_OFF) && - (core_next_state > PWRDM_POWER_RET)) - per_next_state = PWRDM_POWER_RET; + if (new_state_idx == 0) { + /* In C1 do not allow PER state lower than CORE state */ + if (per_next_state < core_next_state) + per_next_state = core_next_state; + } else { + /* + * Prevent PER OFF if CORE is not in RETention or OFF as this + * would disable PER wakeups completely. + */ + if ((per_next_state == PWRDM_POWER_OFF) && + (core_next_state > PWRDM_POWER_RET)) + per_next_state = PWRDM_POWER_RET; + } /* Are we changing PER target state? */ if (per_next_state != per_saved_state) pwrdm_set_next_pwrst(per_pd, per_next_state); - new_state_idx = next_valid_state(dev, drv, index); - -select_state: ret = omap3_enter_idle(dev, drv, new_state_idx); /* Restore original PER state if it was modified */ @@ -286,7 +269,7 @@ struct cpuidle_driver omap3_idle_driver = { .owner = THIS_MODULE, .states = { { - .enter = omap3_enter_idle, + .enter = omap3_enter_idle_bm, .exit_latency = 2 + 2, .target_residency = 5, .flags = CPUIDLE_FLAG_TIME_VALID, diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 71651e20a43..c00c68961bb 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -27,7 +27,6 @@ #include "iomap.h" #include <plat/board.h> -#include <plat/mmc.h> #include <plat/dma.h> #include <plat/omap_hwmod.h> #include <plat/omap_device.h> @@ -603,112 +602,6 @@ static inline void omap_init_aes(void) { } /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) - -static inline void omap242x_mmc_mux(struct omap_mmc_platform_data - *mmc_controller) -{ - if ((mmc_controller->slots[0].switch_pin > 0) && \ - (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) - omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, - OMAP_PIN_INPUT_PULLUP); - if ((mmc_controller->slots[0].gpio_wp > 0) && \ - (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) - omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, - OMAP_PIN_INPUT_PULLUP); - - omap_mux_init_signal("sdmmc_cmd", 0); - omap_mux_init_signal("sdmmc_clki", 0); - omap_mux_init_signal("sdmmc_clko", 0); - omap_mux_init_signal("sdmmc_dat0", 0); - omap_mux_init_signal("sdmmc_dat_dir0", 0); - omap_mux_init_signal("sdmmc_cmd_dir", 0); - if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) { - omap_mux_init_signal("sdmmc_dat1", 0); - omap_mux_init_signal("sdmmc_dat2", 0); - omap_mux_init_signal("sdmmc_dat3", 0); - omap_mux_init_signal("sdmmc_dat_dir1", 0); - omap_mux_init_signal("sdmmc_dat_dir2", 0); - omap_mux_init_signal("sdmmc_dat_dir3", 0); - } - - /* - * Use internal loop-back in MMC/SDIO Module Input Clock - * selection - */ - if (mmc_controller->slots[0].internal_clock) { - u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - v |= (1 << 24); - omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); - } -} - -void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) -{ - struct platform_device *pdev; - struct omap_hwmod *oh; - int id = 0; - char *oh_name = "msdi1"; - char *dev_name = "mmci-omap"; - - if (!mmc_data[0]) { - pr_err("%s fails: Incomplete platform data\n", __func__); - return; - } - - omap242x_mmc_mux(mmc_data[0]); - - oh = omap_hwmod_lookup(oh_name); - if (!oh) { - pr_err("Could not look up %s\n", oh_name); - return; - } - pdev = omap_device_build(dev_name, id, oh, mmc_data[0], - sizeof(struct omap_mmc_platform_data), NULL, 0, 0); - if (IS_ERR(pdev)) - WARN(1, "Can'd build omap_device for %s:%s.\n", - dev_name, oh->name); -} - -#endif - -/*-------------------------------------------------------------------------*/ - -#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) -#define OMAP_HDQ_BASE 0x480B2000 -static struct resource omap_hdq_resources[] = { - { - .start = OMAP_HDQ_BASE, - .end = OMAP_HDQ_BASE + 0x1C, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_24XX_HDQ_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; -static struct platform_device omap_hdq_dev = { - .name = "omap_hdq", - .id = 0, - .dev = { - .platform_data = NULL, - }, - .num_resources = ARRAY_SIZE(omap_hdq_resources), - .resource = omap_hdq_resources, -}; -static inline void omap_hdq_init(void) -{ - if (cpu_is_omap2420()) - return; - - platform_device_register(&omap_hdq_dev); -} -#else -static inline void omap_hdq_init(void) {} -#endif - -/*---------------------------------------------------------------------------*/ - #if defined(CONFIG_VIDEO_OMAP2_VOUT) || \ defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE) #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) @@ -753,7 +646,6 @@ static int __init omap2_init_devices(void) omap_init_mcspi(); } omap_init_pmu(); - omap_hdq_init(); omap_init_sti(); omap_init_sham(); omap_init_aes(); diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c index 297ebe03f09..cdd6dda0382 100644 --- a/arch/arm/mach-omap2/hdq1w.c +++ b/arch/arm/mach-omap2/hdq1w.c @@ -22,7 +22,13 @@ * 02110-1301 USA */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/platform_device.h> + #include <plat/omap_hwmod.h> +#include <plat/omap_device.h> #include <plat/hdq1w.h> #include "common.h" @@ -70,3 +76,23 @@ int omap_hdq1w_reset(struct omap_hwmod *oh) return 0; } + +static int __init omap_init_hdq(void) +{ + int id = -1; + struct platform_device *pdev; + struct omap_hwmod *oh; + char *oh_name = "hdq1w"; + char *devname = "omap_hdq"; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) + return 0; + + pdev = omap_device_build(devname, id, oh, NULL, 0, NULL, 0, 0); + WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", + devname, oh->name); + + return 0; +} +arch_initcall(omap_init_hdq); diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c index ef2a6924731..fb5bc6cf377 100644 --- a/arch/arm/mach-omap2/msdi.c +++ b/arch/arm/mach-omap2/msdi.c @@ -22,11 +22,15 @@ */ #include <linux/kernel.h> +#include <linux/err.h> #include <plat/omap_hwmod.h> +#include <plat/omap_device.h> #include <plat/mmc.h> #include "common.h" +#include "control.h" +#include "mux.h" /* * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register @@ -86,3 +90,72 @@ int omap_msdi_reset(struct omap_hwmod *oh) return 0; } + +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) + +static inline void omap242x_mmc_mux(struct omap_mmc_platform_data + *mmc_controller) +{ < |