aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2012-04-19 02:58:22 -0400
committerPaul Walmsley <paul@pwsan.com>2012-04-19 03:47:36 -0400
commit381d033a0164afaaac2a1c35bc8bc379052595b2 (patch)
treee93d9a16cc6b64f00dec85bf7a4bb6430f2062ea
parent30e105c000abbac55602b37f4831437bca5487b0 (diff)
ARM: OMAP2+: hwmod: reorganize and document the initialization process
Reorganize the code involved in initializing the internal data for each hwmod to make it easier to read and maintain. This involves improving documentation and removing some duplicated and unnecessary code. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: BenoƮt Cousson <b-cousson@ti.com>
-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 5b07ad0251d7..503832e20d56 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;