aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c137
1 files changed, 80 insertions, 57 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 5b07ad0251d..503832e20d5 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1769,6 +1769,56 @@ static int _shutdown(struct omap_hwmod *oh)
1769} 1769}
1770 1770
1771/** 1771/**
1772 * _init_mpu_rt_base - populate the virtual address for a hwmod
1773 * @oh: struct omap_hwmod * to locate the virtual address
1774 *
1775 * Cache the virtual address used by the MPU to access this IP block's
1776 * registers. This address is needed early so the OCP registers that
1777 * are part of the device's address space can be ioremapped properly.
1778 * No return value.
1779 */
1780static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
1781{
1782 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
1783 return;
1784
1785 oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
1786}
1787
1788/**
1789 * _init - initialize internal data for the hwmod @oh
1790 * @oh: struct omap_hwmod *
1791 * @n: (unused)
1792 *
1793 * Look up the clocks and the address space used by the MPU to access
1794 * registers belonging to the hwmod @oh. @oh must already be
1795 * registered at this point. This is the first of two phases for
1796 * hwmod initialization. Code called here does not touch any hardware
1797 * registers, it simply prepares internal data structures. Returns 0
1798 * upon success or if the hwmod isn't registered, or -EINVAL upon
1799 * failure.
1800 */
1801static int __init _init(struct omap_hwmod *oh, void *data)
1802{
1803 int r;
1804
1805 if (oh->_state != _HWMOD_STATE_REGISTERED)
1806 return 0;
1807
1808 _init_mpu_rt_base(oh, NULL);
1809
1810 r = _init_clocks(oh, NULL);
1811 if (IS_ERR_VALUE(r)) {
1812 WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name);
1813 return -EINVAL;
1814 }
1815
1816 oh->_state = _HWMOD_STATE_INITIALIZED;
1817
1818 return 0;
1819}
1820
1821/**
1772 * _setup - do initial configuration of omap_hwmod 1822 * _setup - do initial configuration of omap_hwmod
1773 * @oh: struct omap_hwmod * 1823 * @oh: struct omap_hwmod *
1774 * 1824 *
@@ -1780,7 +1830,7 @@ static int _setup(struct omap_hwmod *oh, void *data)
1780 int i, r; 1830 int i, r;
1781 u8 postsetup_state; 1831 u8 postsetup_state;
1782 1832
1783 if (oh->_state != _HWMOD_STATE_CLKS_INITED) 1833 if (oh->_state != _HWMOD_STATE_INITIALIZED)
1784 return 0; 1834 return 0;
1785 1835
1786 /* Set iclk autoidle mode */ 1836 /* Set iclk autoidle mode */
@@ -2052,96 +2102,69 @@ int __init omap_hwmod_register(struct omap_hwmod **ohs)
2052 return 0; 2102 return 0;
2053} 2103}
2054 2104
2055/* 2105/**
2056 * _populate_mpu_rt_base - populate the virtual address for a hwmod 2106 * _ensure_mpu_hwmod_is_setup - ensure the MPU SS hwmod is init'ed and set up
2107 * @oh: pointer to the hwmod currently being set up (usually not the MPU)
2057 * 2108 *
2058 * Must be called only from omap_hwmod_setup_*() so ioremap works properly. 2109 * If the hwmod data corresponding to the MPU subsystem IP block
2059 * Assumes the caller takes care of locking if needed. 2110 * hasn't been initialized and set up yet, do so now. This must be
2111 * done first since sleep dependencies may be added from other hwmods
2112 * to the MPU. Intended to be called only by omap_hwmod_setup*(). No
2113 * return value.
2060 */ 2114 */
2061static int __init _populate_mpu_rt_base(struct omap_hwmod *oh, void *data) 2115static void __init _ensure_mpu_hwmod_is_setup(struct omap_hwmod *oh)
2062{ 2116{
2063 if (oh->_state != _HWMOD_STATE_REGISTERED) 2117 if (!mpu_oh || mpu_oh->_state == _HWMOD_STATE_UNKNOWN)
2064 return 0; 2118 pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n",
2065 2119 __func__, MPU_INITIATOR_NAME);
2066 if (oh->_int_flags & _HWMOD_NO_MPU_PORT) 2120 else if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh)
2067 return 0; 2121 omap_hwmod_setup_one(MPU_INITIATOR_NAME);
2068
2069 oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
2070
2071 return 0;
2072} 2122}
2073 2123
2074/** 2124/**
2075 * omap_hwmod_setup_one - set up a single hwmod 2125 * omap_hwmod_setup_one - set up a single hwmod
2076 * @oh_name: const char * name of the already-registered hwmod to set up 2126 * @oh_name: const char * name of the already-registered hwmod to set up
2077 * 2127 *
2078 * Must be called after omap2_clk_init(). Resolves the struct clk 2128 * Initialize and set up a single hwmod. Intended to be used for a
2079 * names to struct clk pointers for each registered omap_hwmod. Also 2129 * small number of early devices, such as the timer IP blocks used for
2080 * calls _setup() on each hwmod. Returns -EINVAL upon error or 0 upon 2130 * the scheduler clock. Must be called after omap2_clk_init().
2081 * success. 2131 * Resolves the struct clk names to struct clk pointers for each
2132 * registered omap_hwmod. Also calls _setup() on each hwmod. Returns
2133 * -EINVAL upon error or 0 upon success.
2082 */ 2134 */
2083int __init omap_hwmod_setup_one(const char *oh_name) 2135int __init omap_hwmod_setup_one(const char *oh_name)
2084{ 2136{
2085 struct omap_hwmod *oh; 2137 struct omap_hwmod *oh;
2086 int r;
2087 2138
2088 pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__); 2139 pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__);
2089 2140
2090 if (!mpu_oh) {
2091 pr_err("omap_hwmod: %s: cannot setup_one: MPU initiator hwmod %s not yet registered\n",
2092 oh_name, MPU_INITIATOR_NAME);
2093 return -EINVAL;
2094 }
2095
2096 oh = _lookup(oh_name); 2141 oh = _lookup(oh_name);
2097 if (!oh) { 2142 if (!oh) {
2098 WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name); 2143 WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name);
2099 return -EINVAL; 2144 return -EINVAL;
2100 } 2145 }
2101 2146
2102 if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh) 2147 _ensure_mpu_hwmod_is_setup(oh);
2103 omap_hwmod_setup_one(MPU_INITIATOR_NAME);
2104
2105 r = _populate_mpu_rt_base(oh, NULL);
2106 if (IS_ERR_VALUE(r)) {
2107 WARN(1, "omap_hwmod: %s: couldn't set mpu_rt_base\n", oh_name);
2108 return -EINVAL;
2109 }
2110
2111 r = _init_clocks(oh, NULL);
2112 if (IS_ERR_VALUE(r)) {
2113 WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh_name);
2114 return -EINVAL;
2115 }
2116 2148
2149 _init(oh, NULL);
2117 _setup(oh, NULL); 2150 _setup(oh, NULL);
2118 2151
2119 return 0; 2152 return 0;
2120} 2153}
2121 2154
2122/** 2155/**
2123 * omap_hwmod_setup - do some post-clock framework initialization 2156 * omap_hwmod_setup_all - set up all registered IP blocks
2124 * 2157 *
2125 * Must be called after omap2_clk_init(). Resolves the struct clk names 2158 * Initialize and set up all IP blocks registered with the hwmod code.
2126 * to struct clk pointers for each registered omap_hwmod. Also calls 2159 * Must be called after omap2_clk_init(). Resolves the struct clk
2127 * _setup() on each hwmod. Returns 0 upon success. 2160 * names to struct clk pointers for each registered omap_hwmod. Also
2161 * calls _setup() on each hwmod. Returns 0 upon success.
2128 */ 2162 */
2129static int __init omap_hwmod_setup_all(void) 2163static int __init omap_hwmod_setup_all(void)
2130{ 2164{
2131 int r; 2165 _ensure_mpu_hwmod_is_setup(NULL);
2132
2133 if (!mpu_oh) {
2134 pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n",
2135 __func__, MPU_INITIATOR_NAME);
2136 return -EINVAL;
2137 }
2138
2139 r = omap_hwmod_for_each(_populate_mpu_rt_base, NULL);
2140
2141 r = omap_hwmod_for_each(_init_clocks, NULL);
2142 WARN(IS_ERR_VALUE(r),
2143 "omap_hwmod: %s: _init_clocks failed\n", __func__);
2144 2166
2167 omap_hwmod_for_each(_init, NULL);
2145 omap_hwmod_for_each(_setup, NULL); 2168 omap_hwmod_for_each(_setup, NULL);
2146 2169
2147 return 0; 2170 return 0;