]> Pileus Git - ~andy/linux/blobdiff - drivers/regulator/ab8500.c
Merge remote-tracking branch 'regulator/topic/lp8788' into v3.9-rc8
[~andy/linux] / drivers / regulator / ab8500.c
index ef12d3d79bdf71f10e1bf774c569c5a0965a859c..f6656b8c28b606f49cbecc8d47a63d9d61832a47 100644 (file)
@@ -46,7 +46,6 @@ struct ab8500_shared_mode {
  * @desc: regulator description
  * @regulator_dev: regulator device
  * @shared_mode: used when mode is shared between two regulators
- * @is_enabled: status of regulator (on/off)
  * @load_lp_uA: maximum load in idle (low power) mode
  * @update_bank: bank to control on/off
  * @update_reg: register to control on/off
@@ -62,14 +61,12 @@ struct ab8500_shared_mode {
  * @voltage_bank: bank to control regulator voltage
  * @voltage_reg: register to control regulator voltage
  * @voltage_mask: mask to control regulator voltage
- * @voltage_shift: shift to control regulator voltage
  */
 struct ab8500_regulator_info {
        struct device           *dev;
        struct regulator_desc   desc;
        struct regulator_dev    *regulator;
        struct ab8500_shared_mode *shared_mode;
-       bool is_enabled;
        int load_lp_uA;
        u8 update_bank;
        u8 update_reg;
@@ -85,13 +82,11 @@ struct ab8500_regulator_info {
        u8 voltage_bank;
        u8 voltage_reg;
        u8 voltage_mask;
-       u8 voltage_shift;
        struct {
                u8 voltage_limit;
                u8 voltage_bank;
                u8 voltage_reg;
                u8 voltage_mask;
-               u8 voltage_shift;
        } expand_register;
 };
 
@@ -149,6 +144,21 @@ static const unsigned int ldo_vaux3_ab8540_voltages[] = {
        3050000,
 };
 
+static const unsigned int ldo_vaux56_ab8540_voltages[] = {
+       750000, 760000, 770000, 780000, 790000, 800000,
+       810000, 820000, 830000, 840000, 850000, 860000,
+       870000, 880000, 890000, 900000, 910000, 920000,
+       930000, 940000, 950000, 960000, 970000, 980000,
+       990000, 1000000, 1010000, 1020000, 1030000,
+       1040000, 1050000, 1060000, 1070000, 1080000,
+       1090000, 1100000, 1110000, 1120000, 1130000,
+       1140000, 1150000, 1160000, 1170000, 1180000,
+       1190000, 1200000, 1210000, 1220000, 1230000,
+       1240000, 1250000, 1260000, 1270000, 1280000,
+       1290000, 1300000, 1310000, 1320000, 1330000,
+       1340000, 1350000, 1360000, 1800000, 2790000,
+};
+
 static const unsigned int ldo_vintcore_voltages[] = {
        1200000,
        1225000,
@@ -244,8 +254,6 @@ static int ab8500_regulator_enable(struct regulator_dev *rdev)
                return ret;
        }
 
-       info->is_enabled = true;
-
        dev_vdbg(rdev_get_dev(rdev),
                "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
                info->desc.name, info->update_bank, info->update_reg,
@@ -273,8 +281,6 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev)
                return ret;
        }
 
-       info->is_enabled = false;
-
        dev_vdbg(rdev_get_dev(rdev),
                "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
                info->desc.name, info->update_bank, info->update_reg,
@@ -283,6 +289,37 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev)
        return ret;
 }
 
+static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
+{
+       int ret;
+       struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+       u8 regval;
+
+       if (info == NULL) {
+               dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
+               return -EINVAL;
+       }
+
+       ret = abx500_get_register_interruptible(info->dev,
+               info->update_bank, info->update_reg, &regval);
+       if (ret < 0) {
+               dev_err(rdev_get_dev(rdev),
+                       "couldn't read 0x%x register\n", info->update_reg);
+               return ret;
+       }
+
+       dev_vdbg(rdev_get_dev(rdev),
+               "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
+               " 0x%x\n",
+               info->desc.name, info->update_bank, info->update_reg,
+               info->update_mask, regval);
+
+       if (regval & info->update_mask)
+               return 1;
+       else
+               return 0;
+}
+
 static unsigned int ab8500_regulator_get_optimum_mode(
                struct regulator_dev *rdev, int input_uV,
                int output_uV, int load_uA)
@@ -308,11 +345,8 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
                                     unsigned int mode)
 {
        int ret = 0;
-       u8 bank;
-       u8 reg;
-       u8 mask;
-       u8 val;
-       bool dmr = false; /* Dedicated mode register */
+       u8 bank, reg, mask, val;
+       bool lp_mode_req = false;
        struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
 
        if (info == NULL) {
@@ -320,75 +354,61 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
                return -EINVAL;
        }
 
-       if (info->shared_mode) {
-               /*
-                * Special case where mode is shared between two regulators.
-                */
-               struct ab8500_shared_mode *sm = info->shared_mode;
-               mutex_lock(&shared_mode_mutex);
-
-               if (mode == REGULATOR_MODE_IDLE) {
-                       sm->lp_mode_req = true; /* Low power mode requested */
-                       if (!((sm->shared_regulator)->
-                             shared_mode->lp_mode_req)) {
-                               mutex_unlock(&shared_mode_mutex);
-                               return 0; /* Other regulator prevent LP mode */
-                       }
-               } else {
-                       sm->lp_mode_req = false;
-               }
-       }
-
        if (info->mode_mask) {
-               /* Dedicated register for handling mode */
-
-               dmr = true;
-
-               switch (mode) {
-               case REGULATOR_MODE_NORMAL:
-                       val = info->mode_val_normal;
-                       break;
-               case REGULATOR_MODE_IDLE:
-                       val = info->mode_val_idle;
-                       break;
-               default:
-                       if (info->shared_mode)
-                               mutex_unlock(&shared_mode_mutex);
-                       return -EINVAL;
-               }
-
                bank = info->mode_bank;
                reg = info->mode_reg;
                mask = info->mode_mask;
        } else {
-               /* Mode register same as enable register */
+               bank = info->update_bank;
+               reg = info->update_reg;
+               mask = info->update_mask;
+       }
+
+       if (info->shared_mode)
+               mutex_lock(&shared_mode_mutex);
 
-               switch (mode) {
-               case REGULATOR_MODE_NORMAL:
-                       info->update_val = info->update_val_normal;
+       switch (mode) {
+       case REGULATOR_MODE_NORMAL:
+               if (info->shared_mode)
+                       lp_mode_req = false;
+
+               if (info->mode_mask)
+                       val = info->mode_val_normal;
+               else
                        val = info->update_val_normal;
-                       break;
-               case REGULATOR_MODE_IDLE:
-                       info->update_val = info->update_val_idle;
-                       val = info->update_val_idle;
-                       break;
-               default:
-                       if (info->shared_mode)
-                               mutex_unlock(&shared_mode_mutex);
-                       return -EINVAL;
+               break;
+       case REGULATOR_MODE_IDLE:
+               if (info->shared_mode) {
+                       struct ab8500_regulator_info *shared_regulator;
+
+                       shared_regulator = info->shared_mode->shared_regulator;
+                       if (!shared_regulator->shared_mode->lp_mode_req) {
+                               /* Other regulator prevent LP mode */
+                               info->shared_mode->lp_mode_req = true;
+                               goto out_unlock;
+                       }
+
+                       lp_mode_req = true;
                }
 
-               bank = info->update_bank;
-               reg = info->update_reg;
-               mask = info->update_mask;
+               if (info->mode_mask)
+                       val = info->mode_val_idle;
+               else
+                       val = info->update_val_idle;
+               break;
+       default:
+               ret = -EINVAL;
+               goto out_unlock;
        }
 
-       if (info->is_enabled || dmr) {
+       if (info->mode_mask || ab8500_regulator_is_enabled(rdev)) {
                ret = abx500_mask_and_set_register_interruptible(info->dev,
                        bank, reg, mask, val);
-               if (ret < 0)
+               if (ret < 0) {
                        dev_err(rdev_get_dev(rdev),
                                "couldn't set regulator mode\n");
+                       goto out_unlock;
+               }
 
                dev_vdbg(rdev_get_dev(rdev),
                        "%s-set_mode (bank, reg, mask, value): "
@@ -397,6 +417,13 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
                        mask, val);
        }
 
+       if (!info->mode_mask)
+               info->update_val = val;
+
+       if (info->shared_mode)
+               info->shared_mode->lp_mode_req = lp_mode_req;
+
+out_unlock:
        if (info->shared_mode)
                mutex_unlock(&shared_mode_mutex);
 
@@ -449,42 +476,9 @@ static unsigned int ab8500_regulator_get_mode(struct regulator_dev *rdev)
        return ret;
 }
 
-static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
-{
-       int ret;
-       struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
-       u8 regval;
-
-       if (info == NULL) {
-               dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
-               return -EINVAL;
-       }
-
-       ret = abx500_get_register_interruptible(info->dev,
-               info->update_bank, info->update_reg, &regval);
-       if (ret < 0) {
-               dev_err(rdev_get_dev(rdev),
-                       "couldn't read 0x%x register\n", info->update_reg);
-               return ret;
-       }
-
-       dev_vdbg(rdev_get_dev(rdev),
-               "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
-               " 0x%x\n",
-               info->desc.name, info->update_bank, info->update_reg,
-               info->update_mask, regval);
-
-       if (regval & info->update_mask)
-               info->is_enabled = true;
-       else
-               info->is_enabled = false;
-
-       return info->is_enabled;
-}
-
 static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
 {
-       int ret, val;
+       int ret, voltage_shift;
        struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
        u8 regval;
 
@@ -493,6 +487,8 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
                return -EINVAL;
        }
 
+       voltage_shift = ffs(info->voltage_mask) - 1;
+
        ret = abx500_get_register_interruptible(info->dev,
                        info->voltage_bank, info->voltage_reg, &regval);
        if (ret < 0) {
@@ -506,15 +502,14 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
                "0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
                info->desc.name, info->voltage_bank,
                info->voltage_reg, info->voltage_mask,
-               info->voltage_shift, regval);
+               voltage_shift, regval);
 
-       val = regval & info->voltage_mask;
-       return val >> info->voltage_shift;
+       return (regval & info->voltage_mask) >> voltage_shift;
 }
 
 static int ab8540_aux3_regulator_get_voltage_sel(struct regulator_dev *rdev)
 {
-       int ret, val;
+       int ret, voltage_shift;
        struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
        u8 regval, regval_expand;
 
@@ -524,18 +519,25 @@ static int ab8540_aux3_regulator_get_voltage_sel(struct regulator_dev *rdev)
        }
 
        ret = abx500_get_register_interruptible(info->dev,
-                       info->voltage_bank, info->voltage_reg, &regval);
-
+                       info->expand_register.voltage_bank,
+                       info->expand_register.voltage_reg, &regval_expand);
        if (ret < 0) {
                dev_err(rdev_get_dev(rdev),
-                       "couldn't read voltage reg for regulator\n");
+                       "couldn't read voltage expand reg for regulator\n");
                return ret;
        }
 
-       ret = abx500_get_register_interruptible(info->dev,
-                       info->expand_register.voltage_bank,
-                       info->expand_register.voltage_reg, &regval_expand);
+       dev_vdbg(rdev_get_dev(rdev),
+                "%s-get_voltage expand (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
+                info->desc.name, info->expand_register.voltage_bank,
+                info->expand_register.voltage_reg,
+                info->expand_register.voltage_mask, regval_expand);
+
+       if (regval_expand & info->expand_register.voltage_mask)
+               return info->expand_register.voltage_limit;
 
+       ret = abx500_get_register_interruptible(info->dev,
+                       info->voltage_bank, info->voltage_reg, &regval);
        if (ret < 0) {
                dev_err(rdev_get_dev(rdev),
                        "couldn't read voltage reg for regulator\n");
@@ -543,30 +545,19 @@ static int ab8540_aux3_regulator_get_voltage_sel(struct regulator_dev *rdev)
        }
 
        dev_vdbg(rdev_get_dev(rdev),
-               "%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
-               " 0x%x\n",
-               info->desc.name, info->voltage_bank, info->voltage_reg,
-               info->voltage_mask, regval);
-       dev_vdbg(rdev_get_dev(rdev),
-               "%s-get_voltage expand (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
-               " 0x%x\n",
-               info->desc.name, info->expand_register.voltage_bank,
-               info->expand_register.voltage_reg,
-               info->expand_register.voltage_mask, regval_expand);
+                "%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
+                info->desc.name, info->voltage_bank, info->voltage_reg,
+                info->voltage_mask, regval);
 
-       if (regval_expand&(info->expand_register.voltage_mask))
-               /* Vaux3 has a different layout */
-               val = info->expand_register.voltage_limit;
-       else
-               val = (regval & info->voltage_mask) >> info->voltage_shift;
+       voltage_shift = ffs(info->voltage_mask) - 1;
 
-       return val;
+       return (regval & info->voltage_mask) >> voltage_shift;
 }
 
 static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
                                            unsigned selector)
 {
-       int ret;
+       int ret, voltage_shift;
        struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
        u8 regval;
 
@@ -575,8 +566,10 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
                return -EINVAL;
        }
 
+       voltage_shift = ffs(info->voltage_mask) - 1;
+
        /* set the registers for the request */
-       regval = (u8)selector << info->voltage_shift;
+       regval = (u8)selector << voltage_shift;
        ret = abx500_mask_and_set_register_interruptible(info->dev,
                        info->voltage_bank, info->voltage_reg,
                        info->voltage_mask, regval);
@@ -598,48 +591,54 @@ static int ab8540_aux3_regulator_set_voltage_sel(struct regulator_dev *rdev,
 {
        int ret;
        struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
-       u8 regval;
+       u8 regval, regval_expand;
 
        if (info == NULL) {
                dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
                return -EINVAL;
        }
 
-       if (selector >= info->expand_register.voltage_limit) {
-               /* Vaux3 bit4 has different layout */
-               regval = (u8)selector << info->expand_register.voltage_shift;
+       if (selector < info->expand_register.voltage_limit) {
+               int voltage_shift = ffs(info->voltage_mask) - 1;
+
+               regval = (u8)selector << voltage_shift;
                ret = abx500_mask_and_set_register_interruptible(info->dev,
-                                       info->expand_register.voltage_bank,
-                                       info->expand_register.voltage_reg,
-                                       info->expand_register.voltage_mask,
-                                       regval);
+                                       info->voltage_bank, info->voltage_reg,
+                                       info->voltage_mask, regval);
+               if (ret < 0) {
+                       dev_err(rdev_get_dev(rdev),
+                               "couldn't set voltage reg for regulator\n");
+                       return ret;
+               }
+
+               dev_vdbg(rdev_get_dev(rdev),
+                        "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
+                        info->desc.name, info->voltage_bank, info->voltage_reg,
+                        info->voltage_mask, regval);
+
+               regval_expand = 0;
        } else {
-               /* set the registers for the request */
-               regval = (u8)selector << info->voltage_shift;
-               ret = abx500_mask_and_set_register_interruptible(info->dev,
-                               info->voltage_bank, info->voltage_reg,
-                               info->voltage_mask, regval);
+               regval_expand = info->expand_register.voltage_mask;
        }
-       if (ret < 0)
+
+       ret = abx500_mask_and_set_register_interruptible(info->dev,
+                               info->expand_register.voltage_bank,
+                               info->expand_register.voltage_reg,
+                               info->expand_register.voltage_mask,
+                               regval_expand);
+       if (ret < 0) {
                dev_err(rdev_get_dev(rdev),
-                       "couldn't set voltage reg for regulator\n");
+                       "couldn't set expand voltage reg for regulator\n");
+               return ret;
+       }
 
        dev_vdbg(rdev_get_dev(rdev),
-                       "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
-                       " 0x%x\n",
-                       info->desc.name, info->voltage_bank, info->voltage_reg,
-                       info->voltage_mask, regval);
-
-       return ret;
-}
-
-static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
-                                            unsigned int old_sel,
-                                            unsigned int new_sel)
-{
-       struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+                "%s-set_voltage expand (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
+                info->desc.name, info->expand_register.voltage_bank,
+                info->expand_register.voltage_reg,
+                info->expand_register.voltage_mask, regval_expand);
 
-       return info->delay;
+       return 0;
 }
 
 static struct regulator_ops ab8500_regulator_volt_mode_ops = {
@@ -664,7 +663,6 @@ static struct regulator_ops ab8540_aux3_regulator_volt_mode_ops = {
        .get_voltage_sel = ab8540_aux3_regulator_get_voltage_sel,
        .set_voltage_sel = ab8540_aux3_regulator_set_voltage_sel,
        .list_voltage   = regulator_list_voltage_table,
-       .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
 };
 
 static struct regulator_ops ab8500_regulator_volt_ops = {
@@ -674,7 +672,6 @@ static struct regulator_ops ab8500_regulator_volt_ops = {
        .get_voltage_sel = ab8500_regulator_get_voltage_sel,
        .set_voltage_sel = ab8500_regulator_set_voltage_sel,
        .list_voltage   = regulator_list_voltage_table,
-       .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
 };
 
 static struct regulator_ops ab8500_regulator_mode_ops = {
@@ -684,14 +681,14 @@ static struct regulator_ops ab8500_regulator_mode_ops = {
        .get_optimum_mode       = ab8500_regulator_get_optimum_mode,
        .set_mode               = ab8500_regulator_set_mode,
        .get_mode               = ab8500_regulator_get_mode,
-       .list_voltage           = regulator_list_voltage_linear,
+       .list_voltage           = regulator_list_voltage_table,
 };
 
 static struct regulator_ops ab8500_regulator_ops = {
        .enable                 = ab8500_regulator_enable,
        .disable                = ab8500_regulator_disable,
        .is_enabled             = ab8500_regulator_is_enabled,
-       .list_voltage           = regulator_list_voltage_linear,
+       .list_voltage           = regulator_list_voltage_table,
 };
 
 static struct regulator_ops ab8500_regulator_anamic_mode_ops = {
@@ -799,7 +796,6 @@ static struct ab8500_regulator_info
                .voltage_bank           = 0x03,
                .voltage_reg            = 0x80,
                .voltage_mask           = 0x38,
-               .voltage_shift          = 3,
        },
 
        /*
@@ -922,7 +918,7 @@ static struct ab8500_regulator_info
         * Variable Voltage Regulators
         *   name, min mV, max mV,
         *   update bank, reg, mask, enable val
-        *   volt bank, reg, mask, table, table length
+        *   volt bank, reg, mask
         */
        [AB8505_LDO_AUX1] = {
                .desc = {
@@ -1074,7 +1070,6 @@ static struct ab8500_regulator_info
                .voltage_bank           = 0x03,
                .voltage_reg            = 0x80,
                .voltage_mask           = 0x38,
-               .voltage_shift          = 3,
        },
 
        /*
@@ -1091,8 +1086,8 @@ static struct ab8500_regulator_info
                        .owner          = THIS_MODULE,
                        .n_voltages     = 1,
                        .volt_table     = fixed_2000000_voltage,
+                       .enable_time    = 10000,
                },
-               .delay                  = 10000,
                .load_lp_uA             = 1000,
                .update_bank            = 0x03,
                .update_reg             = 0x80,
@@ -1134,10 +1129,7 @@ static struct ab8500_regulator_info
                .update_val             = 0x02,
                .voltage_bank           = 0x01,
                .voltage_reg            = 0x57,
-               .voltage_mask           = 0x7,
-               .voltage_shift          = 4,
-               .voltages               = ldo_vaudio_voltages,
-               .voltages_len           = ARRAY_SIZE(ldo_vaudio_voltages),
+               .voltage_mask           = 0x70,
        },
        [AB8505_LDO_ANAMIC1] = {
                .desc = {
@@ -1219,8 +1211,6 @@ static struct ab8500_regulator_info
                .voltage_bank           = 0x04,
                .voltage_reg            = 0x29,
                .voltage_mask           = 0x7,
-               .voltages               = ldo_vana_voltages,
-               .voltages_len           = ARRAY_SIZE(ldo_vana_voltages),
        },
 };
 
@@ -1231,7 +1221,7 @@ static struct ab8500_regulator_info
         * Variable Voltage Regulators
         *   name, min mV, max mV,
         *   update bank, reg, mask, enable val
-        *   volt bank, reg, mask, table, table length
+        *   volt bank, reg, mask
         */
        [AB9540_LDO_AUX1] = {
                .desc = {
@@ -1339,7 +1329,6 @@ static struct ab8500_regulator_info
                .voltage_bank           = 0x03,
                .voltage_reg            = 0x80,
                .voltage_mask           = 0x38,
-               .voltage_shift          = 3,
        },
 
        /*
@@ -1356,8 +1345,8 @@ static struct ab8500_regulator_info
                        .owner          = THIS_MODULE,
                        .n_voltages     = 1,
                        .volt_table     = fixed_2000000_voltage,
+                       .enable_time    = 10000,
                },
-               .delay                  = 10000,
                .load_lp_uA             = 1000,
                .update_bank            = 0x03,
                .update_reg             = 0x80,
@@ -1474,7 +1463,7 @@ static struct ab8500_regulator_info
         * Variable Voltage Regulators
         *   name, min mV, max mV,
         *   update bank, reg, mask, enable val
-        *   volt bank, reg, mask, table, table length
+        *   volt bank, reg, mask
         */
        [AB8540_LDO_AUX1] = {
                .desc = {
@@ -1543,7 +1532,6 @@ static struct ab8500_regulator_info
                        .voltage_bank           = 0x04,
                        .voltage_reg            = 0x01,
                        .voltage_mask           = 0x10,
-                       .voltage_shift          = 1,
                }
        },
        [AB8540_LDO_AUX4] = {
@@ -1569,6 +1557,52 @@ static struct ab8500_regulator_info
                .voltage_reg            = 0x2f,
                .voltage_mask           = 0x0f,
        },
+       [AB8540_LDO_AUX5] = {
+               .desc = {
+                       .name           = "LDO-AUX5",
+                       .ops            = &ab8500_regulator_volt_mode_ops,
+                       .type           = REGULATOR_VOLTAGE,
+                       .id             = AB8540_LDO_AUX5,
+                       .owner          = THIS_MODULE,
+                       .n_voltages     = ARRAY_SIZE(ldo_vaux56_ab8540_voltages),
+                       .volt_table     = ldo_vaux56_ab8540_voltages,
+               },
+               .load_lp_uA             = 20000,
+               /* values for Vaux5Regu register */
+               .update_bank            = 0x04,
+               .update_reg             = 0x32,
+               .update_mask            = 0x03,
+               .update_val             = 0x01,
+               .update_val_idle        = 0x03,
+               .update_val_normal      = 0x01,
+               /* values for Vaux5SEL register */
+               .voltage_bank           = 0x04,
+               .voltage_reg            = 0x33,
+               .voltage_mask           = 0x3f,
+       },
+       [AB8540_LDO_AUX6] = {
+               .desc = {
+                       .name           = "LDO-AUX6",
+                       .ops            = &ab8500_regulator_volt_mode_ops,
+                       .type           = REGULATOR_VOLTAGE,
+                       .id             = AB8540_LDO_AUX6,
+                       .owner          = THIS_MODULE,
+                       .n_voltages     = ARRAY_SIZE(ldo_vaux56_ab8540_voltages),
+                       .volt_table     = ldo_vaux56_ab8540_voltages,
+               },
+               .load_lp_uA             = 20000,
+               /* values for Vaux6Regu register */
+               .update_bank            = 0x04,
+               .update_reg             = 0x35,
+               .update_mask            = 0x03,
+               .update_val             = 0x01,
+               .update_val_idle        = 0x03,
+               .update_val_normal      = 0x01,
+               /* values for Vaux6SEL register */
+               .voltage_bank           = 0x04,
+               .voltage_reg            = 0x36,
+               .voltage_mask           = 0x3f,
+       },
        [AB8540_LDO_INTCORE] = {
                .desc = {
                        .name           = "LDO-INTCORE",
@@ -1589,7 +1623,6 @@ static struct ab8500_regulator_info
                .voltage_bank           = 0x03,
                .voltage_reg            = 0x80,
                .voltage_mask           = 0x38,
-               .voltage_shift          = 3,
        },
 
        /*
@@ -1605,8 +1638,9 @@ static struct ab8500_regulator_info
                        .id             = AB8540_LDO_TVOUT,
                        .owner          = THIS_MODULE,
                        .n_voltages     = 1,
+                       .volt_table     = fixed_2000000_voltage,
+                       .enable_time    = 10000,
                },
-               .delay                  = 10000,
                .load_lp_uA             = 1000,
                .update_bank            = 0x03,
                .update_reg             = 0x80,
@@ -1680,6 +1714,7 @@ static struct ab8500_regulator_info
                        .id             = AB8540_LDO_DMIC,
                        .owner          = THIS_MODULE,
                        .n_voltages     = ARRAY_SIZE(ldo_vdmic_voltages),
+                       .volt_table     = ldo_vdmic_voltages,
                },
                .load_lp_uA             = 1000,
                .update_bank            = 0x03,
@@ -1689,8 +1724,6 @@ static struct ab8500_regulator_info
                .voltage_bank           = 0x03,
                .voltage_reg            = 0x83,
                .voltage_mask           = 0xc0,
-               .voltages               = ldo_vdmic_voltages,
-               .voltages_len           = ARRAY_SIZE(ldo_vdmic_voltages),
        },
 
        /*
@@ -2860,10 +2893,112 @@ static struct ab8500_reg_init ab8540_reg_init[] = {
        REG_INIT(AB8540_REGUCTRLDISCH4,         0x04, 0x49, 0x07),
 };
 
+static struct of_regulator_match ab8500_regulator_match[] = {
+       { .name = "ab8500_ldo_aux1",    .driver_data = (void *) AB8500_LDO_AUX1, },
+       { .name = "ab8500_ldo_aux2",    .driver_data = (void *) AB8500_LDO_AUX2, },
+       { .name = "ab8500_ldo_aux3",    .driver_data = (void *) AB8500_LDO_AUX3, },
+       { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
+       { .name = "ab8500_ldo_tvout",   .driver_data = (void *) AB8500_LDO_TVOUT, },
+       { .name = "ab8500_ldo_audio",   .driver_data = (void *) AB8500_LDO_AUDIO, },
+       { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
+       { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
+       { .name = "ab8500_ldo_dmic",    .driver_data = (void *) AB8500_LDO_DMIC, },
+       { .name = "ab8500_ldo_ana",     .driver_data = (void *) AB8500_LDO_ANA, },
+};
+
+static struct of_regulator_match ab8505_regulator_match[] = {
+       { .name = "ab8500_ldo_aux1",    .driver_data = (void *) AB8505_LDO_AUX1, },
+       { .name = "ab8500_ldo_aux2",    .driver_data = (void *) AB8505_LDO_AUX2, },
+       { .name = "ab8500_ldo_aux3",    .driver_data = (void *) AB8505_LDO_AUX3, },
+       { .name = "ab8500_ldo_aux4",    .driver_data = (void *) AB8505_LDO_AUX4, },
+       { .name = "ab8500_ldo_aux5",    .driver_data = (void *) AB8505_LDO_AUX5, },
+       { .name = "ab8500_ldo_aux6",    .driver_data = (void *) AB8505_LDO_AUX6, },
+       { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8505_LDO_INTCORE, },
+       { .name = "ab8500_ldo_adc",     .driver_data = (void *) AB8505_LDO_ADC, },
+       { .name = "ab8500_ldo_audio",   .driver_data = (void *) AB8505_LDO_AUDIO, },
+       { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8505_LDO_ANAMIC1, },
+       { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8505_LDO_ANAMIC2, },
+       { .name = "ab8500_ldo_aux8",    .driver_data = (void *) AB8505_LDO_AUX8, },
+       { .name = "ab8500_ldo_ana",     .driver_data = (void *) AB8505_LDO_ANA, },
+};
+
+static struct of_regulator_match ab8540_regulator_match[] = {
+       { .name = "ab8500_ldo_aux1",    .driver_data = (void *) AB8540_LDO_AUX1, },
+       { .name = "ab8500_ldo_aux2",    .driver_data = (void *) AB8540_LDO_AUX2, },
+       { .name = "ab8500_ldo_aux3",    .driver_data = (void *) AB8540_LDO_AUX3, },
+       { .name = "ab8500_ldo_aux4",    .driver_data = (void *) AB8540_LDO_AUX4, },
+       { .name = "ab8500_ldo_aux5",    .driver_data = (void *) AB8540_LDO_AUX5, },
+       { .name = "ab8500_ldo_aux6",    .driver_data = (void *) AB8540_LDO_AUX6, },
+       { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8540_LDO_INTCORE, },
+       { .name = "ab8500_ldo_tvout",   .driver_data = (void *) AB8540_LDO_TVOUT, },
+       { .name = "ab8500_ldo_audio",   .driver_data = (void *) AB8540_LDO_AUDIO, },
+       { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8540_LDO_ANAMIC1, },
+       { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8540_LDO_ANAMIC2, },
+       { .name = "ab8500_ldo_dmic",    .driver_data = (void *) AB8540_LDO_DMIC, },
+       { .name = "ab8500_ldo_ana",     .driver_data = (void *) AB8540_LDO_ANA, },
+       { .name = "ab8500_ldo_sdio",    .driver_data = (void *) AB8540_LDO_SDIO, },
+};
+
+static struct of_regulator_match ab9540_regulator_match[] = {
+       { .name = "ab8500_ldo_aux1",    .driver_data = (void *) AB9540_LDO_AUX1, },
+       { .name = "ab8500_ldo_aux2",    .driver_data = (void *) AB9540_LDO_AUX2, },
+       { .name = "ab8500_ldo_aux3",    .driver_data = (void *) AB9540_LDO_AUX3, },
+       { .name = "ab8500_ldo_aux4",    .driver_data = (void *) AB9540_LDO_AUX4, },
+       { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB9540_LDO_INTCORE, },
+       { .name = "ab8500_ldo_tvout",   .driver_data = (void *) AB9540_LDO_TVOUT, },
+       { .name = "ab8500_ldo_audio",   .driver_data = (void *) AB9540_LDO_AUDIO, },
+       { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB9540_LDO_ANAMIC1, },
+       { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB9540_LDO_ANAMIC2, },
+       { .name = "ab8500_ldo_dmic",    .driver_data = (void *) AB9540_LDO_DMIC, },
+       { .name = "ab8500_ldo_ana",     .driver_data = (void *) AB9540_LDO_ANA, },
+};
+
+static struct {
+       struct ab8500_regulator_info *info;
+       int info_size;
+       struct ab8500_reg_init *init;
+       int init_size;
+       struct of_regulator_match *match;
+       int match_size;
+} abx500_regulator;
+
+static void abx500_get_regulator_info(struct ab8500 *ab8500)
+{
+       if (is_ab9540(ab8500)) {
+               abx500_regulator.info = ab9540_regulator_info;
+               abx500_regulator.info_size = ARRAY_SIZE(ab9540_regulator_info);
+               abx500_regulator.init = ab9540_reg_init;
+               abx500_regulator.init_size = AB9540_NUM_REGULATOR_REGISTERS;
+               abx500_regulator.match = ab9540_regulator_match;
+               abx500_regulator.match_size = ARRAY_SIZE(ab9540_regulator_match);
+       } else if (is_ab8505(ab8500)) {
+               abx500_regulator.info = ab8505_regulator_info;
+               abx500_regulator.info_size = ARRAY_SIZE(ab8505_regulator_info);
+               abx500_regulator.init = ab8505_reg_init;
+               abx500_regulator.init_size = AB8505_NUM_REGULATOR_REGISTERS;
+               abx500_regulator.match = ab8505_regulator_match;
+               abx500_regulator.match_size = ARRAY_SIZE(ab8505_regulator_match);
+       } else if (is_ab8540(ab8500)) {
+               abx500_regulator.info = ab8540_regulator_info;
+               abx500_regulator.info_size = ARRAY_SIZE(ab8540_regulator_info);
+               abx500_regulator.init = ab8540_reg_init;
+               abx500_regulator.init_size = AB8540_NUM_REGULATOR_REGISTERS;
+               abx500_regulator.match = ab8540_regulator_match;
+               abx500_regulator.match_size = ARRAY_SIZE(ab8540_regulator_match);
+       } else {
+               abx500_regulator.info = ab8500_regulator_info;
+               abx500_regulator.info_size = ARRAY_SIZE(ab8500_regulator_info);
+               abx500_regulator.init = ab8500_reg_init;
+               abx500_regulator.init_size = AB8500_NUM_REGULATOR_REGISTERS;
+               abx500_regulator.match = ab8500_regulator_match;
+               abx500_regulator.match_size = ARRAY_SIZE(ab8500_regulator_match);
+       }
+}
+
 static int ab8500_regulator_init_registers(struct platform_device *pdev,
-                                          struct ab8500_reg_init *reg_init,
                                           int id, int mask, int value)
 {
+       struct ab8500_reg_init *reg_init = abx500_regulator.init;
        int err;
 
        BUG_ON(value & ~mask);
@@ -2893,7 +3028,6 @@ static int ab8500_regulator_init_registers(struct platform_device *pdev,
 
 static int ab8500_regulator_register(struct platform_device *pdev,
                                     struct regulator_init_data *init_data,
-                                    struct ab8500_regulator_info *regulator_info,
                                     int id, struct device_node *np)
 {
        struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
@@ -2902,7 +3036,7 @@ static int ab8500_regulator_register(struct platform_device *pdev,
        int err;
 
        /* assign per-regulator data */
-       info = &regulator_info[id];
+       info = &abx500_regulator.info[id];
        info->dev = &pdev->dev;
 
        config.dev = &pdev->dev;
@@ -2928,7 +3062,7 @@ static int ab8500_regulator_register(struct platform_device *pdev,
                        info->desc.name);
                /* when we fail, un-register all earlier regulators */
                while (--id >= 0) {
-                       info = &regulator_info[id];
+                       info = &abx500_regulator.info[id];
                        regulator_unregister(info->regulator);
                }
                return err;
@@ -2937,77 +3071,16 @@ static int ab8500_regulator_register(struct platform_device *pdev,
        return 0;
 }
 
-static struct of_regulator_match ab8500_regulator_match[] = {
-       { .name = "ab8500_ldo_aux1",    .driver_data = (void *) AB8500_LDO_AUX1, },
-       { .name = "ab8500_ldo_aux2",    .driver_data = (void *) AB8500_LDO_AUX2, },
-       { .name = "ab8500_ldo_aux3",    .driver_data = (void *) AB8500_LDO_AUX3, },
-       { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
-       { .name = "ab8500_ldo_tvout",   .driver_data = (void *) AB8500_LDO_TVOUT, },
-       { .name = "ab8500_ldo_audio",   .driver_data = (void *) AB8500_LDO_AUDIO, },
-       { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
-       { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
-       { .name = "ab8500_ldo_dmic",    .driver_data = (void *) AB8500_LDO_DMIC, },
-       { .name = "ab8500_ldo_ana",     .driver_data = (void *) AB8500_LDO_ANA, },
-};
-
-static struct of_regulator_match ab8505_regulator_match[] = {
-       { .name = "ab8500_ldo_aux1",    .driver_data = (void *) AB8505_LDO_AUX1, },
-       { .name = "ab8500_ldo_aux2",    .driver_data = (void *) AB8505_LDO_AUX2, },
-       { .name = "ab8500_ldo_aux3",    .driver_data = (void *) AB8505_LDO_AUX3, },
-       { .name = "ab8500_ldo_aux4",    .driver_data = (void *) AB8505_LDO_AUX4, },
-       { .name = "ab8500_ldo_aux5",    .driver_data = (void *) AB8505_LDO_AUX5, },
-       { .name = "ab8500_ldo_aux6",    .driver_data = (void *) AB8505_LDO_AUX6, },
-       { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8505_LDO_INTCORE, },
-       { .name = "ab8500_ldo_adc",     .driver_data = (void *) AB8505_LDO_ADC, },
-       { .name = "ab8500_ldo_audio",   .driver_data = (void *) AB8505_LDO_AUDIO, },
-       { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8505_LDO_ANAMIC1, },
-       { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8505_LDO_ANAMIC2, },
-       { .name = "ab8500_ldo_aux8",    .driver_data = (void *) AB8505_LDO_AUX8, },
-       { .name = "ab8500_ldo_ana",     .driver_data = (void *) AB8505_LDO_ANA, },
-};
-
-static struct of_regulator_match ab8540_regulator_match[] = {
-       { .name = "ab8500_ldo_aux1",    .driver_data = (void *) AB8540_LDO_AUX1, },
-       { .name = "ab8500_ldo_aux2",    .driver_data = (void *) AB8540_LDO_AUX2, },
-       { .name = "ab8500_ldo_aux3",    .driver_data = (void *) AB8540_LDO_AUX3, },
-       { .name = "ab8500_ldo_aux4",    .driver_data = (void *) AB8540_LDO_AUX4, },
-       { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8540_LDO_INTCORE, },
-       { .name = "ab8500_ldo_tvout",   .driver_data = (void *) AB8540_LDO_TVOUT, },
-       { .name = "ab8500_ldo_audio",   .driver_data = (void *) AB8540_LDO_AUDIO, },
-       { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8540_LDO_ANAMIC1, },
-       { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8540_LDO_ANAMIC2, },
-       { .name = "ab8500_ldo_dmic",    .driver_data = (void *) AB8540_LDO_DMIC, },
-       { .name = "ab8500_ldo_ana",     .driver_data = (void *) AB8540_LDO_ANA, },
-       { .name = "ab8500_ldo_sdio",    .driver_data = (void *) AB8540_LDO_SDIO, },
-};
-
-static struct of_regulator_match ab9540_regulator_match[] = {
-       { .name = "ab8500_ldo_aux1",    .driver_data = (void *) AB9540_LDO_AUX1, },
-       { .name = "ab8500_ldo_aux2",    .driver_data = (void *) AB9540_LDO_AUX2, },
-       { .name = "ab8500_ldo_aux3",    .driver_data = (void *) AB9540_LDO_AUX3, },
-       { .name = "ab8500_ldo_aux4",    .driver_data = (void *) AB9540_LDO_AUX4, },
-       { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB9540_LDO_INTCORE, },
-       { .name = "ab8500_ldo_tvout",   .driver_data = (void *) AB9540_LDO_TVOUT, },
-       { .name = "ab8500_ldo_audio",   .driver_data = (void *) AB9540_LDO_AUDIO, },
-       { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB9540_LDO_ANAMIC1, },
-       { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB9540_LDO_ANAMIC2, },
-       { .name = "ab8500_ldo_dmic",    .driver_data = (void *) AB9540_LDO_DMIC, },
-       { .name = "ab8500_ldo_ana",     .driver_data = (void *) AB9540_LDO_ANA, },
-};
-
 static int
 ab8500_regulator_of_probe(struct platform_device *pdev,
-                         struct ab8500_regulator_info *regulator_info,
-                         int regulator_info_size,
-                         struct of_regulator_match *match,
                          struct device_node *np)
 {
+       struct of_regulator_match *match = abx500_regulator.match;
        int err, i;
 
-       for (i = 0; i < regulator_info_size; i++) {
+       for (i = 0; i < abx500_regulator.info_size; i++) {
                err = ab8500_regulator_register(
-                       pdev, match[i].init_data, regulator_info,
-                       i, match[i].of_node);
+                       pdev, match[i].init_data, i, match[i].of_node);
                if (err)
                        return err;
        }
@@ -3019,59 +3092,31 @@ static int ab8500_regulator_probe(struct platform_device *pdev)
 {
        struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
        struct device_node *np = pdev->dev.of_node;
-       struct of_regulator_match *match;
        struct ab8500_platform_data *ppdata;
        struct ab8500_regulator_platform_data *pdata;
        int i, err;
-       struct ab8500_regulator_info *regulator_info;
-       int regulator_info_size;
-       struct ab8500_reg_init *reg_init;
-       int reg_init_size;
 
-       if (is_ab9540(ab8500)) {
-               regulator_info = ab9540_regulator_info;
-               regulator_info_size = ARRAY_SIZE(ab9540_regulator_info);
-               reg_init = ab9540_reg_init;
-               reg_init_size = AB9540_NUM_REGULATOR_REGISTERS;
-               match = ab9540_regulator_match;
-               match_size = ARRAY_SIZE(ab9540_regulator_match)
-       } else if (is_ab8505(ab8500)) {
-               regulator_info = ab8505_regulator_info;
-               regulator_info_size = ARRAY_SIZE(ab8505_regulator_info);
-               reg_init = ab8505_reg_init;
-               reg_init_size = AB8505_NUM_REGULATOR_REGISTERS;
-       } else if (is_ab8540(ab8500)) {
-               regulator_info = ab8540_regulator_info;
-               regulator_info_size = ARRAY_SIZE(ab8540_regulator_info);
-               reg_init = ab8540_reg_init;
-               reg_init_size = AB8540_NUM_REGULATOR_REGISTERS;
-       } else {
-               regulator_info = ab8500_regulator_info;
-               regulator_info_size = ARRAY_SIZE(ab8500_regulator_info);
-               reg_init = ab8500_reg_init;
-               reg_init_size = AB8500_NUM_REGULATOR_REGISTERS;
-               match = ab8500_regulator_match;
-               match_size = ARRAY_SIZE(ab8500_regulator_match)
+       if (!ab8500) {
+               dev_err(&pdev->dev, "null mfd parent\n");
+               return -EINVAL;
        }
 
+       abx500_get_regulator_info(ab8500);
+
        if (np) {
-               err = of_regulator_match(&pdev->dev, np, match, match_size);
+               err = of_regulator_match(&pdev->dev, np,
+                                        abx500_regulator.match,
+                                        abx500_regulator.match_size);
                if (err < 0) {
                        dev_err(&pdev->dev,
                                "Error parsing regulator init data: %d\n", err);
                        return err;
                }
 
-               err = ab8500_regulator_of_probe(pdev, regulator_info,
-                                               regulator_info_size, match, np);
+               err = ab8500_regulator_of_probe(pdev, np);
                return err;
        }
 
-       if (!ab8500) {
-               dev_err(&pdev->dev, "null mfd parent\n");
-               return -EINVAL;
-       }
-
        ppdata = dev_get_platdata(ab8500->dev);
        if (!ppdata) {
                dev_err(&pdev->dev, "null parent pdata\n");
@@ -3085,7 +3130,7 @@ static int ab8500_regulator_probe(struct platform_device *pdev)
        }
 
        /* make sure the platform data has the correct size */
-       if (pdata->num_regulator != regulator_info_size) {
+       if (pdata->num_regulator != abx500_regulator.info_size) {
                dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
                return -EINVAL;
        }
@@ -3104,9 +3149,9 @@ static int ab8500_regulator_probe(struct platform_device *pdev)
                value = pdata->reg_init[i].value;
 
                /* check for configuration errors */
-               BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS);
+               BUG_ON(id >= abx500_regulator.init_size);
 
-               err = ab8500_regulator_init_registers(pdev, reg_init, id, mask, value);
+               err = ab8500_regulator_init_registers(pdev, id, mask, value);
                if (err < 0)
                        return err;
        }
@@ -3119,11 +3164,14 @@ static int ab8500_regulator_probe(struct platform_device *pdev)
        }
 
        /* register all regulators */
-       for (i = 0; i < regulator_info_size; i++) {
+       for (i = 0; i < abx500_regulator.info_size; i++) {
                err = ab8500_regulator_register(pdev, &pdata->regulator[i],
-                                               regulator_info, i, NULL);
-               if (err < 0)
+                                               i, NULL);
+               if (err < 0) {
+                       if (!is_ab8505(ab8500))
+                               ab8500_ext_regulator_exit(pdev);
                        return err;
+               }
        }
 
        return 0;
@@ -3133,27 +3181,10 @@ static int ab8500_regulator_remove(struct platform_device *pdev)
 {
        int i, err;
        struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
-       struct ab8500_regulator_info *regulator_info;
-       int regulator_info_size;
-
 
-       if (is_ab9540(ab8500)) {
-               regulator_info = ab9540_regulator_info;
-               regulator_info_size = ARRAY_SIZE(ab9540_regulator_info);
-       } else if (is_ab8505(ab8500)) {
-               regulator_info = ab8505_regulator_info;
-               regulator_info_size = ARRAY_SIZE(ab8505_regulator_info);
-       } else if (is_ab8540(ab8500)) {
-               regulator_info = ab8540_regulator_info;
-               regulator_info_size = ARRAY_SIZE(ab8540_regulator_info);
-       } else {
-               regulator_info = ab8500_regulator_info;
-               regulator_info_size = ARRAY_SIZE(ab8500_regulator_info);
-       }
-
-       for (i = 0; i < regulator_info_size; i++) {
+       for (i = 0; i < abx500_regulator.info_size; i++) {
                struct ab8500_regulator_info *info = NULL;
-               info = &regulator_info[i];
+               info = &abx500_regulator.info[i];
 
                dev_vdbg(rdev_get_dev(info->regulator),
                        "%s-remove\n", info->desc.name);
@@ -3161,12 +3192,9 @@ static int ab8500_regulator_remove(struct platform_device *pdev)
                regulator_unregister(info->regulator);
        }
 
-       if (!is_ab8505(ab8500)) {
-               /* remove external regulators (after Vaux1, 2 and 3) */
-               err = ab8500_ext_regulator_exit(pdev);
-               if (err)
-                       return err;
-       }
+       /* remove external regulators (after Vaux1, 2 and 3) */
+       if (!is_ab8505(ab8500))
+               ab8500_ext_regulator_exit(pdev);
 
        /* remove regulator debug */
        err = ab8500_regulator_debug_exit(pdev);