]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/arm/mach-omap2/omap_hwmod.c
OMAP3: hwmod: support to specify the offset position of various SYSCONFIG register...
[mv-sheeva.git] / arch / arm / mach-omap2 / omap_hwmod.c
index 70912d1c71e0f366a1661c9b1f1b0e740674ed29..fb11ec176d551551c0e5fee69ddd160e3f8108c5 100644 (file)
@@ -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 */