aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-23 20:43:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-23 20:43:53 -0400
commita5ebba6b54bc8038a38d3eacac3a79bbeaf3ee24 (patch)
treed36eb26a7efd4e00381bc9f6474ea3ec31340585 /arch/arm/mach-omap2/omap_hwmod.c
parente81218f5f0fd219bd75768d845159ba4810bdd48 (diff)
parent6b21a9ce0402e0c5fd2adfa3d41328fdd8f55a9a (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/mach-omap2/omap_hwmod.c')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 3f21568f1753..6ca8e519968d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -153,6 +153,7 @@
153#include "prm44xx.h" 153#include "prm44xx.h"
154#include "prminst44xx.h" 154#include "prminst44xx.h"
155#include "mux.h" 155#include "mux.h"
156#include "pm.h"
156 157
157/* Maximum microseconds to wait for OMAP module to softreset */ 158/* Maximum microseconds to wait for OMAP module to softreset */
158#define MAX_MODULE_SOFTRESET_WAIT 10000 159#define MAX_MODULE_SOFTRESET_WAIT 10000
@@ -197,6 +198,9 @@ static LIST_HEAD(omap_hwmod_list);
197/* mpu_oh: used to add/remove MPU initiator from sleepdep list */ 198/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
198static struct omap_hwmod *mpu_oh; 199static struct omap_hwmod *mpu_oh;
199 200
201/* io_chain_lock: used to serialize reconfigurations of the I/O chain */
202static DEFINE_SPINLOCK(io_chain_lock);
203
200/* 204/*
201 * linkspace: ptr to a buffer that struct omap_hwmod_link records are 205 * linkspace: ptr to a buffer that struct omap_hwmod_link records are
202 * allocated from - used to reduce the number of small memory 206 * allocated from - used to reduce the number of small memory
@@ -1759,6 +1763,32 @@ static int _reset(struct omap_hwmod *oh)
1759} 1763}
1760 1764
1761/** 1765/**
1766 * _reconfigure_io_chain - clear any I/O chain wakeups and reconfigure chain
1767 *
1768 * Call the appropriate PRM function to clear any logged I/O chain
1769 * wakeups and to reconfigure the chain. This apparently needs to be
1770 * done upon every mux change. Since hwmods can be concurrently
1771 * enabled and idled, hold a spinlock around the I/O chain
1772 * reconfiguration sequence. No return value.
1773 *
1774 * XXX When the PRM code is moved to drivers, this function can be removed,
1775 * as the PRM infrastructure should abstract this.
1776 */
1777static void _reconfigure_io_chain(void)
1778{
1779 unsigned long flags;
1780
1781 spin_lock_irqsave(&io_chain_lock, flags);
1782
1783 if (cpu_is_omap34xx() && omap3_has_io_chain_ctrl())
1784 omap3xxx_prm_reconfigure_io_chain();
1785 else if (cpu_is_omap44xx())
1786 omap44xx_prm_reconfigure_io_chain();
1787
1788 spin_unlock_irqrestore(&io_chain_lock, flags);
1789}
1790
1791/**
1762 * _enable - enable an omap_hwmod 1792 * _enable - enable an omap_hwmod
1763 * @oh: struct omap_hwmod * 1793 * @oh: struct omap_hwmod *
1764 * 1794 *
@@ -1814,8 +1844,10 @@ static int _enable(struct omap_hwmod *oh)
1814 /* Mux pins for device runtime if populated */ 1844 /* Mux pins for device runtime if populated */
1815 if (oh->mux && (!oh->mux->enabled || 1845 if (oh->mux && (!oh->mux->enabled ||
1816 ((oh->_state == _HWMOD_STATE_IDLE) && 1846 ((oh->_state == _HWMOD_STATE_IDLE) &&
1817 oh->mux->pads_dynamic))) 1847 oh->mux->pads_dynamic))) {
1818 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); 1848 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
1849 _reconfigure_io_chain();
1850 }
1819 1851
1820 _add_initiator_dep(oh, mpu_oh); 1852 _add_initiator_dep(oh, mpu_oh);
1821 1853
@@ -1907,8 +1939,10 @@ static int _idle(struct omap_hwmod *oh)
1907 clkdm_hwmod_disable(oh->clkdm, oh); 1939 clkdm_hwmod_disable(oh->clkdm, oh);
1908 1940
1909 /* Mux pins for device idle if populated */ 1941 /* Mux pins for device idle if populated */
1910 if (oh->mux && oh->mux->pads_dynamic) 1942 if (oh->mux && oh->mux->pads_dynamic) {
1911 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); 1943 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
1944 _reconfigure_io_chain();
1945 }
1912 1946
1913 oh->_state = _HWMOD_STATE_IDLE; 1947 oh->_state = _HWMOD_STATE_IDLE;
1914 1948