mm: thp: set the accessed flag for old pages on access fault
[pandora-kernel.git] / drivers / regulator / twl-regulator.c
index ee8747f..b44f667 100644 (file)
@@ -58,6 +58,16 @@ struct twlreg_info {
 
        /* chip specific features */
        unsigned long           features;
+
+       /*
+        * optional override functions for voltage set/get
+        * these are currently only used for SMPS regulators
+        */
+       int                     (*get_voltage)(void *data);
+       int                     (*set_voltage)(void *data, int target_uV);
+
+       /* data passed from board for external get/set voltage */
+       void                    *data;
 };
 
 
@@ -71,6 +81,7 @@ struct twlreg_info {
 #define VREG_TYPE              1
 #define VREG_REMAP             2
 #define VREG_DEDICATED         3       /* LDO control */
+#define VREG_VOLTAGE_SMPS_4030 9
 /* TWL6030 register offsets */
 #define VREG_TRANS             1
 #define VREG_STATE             2
@@ -374,7 +385,7 @@ static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
  * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported.
  * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting.
  */
-#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED
+#if 1 //def CONFIG_TWL4030_ALLOW_UNSUPPORTED
 #define UNSUP_MASK     0x0000
 #else
 #define UNSUP_MASK     0x8000
@@ -514,6 +525,68 @@ static struct regulator_ops twl4030ldo_ops = {
        .get_status     = twl4030reg_get_status,
 };
 
+static int
+twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
+                       unsigned *selector)
+{
+       struct twlreg_info *info = rdev_get_drvdata(rdev);
+       int vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
+
+       if (info->set_voltage) {
+               return info->set_voltage(info->data, min_uV);
+       } else {
+               twlreg_write(info, TWL_MODULE_PM_RECEIVER,
+                       VREG_VOLTAGE_SMPS_4030, vsel);
+       }
+
+       return 0;
+}
+
+static int twl4030smps_get_voltage(struct regulator_dev *rdev)
+{
+       struct twlreg_info *info = rdev_get_drvdata(rdev);
+       int vsel;
+
+       if (info->get_voltage)
+               return info->get_voltage(info->data);
+
+       vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
+               VREG_VOLTAGE_SMPS_4030);
+
+       return vsel * 12500 + 600000;
+}
+
+static struct regulator_ops twl4030smps_ops = {
+       .set_voltage    = twl4030smps_set_voltage,
+       .get_voltage    = twl4030smps_get_voltage,
+};
+
+static int twl6030coresmps_set_voltage(struct regulator_dev *rdev, int min_uV,
+       int max_uV, unsigned *selector)
+{
+       struct twlreg_info *info = rdev_get_drvdata(rdev);
+
+       if (info->set_voltage)
+               return info->set_voltage(info->data, min_uV);
+
+       return -ENODEV;
+}
+
+static int twl6030coresmps_get_voltage(struct regulator_dev *rdev)
+{
+       struct twlreg_info *info = rdev_get_drvdata(rdev);
+
+       if (info->get_voltage)
+               return info->get_voltage(info->data);
+
+       return -ENODEV;
+}
+
+static struct regulator_ops twl6030coresmps_ops = {
+       .set_voltage    = twl6030coresmps_set_voltage,
+       .get_voltage    = twl6030coresmps_get_voltage,
+};
+
 static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
 {
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
@@ -856,6 +929,31 @@ static struct regulator_ops twlsmps_ops = {
                }, \
        }
 
+#define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \
+       { \
+       .base = offset, \
+       .id = num, \
+       .delay = turnon_delay, \
+       .remap = remap_conf, \
+       .desc = { \
+               .name = #label, \
+               .id = TWL4030_REG_##label, \
+               .ops = &twl4030smps_ops, \
+               .type = REGULATOR_VOLTAGE, \
+               .owner = THIS_MODULE, \
+               }, \
+       }
+
+#define TWL6030_ADJUSTABLE_SMPS(label) { \
+       .desc = { \
+               .name = #label, \
+               .id = TWL6030_REG_##label, \
+               .ops = &twl6030coresmps_ops, \
+               .type = REGULATOR_VOLTAGE, \
+               .owner = THIS_MODULE, \
+               }, \
+       }
+
 #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \
        .base = offset, \
        .min_mV = min_mVolts, \
@@ -947,8 +1045,8 @@ static struct twlreg_info twl_regs[] = {
        TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08),
        TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08),
        TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08),
-       TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15, 1000, 0x08),
-       TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16, 1000, 0x08),
+       TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08),
+       TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08),
        TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08),
        TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08),
        TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08),
@@ -957,6 +1055,9 @@ static struct twlreg_info twl_regs[] = {
        /* 6030 REG with base as PMC Slave Misc : 0x0030 */
        /* Turnon-delay and remap configuration values for 6030 are not
           verified since the specification is not public */
+       TWL6030_ADJUSTABLE_SMPS(VDD1),
+       TWL6030_ADJUSTABLE_SMPS(VDD2),
+       TWL6030_ADJUSTABLE_SMPS(VDD3),
        TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300),
        TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300),
        TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300),
@@ -1010,6 +1111,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
        struct regulator_init_data      *initdata;
        struct regulation_constraints   *c;
        struct regulator_dev            *rdev;
+       struct twl_regulator_driver_data        *drvdata;
 
        for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
                if (twl_regs[i].desc.id != pdev->id)
@@ -1024,8 +1126,16 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
        if (!initdata)
                return -EINVAL;
 
-       /* copy the features into regulator data */
-       info->features = (unsigned long)initdata->driver_data;
+       drvdata = initdata->driver_data;
+
+       if (!drvdata)
+               return -EINVAL;
+
+       /* copy the driver data into regulator data */
+       info->features = drvdata->features;
+       info->data = drvdata->data;
+       info->set_voltage = drvdata->set_voltage;
+       info->get_voltage = drvdata->get_voltage;
 
        /* Constrain board-specific capabilities according to what
         * this driver and the chip itself can actually do.