diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 100 |
1 files changed, 87 insertions, 13 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 70912d1c71e0..fb11ec176d55 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -137,12 +137,24 @@ static void _write_sysconfig(u32 v, struct omap_hwmod *oh) static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode, u32 *v) { + u32 mstandby_mask; + u8 mstandby_shift; + if (!oh->sysconfig || !(oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE)) return -EINVAL; - *v &= ~SYSC_MIDLEMODE_MASK; - *v |= __ffs(standbymode) << SYSC_MIDLEMODE_SHIFT; + if (!oh->sysconfig->sysc_fields) { + WARN(!oh->sysconfig->sysc_fields, "offset struct for " + "sysconfig not provided!\n"); + return -EINVAL; + } + + mstandby_shift = oh->sysconfig->sysc_fields->midle_shift; + mstandby_mask = (0x3 << mstandby_shift); + + *v &= ~mstandby_mask; + *v |= __ffs(standbymode) << mstandby_shift; return 0; } @@ -159,12 +171,24 @@ static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode, */ static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v) { + u32 sidle_mask; + u8 sidle_shift; + if (!oh->sysconfig || !(oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE)) return -EINVAL; - *v &= ~SYSC_SIDLEMODE_MASK; - *v |= __ffs(idlemode) << SYSC_SIDLEMODE_SHIFT; + if (!oh->sysconfig->sysc_fields) { + WARN(!oh->sysconfig->sysc_fields, "offset struct for " + "sysconfig not provided!\n"); + return -EINVAL; + } + + sidle_shift = oh->sysconfig->sysc_fields->sidle_shift; + sidle_mask = (0x3 << sidle_shift); + + *v &= ~sidle_mask; + *v |= __ffs(idlemode) << sidle_shift; return 0; } @@ -182,12 +206,24 @@ static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v) */ static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v) { + u32 clkact_mask; + u8 clkact_shift; + if (!oh->sysconfig || !(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY)) return -EINVAL; - *v &= ~SYSC_CLOCKACTIVITY_MASK; - *v |= clockact << SYSC_CLOCKACTIVITY_SHIFT; + if (!oh->sysconfig->sysc_fields) { + WARN(!oh->sysconfig->sysc_fields, "offset struct for " + "sysconfig not provided!\n"); + return -EINVAL; + } + + clkact_shift = oh->sysconfig->sysc_fields->clkact_shift; + clkact_mask = (0x3 << clkact_shift); + + *v &= ~clkact_mask; + *v |= clockact << clkact_shift; return 0; } @@ -202,11 +238,21 @@ static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v) */ static int _set_softreset(struct omap_hwmod *oh, u32 *v) { + u32 softrst_mask; + if (!oh->sysconfig || !(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET)) return -EINVAL; - *v |= SYSC_SOFTRESET_MASK; + if (!oh->sysconfig->sysc_fields) { + WARN(!oh->sysconfig->sysc_fields, "offset struct for " + "sysconfig not provided!\n"); + return -EINVAL; + } + + softrst_mask = (0x1 << oh->sysconfig->sysc_fields->srst_shift); + + *v |= softrst_mask; return 0; } @@ -227,12 +273,24 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle, u32 *v) { + u32 autoidle_mask; + u8 autoidle_shift; + if (!oh->sysconfig || !(oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE)) return -EINVAL; - *v &= ~SYSC_AUTOIDLE_MASK; - *v |= autoidle << SYSC_AUTOIDLE_SHIFT; + if (!oh->sysconfig->sysc_fields) { + WARN(oh->sysconfig->sysc_fields, "offset struct for " + "sysconfig not provided!\n"); + return -EINVAL; + } + + autoidle_shift = oh->sysconfig->sysc_fields->autoidle_shift; + autoidle_mask = (0x3 << autoidle_shift); + + *v &= ~autoidle_mask; + *v |= autoidle << autoidle_shift; return 0; } @@ -246,14 +304,22 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle, */ static int _enable_wakeup(struct omap_hwmod *oh) { - u32 v; + u32 v, wakeup_mask; if (!oh->sysconfig || !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP)) return -EINVAL; + if (!oh->sysconfig->sysc_fields) { + WARN(!oh->sysconfig->sysc_fields, "offset struct for " + "sysconfig not provided!\n"); + return -EINVAL; + } + + wakeup_mask = (0x1 << oh->sysconfig->sysc_fields->enwkup_shift); + v = oh->_sysc_cache; - v |= SYSC_ENAWAKEUP_MASK; + v |= wakeup_mask; _write_sysconfig(v, oh); /* XXX test pwrdm_get_wken for this hwmod's subsystem */ @@ -272,14 +338,22 @@ static int _enable_wakeup(struct omap_hwmod *oh) */ static int _disable_wakeup(struct omap_hwmod *oh) { - u32 v; + u32 v, wakeup_mask; if (!oh->sysconfig || !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP)) return -EINVAL; + if (!oh->sysconfig->sysc_fields) { + WARN(!oh->sysconfig->sysc_fields, "offset struct for " + "sysconfig not provided!\n"); + return -EINVAL; + } + + wakeup_mask = (0x1 << oh->sysconfig->sysc_fields->enwkup_shift); + v = oh->_sysc_cache; - v &= ~SYSC_ENAWAKEUP_MASK; + v &= ~wakeup_mask; _write_sysconfig(v, oh); /* XXX test pwrdm_get_wken for this hwmod's subsystem */ |