Skip to content

Commit 64813c3

Browse files
author
Paul Walmsley
committed
ARM: OMAP2+: hwmod: reorganize and document the reset and configuration process
Reorganize the code involved in resetting and configuring an IP block to make it easier to read and maintain. This involves improving documentation, splitting some large functions up into smaller ones to better conform with Documentation/CodingStyle, and removing some unnecessary code. Signed-off-by: Paul Walmsley <[email protected]> Cc: Benoît Cousson <[email protected]>
1 parent 381d033 commit 64813c3

File tree

1 file changed

+120
-32
lines changed

1 file changed

+120
-32
lines changed

arch/arm/mach-omap2/omap_hwmod.c

Lines changed: 120 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,10 +1534,9 @@ static int _enable(struct omap_hwmod *oh)
15341534
pr_debug("omap_hwmod: %s: enabling\n", oh->name);
15351535

15361536
/*
1537-
* hwmods with HWMOD_INIT_NO_IDLE flag set are left
1538-
* in enabled state at init.
1539-
* Now that someone is really trying to enable them,
1540-
* just ensure that the hwmod mux is set.
1537+
* hwmods with HWMOD_INIT_NO_IDLE flag set are left in enabled
1538+
* state at init. Now that someone is really trying to enable
1539+
* them, just ensure that the hwmod mux is set.
15411540
*/
15421541
if (oh->_int_flags & _HWMOD_SKIP_ENABLE) {
15431542
/*
@@ -1819,46 +1818,60 @@ static int __init _init(struct omap_hwmod *oh, void *data)
18191818
}
18201819

18211820
/**
1822-
* _setup - do initial configuration of omap_hwmod
1821+
* _setup_iclk_autoidle - configure an IP block's interface clocks
18231822
* @oh: struct omap_hwmod *
18241823
*
1825-
* Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
1826-
* OCP_SYSCONFIG register. Returns 0.
1824+
* Set up the module's interface clocks. XXX This function is still mostly
1825+
* a stub; implementing this properly requires iclk autoidle usecounting in
1826+
* the clock code. No return value.
18271827
*/
1828-
static int _setup(struct omap_hwmod *oh, void *data)
1828+
static void __init _setup_iclk_autoidle(struct omap_hwmod *oh)
18291829
{
1830-
int i, r;
1831-
u8 postsetup_state;
1830+
int i;
18321831

18331832
if (oh->_state != _HWMOD_STATE_INITIALIZED)
1834-
return 0;
1833+
return;
18351834

1836-
/* Set iclk autoidle mode */
1837-
if (oh->slaves_cnt > 0) {
1838-
for (i = 0; i < oh->slaves_cnt; i++) {
1839-
struct omap_hwmod_ocp_if *os = oh->slaves[i];
1840-
struct clk *c = os->_clk;
1835+
for (i = 0; i < oh->slaves_cnt; i++) {
1836+
struct omap_hwmod_ocp_if *os = oh->slaves[i];
1837+
struct clk *c = os->_clk;
18411838

1842-
if (!c)
1843-
continue;
1839+
if (!c)
1840+
continue;
18441841

1845-
if (os->flags & OCPIF_SWSUP_IDLE) {
1846-
/* XXX omap_iclk_deny_idle(c); */
1847-
} else {
1848-
/* XXX omap_iclk_allow_idle(c); */
1849-
clk_enable(c);
1850-
}
1842+
if (os->flags & OCPIF_SWSUP_IDLE) {
1843+
/* XXX omap_iclk_deny_idle(c); */
1844+
} else {
1845+
/* XXX omap_iclk_allow_idle(c); */
1846+
clk_enable(c);
18511847
}
18521848
}
18531849

1854-
oh->_state = _HWMOD_STATE_INITIALIZED;
1850+
return;
1851+
}
1852+
1853+
/**
1854+
* _setup_reset - reset an IP block during the setup process
1855+
* @oh: struct omap_hwmod *
1856+
*
1857+
* Reset the IP block corresponding to the hwmod @oh during the setup
1858+
* process. The IP block is first enabled so it can be successfully
1859+
* reset. Returns 0 upon success or a negative error code upon
1860+
* failure.
1861+
*/
1862+
static int __init _setup_reset(struct omap_hwmod *oh)
1863+
{
1864+
int r;
1865+
1866+
if (oh->_state != _HWMOD_STATE_INITIALIZED)
1867+
return -EINVAL;
18551868

18561869
/*
18571870
* In the case of hwmod with hardreset that should not be
18581871
* de-assert at boot time, we have to keep the module
18591872
* initialized, because we cannot enable it properly with the
1860-
* reset asserted. Exit without warning because that behavior is
1861-
* expected.
1873+
* reset asserted. Exit without warning because that behavior
1874+
* is expected.
18621875
*/
18631876
if ((oh->flags & HWMOD_INIT_NO_RESET) && oh->rst_lines_cnt > 0)
18641877
return 0;
@@ -1871,7 +1884,53 @@ static int _setup(struct omap_hwmod *oh, void *data)
18711884
}
18721885

18731886
if (!(oh->flags & HWMOD_INIT_NO_RESET))
1874-
_reset(oh);
1887+
r = _reset(oh);
1888+
1889+
return r;
1890+
}
1891+
1892+
/**
1893+
* _setup_postsetup - transition to the appropriate state after _setup
1894+
* @oh: struct omap_hwmod *
1895+
*
1896+
* Place an IP block represented by @oh into a "post-setup" state --
1897+
* either IDLE, ENABLED, or DISABLED. ("post-setup" simply means that
1898+
* this function is called at the end of _setup().) The postsetup
1899+
* state for an IP block can be changed by calling
1900+
* omap_hwmod_enter_postsetup_state() early in the boot process,
1901+
* before one of the omap_hwmod_setup*() functions are called for the
1902+
* IP block.
1903+
*
1904+
* The IP block stays in this state until a PM runtime-based driver is
1905+
* loaded for that IP block. A post-setup state of IDLE is
1906+
* appropriate for almost all IP blocks with runtime PM-enabled
1907+
* drivers, since those drivers are able to enable the IP block. A
1908+
* post-setup state of ENABLED is appropriate for kernels with PM
1909+
* runtime disabled. The DISABLED state is appropriate for unusual IP
1910+
* blocks such as the MPU WDTIMER on kernels without WDTIMER drivers
1911+
* included, since the WDTIMER starts running on reset and will reset
1912+
* the MPU if left active.
1913+
*
1914+
* This post-setup mechanism is deprecated. Once all of the OMAP
1915+
* drivers have been converted to use PM runtime, and all of the IP
1916+
* block data and interconnect data is available to the hwmod code, it
1917+
* should be possible to replace this mechanism with a "lazy reset"
1918+
* arrangement. In a "lazy reset" setup, each IP block is enabled
1919+
* when the driver first probes, then all remaining IP blocks without
1920+
* drivers are either shut down or enabled after the drivers have
1921+
* loaded. However, this cannot take place until the above
1922+
* preconditions have been met, since otherwise the late reset code
1923+
* has no way of knowing which IP blocks are in use by drivers, and
1924+
* which ones are unused.
1925+
*
1926+
* No return value.
1927+
*/
1928+
static void __init _setup_postsetup(struct omap_hwmod *oh)
1929+
{
1930+
u8 postsetup_state;
1931+
1932+
if (oh->rst_lines_cnt > 0)
1933+
return;
18751934

18761935
postsetup_state = oh->_postsetup_state;
18771936
if (postsetup_state == _HWMOD_STATE_UNKNOWN)
@@ -1895,6 +1954,35 @@ static int _setup(struct omap_hwmod *oh, void *data)
18951954
WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
18961955
oh->name, postsetup_state);
18971956

1957+
return;
1958+
}
1959+
1960+
/**
1961+
* _setup - prepare IP block hardware for use
1962+
* @oh: struct omap_hwmod *
1963+
* @n: (unused, pass NULL)
1964+
*
1965+
* Configure the IP block represented by @oh. This may include
1966+
* enabling the IP block, resetting it, and placing it into a
1967+
* post-setup state, depending on the type of IP block and applicable
1968+
* flags. IP blocks are reset to prevent any previous configuration
1969+
* by the bootloader or previous operating system from interfering
1970+
* with power management or other parts of the system. The reset can
1971+
* be avoided; see omap_hwmod_no_setup_reset(). This is the second of
1972+
* two phases for hwmod initialization. Code called here generally
1973+
* affects the IP block hardware, or system integration hardware
1974+
* associated with the IP block. Returns 0.
1975+
*/
1976+
static int __init _setup(struct omap_hwmod *oh, void *data)
1977+
{
1978+
if (oh->_state != _HWMOD_STATE_INITIALIZED)
1979+
return 0;
1980+
1981+
_setup_iclk_autoidle(oh);
1982+
1983+
if (!_setup_reset(oh))
1984+
_setup_postsetup(oh);
1985+
18981986
return 0;
18991987
}
19001988

@@ -2700,10 +2788,10 @@ int omap_hwmod_for_each_by_class(const char *classname,
27002788
* @state: state that _setup() should leave the hwmod in
27012789
*
27022790
* Sets the hwmod state that @oh will enter at the end of _setup()
2703-
* (called by omap_hwmod_setup_*()). Only valid to call between
2704-
* calling omap_hwmod_register() and omap_hwmod_setup_*(). Returns
2705-
* 0 upon success or -EINVAL if there is a problem with the arguments
2706-
* or if the hwmod is in the wrong state.
2791+
* (called by omap_hwmod_setup_*()). See also the documentation
2792+
* for _setup_postsetup(), above. Returns 0 upon success or
2793+
* -EINVAL if there is a problem with the arguments or if the hwmod is
2794+
* in the wrong state.
27072795
*/
27082796
int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
27092797
{

0 commit comments

Comments
 (0)