aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 bf86f7e8f91f..6d6c31a10a1b 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
@@ -172,6 +173,9 @@ static LIST_HEAD(omap_hwmod_list);
172/* mpu_oh: used to add/remove MPU initiator from sleepdep list */ 173/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
173static struct omap_hwmod *mpu_oh; 174static struct omap_hwmod *mpu_oh;
174 175
176/* io_chain_lock: used to serialize reconfigurations of the I/O chain */
177static DEFINE_SPINLOCK(io_chain_lock);
178
175/* 179/*
176 * linkspace: ptr to a buffer that struct omap_hwmod_link records are 180 * linkspace: ptr to a buffer that struct omap_hwmod_link records are
177 * allocated from - used to reduce the number of small memory 181 * allocated from - used to reduce the number of small memory
@@ -1738,6 +1742,32 @@ static int _reset(struct omap_hwmod *oh)
1738} 1742}
1739 1743
1740/** 1744/**
1745 * _reconfigure_io_chain - clear any I/O chain wakeups and reconfigure chain
1746 *
1747 * Call the appropriate PRM function to clear any logged I/O chain
1748 * wakeups and to reconfigure the chain. This apparently needs to be
1749 * done upon every mux change. Since hwmods can be concurrently
1750 * enabled and idled, hold a spinlock around the I/O chain
1751 * reconfiguration sequence. No return value.
1752 *
1753 * XXX When the PRM code is moved to drivers, this function can be removed,
1754 * as the PRM infrastructure should abstract this.
1755 */
1756static void _reconfigure_io_chain(void)
1757{
1758 unsigned long flags;
1759
1760 spin_lock_irqsave(&io_chain_lock, flags);
1761
1762 if (cpu_is_omap34xx() && omap3_has_io_chain_ctrl())
1763 omap3xxx_prm_reconfigure_io_chain();
1764 else if (cpu_is_omap44xx())
1765 omap44xx_prm_reconfigure_io_chain();
1766
1767 spin_unlock_irqrestore(&io_chain_lock, flags);
1768}
1769
1770/**
1741 * _enable - enable an omap_hwmod 1771 * _enable - enable an omap_hwmod
1742 * @oh: struct omap_hwmod * 1772 * @oh: struct omap_hwmod *
1743 * 1773 *
@@ -1793,8 +1823,10 @@ static int _enable(struct omap_hwmod *oh)
1793 /* Mux pins for device runtime if populated */ 1823 /* Mux pins for device runtime if populated */
1794 if (oh->mux && (!oh->mux->enabled || 1824 if (oh->mux && (!oh->mux->enabled ||
1795 ((oh->_state == _HWMOD_STATE_IDLE) && 1825 ((oh->_state == _HWMOD_STATE_IDLE) &&
1796 oh->mux->pads_dynamic))) 1826 oh->mux->pads_dynamic))) {
1797 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); 1827 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
1828 _reconfigure_io_chain();
1829 }
1798 1830
1799 _add_initiator_dep(oh, mpu_oh); 1831 _add_initiator_dep(oh, mpu_oh);
1800 1832
@@ -1883,8 +1915,10 @@ static int _idle(struct omap_hwmod *oh)
1883 clkdm_hwmod_disable(oh->clkdm, oh); 1915 clkdm_hwmod_disable(oh->clkdm, oh);
1884 1916
1885 /* Mux pins for device idle if populated */ 1917 /* Mux pins for device idle if populated */
1886 if (oh->mux && oh->mux->pads_dynamic) 1918 if (oh->mux && oh->mux->pads_dynamic) {
1887 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); 1919 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
1920 _reconfigure_io_chain();
1921 }
1888 1922
1889 oh->_state = _HWMOD_STATE_IDLE; 1923 oh->_state = _HWMOD_STATE_IDLE;
1890 1924