Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 226586
b: refs/heads/master
c: 2092e5c
h: refs/heads/master
v: v3
  • Loading branch information
Paul Walmsley committed Dec 22, 2010
1 parent 176624d commit 826d36f
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e4dc8f507c3066d6fcece988d99b6d766c46af85
refs/heads/master: 2092e5ccf89db09ebde94e9aabd3c86d5fa05c6c
32 changes: 20 additions & 12 deletions trunk/arch/arm/mach-omap2/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,11 @@ static int __init _omap2_init_reprogram_sdrc(void)
return v;
}

static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data)
{
return omap_hwmod_set_postsetup_state(oh, *(u8 *)data);
}

/*
* Initialize asm_irq_base for entry-macro.S
*/
Expand All @@ -333,6 +338,8 @@ static inline void omap_irq_base_init(void)

void __init omap2_init_common_infrastructure(void)
{
u8 postsetup_state;

pwrdm_init(powerdomains_omap);
clkdm_init(clockdomains_omap, clkdm_autodeps);
if (cpu_is_omap242x())
Expand All @@ -343,6 +350,16 @@ void __init omap2_init_common_infrastructure(void)
omap3xxx_hwmod_init();
else if (cpu_is_omap44xx())
omap44xx_hwmod_init();
else
pr_err("Could not init hwmod data - unknown SoC\n");

/* Set the default postsetup state for all hwmods */
#ifdef CONFIG_PM_RUNTIME
postsetup_state = _HWMOD_STATE_IDLE;
#else
postsetup_state = _HWMOD_STATE_ENABLED;
#endif
omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state);

omap_pm_if_early_init();

Expand All @@ -355,25 +372,16 @@ void __init omap2_init_common_infrastructure(void)
else if (cpu_is_omap44xx())
omap4xxx_clk_init();
else
pr_err("Could not init clock framework - unknown CPU\n");
pr_err("Could not init clock framework - unknown SoC\n");
}

/*
* XXX Ideally, this function will dwindle into nothingness over time;
* almost all device init code should be possible through initcalls
* and other generalized mechanisms
*/
void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,
struct omap_sdrc_params *sdrc_cs1)
{
u8 skip_setup_idle = 0;

omap_serial_early_init();

#ifndef CONFIG_PM_RUNTIME
skip_setup_idle = 1;
#endif
omap_hwmod_late_init(skip_setup_idle);
omap_hwmod_late_init();

if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
_omap2_init_reprogram_sdrc();
Expand Down
82 changes: 63 additions & 19 deletions trunk/arch/arm/mach-omap2/omap_hwmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -1313,23 +1313,15 @@ static int _shutdown(struct omap_hwmod *oh)
/**
* _setup - do initial configuration of omap_hwmod
* @oh: struct omap_hwmod *
* @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1
*
* Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
* OCP_SYSCONFIG register. @skip_setup_idle is intended to be used on
* a system that will not call omap_hwmod_enable() to enable devices
* (e.g., a system without PM runtime). Returns -EINVAL if the hwmod
* is in the wrong state or returns 0.
* OCP_SYSCONFIG register. Returns -EINVAL if the hwmod is in the
* wrong state or returns 0.
*/
static int _setup(struct omap_hwmod *oh, void *data)
{
int i, r;
u8 skip_setup_idle;

if (!oh || !data)
return -EINVAL;

skip_setup_idle = *(u8 *)data;
u8 postsetup_state;

/* Set iclk autoidle mode */
if (oh->slaves_cnt > 0) {
Expand All @@ -1349,7 +1341,6 @@ static int _setup(struct omap_hwmod *oh, void *data)
}
}

mutex_init(&oh->_mutex);
oh->_state = _HWMOD_STATE_INITIALIZED;

/*
Expand Down Expand Up @@ -1383,8 +1374,25 @@ static int _setup(struct omap_hwmod *oh, void *data)
}
}

if (!(oh->flags & HWMOD_INIT_NO_IDLE) && !skip_setup_idle)
postsetup_state = oh->_postsetup_state;
if (postsetup_state == _HWMOD_STATE_UNKNOWN)
postsetup_state = _HWMOD_STATE_ENABLED;

/*
* XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data -
* it should be set by the core code as a runtime flag during startup
*/
if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
(postsetup_state == _HWMOD_STATE_IDLE))
postsetup_state = _HWMOD_STATE_ENABLED;

if (postsetup_state == _HWMOD_STATE_IDLE)
_omap_hwmod_idle(oh);
else if (postsetup_state == _HWMOD_STATE_DISABLED)
_shutdown(oh);
else if (postsetup_state != _HWMOD_STATE_ENABLED)
WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
oh->name, postsetup_state);

return 0;
}
Expand Down Expand Up @@ -1485,6 +1493,8 @@ int omap_hwmod_register(struct omap_hwmod *oh)

list_add_tail(&oh->node, &omap_hwmod_list);

mutex_init(&oh->_mutex);

oh->_state = _HWMOD_STATE_REGISTERED;

ret = 0;
Expand Down Expand Up @@ -1585,13 +1595,12 @@ int omap_hwmod_init(struct omap_hwmod **ohs)

/**
* omap_hwmod_late_init - do some post-clock framework initialization
* @skip_setup_idle: if 1, do not idle hwmods in _setup()
*
* Must be called after omap2_clk_init(). Resolves the struct clk names
* to struct clk pointers for each registered omap_hwmod. Also calls
* _setup() on each hwmod. Returns 0.
*/
int omap_hwmod_late_init(u8 skip_setup_idle)
int omap_hwmod_late_init(void)
{
int r;

Expand All @@ -1603,10 +1612,7 @@ int omap_hwmod_late_init(u8 skip_setup_idle)
WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n",
MPU_INITIATOR_NAME);

if (skip_setup_idle)
pr_debug("omap_hwmod: will leave hwmods enabled during setup\n");

omap_hwmod_for_each(_setup, &skip_setup_idle);
omap_hwmod_for_each(_setup, NULL);

return 0;
}
Expand Down Expand Up @@ -2132,3 +2138,41 @@ int omap_hwmod_for_each_by_class(const char *classname,
return ret;
}

/**
* omap_hwmod_set_postsetup_state - set the post-_setup() state for this hwmod
* @oh: struct omap_hwmod *
* @state: state that _setup() should leave the hwmod in
*
* Sets the hwmod state that @oh will enter at the end of _setup() (called by
* omap_hwmod_late_init()). Only valid to call between calls to
* omap_hwmod_init() and omap_hwmod_late_init(). Returns 0 upon success or
* -EINVAL if there is a problem with the arguments or if the hwmod is
* in the wrong state.
*/
int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
{
int ret;

if (!oh)
return -EINVAL;

if (state != _HWMOD_STATE_DISABLED &&
state != _HWMOD_STATE_ENABLED &&
state != _HWMOD_STATE_IDLE)
return -EINVAL;

mutex_lock(&oh->_mutex);

if (oh->_state != _HWMOD_STATE_REGISTERED) {
ret = -EINVAL;
goto ohsps_unlock;
}

oh->_postsetup_state = state;
ret = 0;

ohsps_unlock:
mutex_unlock(&oh->_mutex);

return ret;
}
6 changes: 5 additions & 1 deletion trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ struct omap_hwmod_class {
* @response_lat: device OCP response latency (in interface clock cycles)
* @_int_flags: internal-use hwmod flags
* @_state: internal-use hwmod state
* @_postsetup_state: internal-use state to leave the hwmod in after _setup()
* @flags: hwmod flags (documented below)
* @omap_chip: OMAP chips this hwmod is present on
* @_mutex: mutex serializing operations on this hwmod
Expand Down Expand Up @@ -510,6 +511,7 @@ struct omap_hwmod {
u8 hwmods_cnt;
u8 _int_flags;
u8 _state;
u8 _postsetup_state;
const struct omap_chip_id omap_chip;
};

Expand All @@ -519,7 +521,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh);
struct omap_hwmod *omap_hwmod_lookup(const char *name);
int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
void *data);
int omap_hwmod_late_init(u8 skip_setup_idle);
int omap_hwmod_late_init(void);

int omap_hwmod_enable(struct omap_hwmod *oh);
int _omap_hwmod_enable(struct omap_hwmod *oh);
Expand Down Expand Up @@ -566,6 +568,8 @@ int omap_hwmod_for_each_by_class(const char *classname,
void *user),
void *user);

int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);

/*
* Chip variant-specific hwmod init routines - XXX should be converted
* to use initcalls once the initial boot ordering is straightened out
Expand Down

0 comments on commit 826d36f

Please sign in to comment.