Commit 5dfcb3b5 authored by Tony Lindgren's avatar Tony Lindgren

Merge tag 'omap-fixes-b2-for-3.7-rc' of...

Merge tag 'omap-fixes-b2-for-3.7-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v3.7-rc4/fixes
parents 55f4851a bc05244e
...@@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = { ...@@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS,
.wkdep_srcs = iss_wkup_sleep_deps, .wkdep_srcs = iss_wkup_sleep_deps,
.sleepdep_srcs = iss_wkup_sleep_deps, .sleepdep_srcs = iss_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP, .flags = CLKDM_CAN_SWSUP,
}; };
static struct clockdomain l3_dss_44xx_clkdm = { static struct clockdomain l3_dss_44xx_clkdm = {
......
...@@ -421,6 +421,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) ...@@ -421,6 +421,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
return 0; return 0;
} }
/**
* _wait_softreset_complete - wait for an OCP softreset to complete
* @oh: struct omap_hwmod * to wait on
*
* Wait until the IP block represented by @oh reports that its OCP
* softreset is complete. This can be triggered by software (see
* _ocp_softreset()) or by hardware upon returning from off-mode (one
* example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT
* microseconds. Returns the number of microseconds waited.
*/
static int _wait_softreset_complete(struct omap_hwmod *oh)
{
struct omap_hwmod_class_sysconfig *sysc;
u32 softrst_mask;
int c = 0;
sysc = oh->class->sysc;
if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
& SYSS_RESETDONE_MASK),
MAX_MODULE_SOFTRESET_WAIT, c);
else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
softrst_mask = (0x1 << sysc->sysc_fields->srst_shift);
omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs)
& softrst_mask),
MAX_MODULE_SOFTRESET_WAIT, c);
}
return c;
}
/** /**
* _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
...@@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh) ...@@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh)
if (!oh->class->sysc) if (!oh->class->sysc)
return; return;
/*
* Wait until reset has completed, this is needed as the IP
* block is reset automatically by hardware in some cases
* (off-mode for example), and the drivers require the
* IP to be ready when they access it
*/
if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
_enable_optional_clocks(oh);
_wait_softreset_complete(oh);
if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
_disable_optional_clocks(oh);
v = oh->_sysc_cache; v = oh->_sysc_cache;
sf = oh->class->sysc->sysc_flags; sf = oh->class->sysc->sysc_flags;
...@@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh) ...@@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)
*/ */
static int _ocp_softreset(struct omap_hwmod *oh) static int _ocp_softreset(struct omap_hwmod *oh)
{ {
u32 v, softrst_mask; u32 v;
int c = 0; int c = 0;
int ret = 0; int ret = 0;
...@@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh) ...@@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh)
if (oh->class->sysc->srst_udelay) if (oh->class->sysc->srst_udelay)
udelay(oh->class->sysc->srst_udelay); udelay(oh->class->sysc->srst_udelay);
if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) c = _wait_softreset_complete(oh);
omap_test_timeout((omap_hwmod_read(oh,
oh->class->sysc->syss_offs)
& SYSS_RESETDONE_MASK),
MAX_MODULE_SOFTRESET_WAIT, c);
else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
omap_test_timeout(!(omap_hwmod_read(oh,
oh->class->sysc->sysc_offs)
& softrst_mask),
MAX_MODULE_SOFTRESET_WAIT, c);
}
if (c == MAX_MODULE_SOFTRESET_WAIT) if (c == MAX_MODULE_SOFTRESET_WAIT)
pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
oh->name, MAX_MODULE_SOFTRESET_WAIT); oh->name, MAX_MODULE_SOFTRESET_WAIT);
...@@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh) ...@@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh)
if (oh->_state != _HWMOD_STATE_INITIALIZED) if (oh->_state != _HWMOD_STATE_INITIALIZED)
return -EINVAL; return -EINVAL;
if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
return -EPERM;
if (oh->rst_lines_cnt == 0) { if (oh->rst_lines_cnt == 0) {
r = _enable(oh); r = _enable(oh);
if (r) { if (r) {
......
...@@ -2125,6 +2125,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { ...@@ -2125,6 +2125,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
.name = "mcpdm", .name = "mcpdm",
.class = &omap44xx_mcpdm_hwmod_class, .class = &omap44xx_mcpdm_hwmod_class,
.clkdm_name = "abe_clkdm", .clkdm_name = "abe_clkdm",
/*
* It's suspected that the McPDM requires an off-chip main
* functional clock, controlled via I2C. This IP block is
* currently reset very early during boot, before I2C is
* available, so it doesn't seem that we have any choice in
* the kernel other than to avoid resetting it.
*/
.flags = HWMOD_EXT_OPT_MAIN_CLK,
.mpu_irqs = omap44xx_mcpdm_irqs, .mpu_irqs = omap44xx_mcpdm_irqs,
.sdma_reqs = omap44xx_mcpdm_sdma_reqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs,
.main_clk = "mcpdm_fck", .main_clk = "mcpdm_fck",
......
...@@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm { ...@@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm {
* in order to complete the reset. Optional clocks will be disabled * in order to complete the reset. Optional clocks will be disabled
* again after the reset. * again after the reset.
* HWMOD_16BIT_REG: Module has 16bit registers * HWMOD_16BIT_REG: Module has 16bit registers
* HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for
* this IP block comes from an off-chip source and is not always
* enabled. This prevents the hwmod code from being able to
* enable and reset the IP block early. XXX Eventually it should
* be possible to query the clock framework for this information.
*/ */
#define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_SIDLE (1 << 0)
#define HWMOD_SWSUP_MSTANDBY (1 << 1) #define HWMOD_SWSUP_MSTANDBY (1 << 1)
...@@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm { ...@@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm {
#define HWMOD_NO_IDLEST (1 << 6) #define HWMOD_NO_IDLEST (1 << 6)
#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
#define HWMOD_16BIT_REG (1 << 8) #define HWMOD_16BIT_REG (1 << 8)
#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
/* /*
* omap_hwmod._int_flags definitions * omap_hwmod._int_flags definitions
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment