diff options
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 38 |
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 */ |
| 173 | static struct omap_hwmod *mpu_oh; | 174 | static struct omap_hwmod *mpu_oh; |
| 174 | 175 | ||
| 176 | /* io_chain_lock: used to serialize reconfigurations of the I/O chain */ | ||
| 177 | static 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 | */ | ||
| 1756 | static 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 | ||
