These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / mfd / sec-core.c
index 4a69afb..989076d 100644 (file)
@@ -103,12 +103,9 @@ static const struct mfd_cell s2mpa01_devs[] = {
 };
 
 static const struct mfd_cell s2mpu02_devs[] = {
-       { .name = "s2mpu02-pmic", },
-       { .name = "s2mpu02-rtc", },
        {
-               .name = "s2mpu02-clk",
-               .of_compatible = "samsung,s2mpu02-clk",
-       }
+               .name = "s2mpu02-pmic",
+       },
 };
 
 #ifdef CONFIG_OF
@@ -253,6 +250,38 @@ static const struct regmap_config s5m8767_regmap_config = {
        .cache_type = REGCACHE_FLAT,
 };
 
+static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
+{
+       unsigned int val;
+
+       /* For each device type, the REG_ID is always the first register */
+       if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val))
+               dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val);
+}
+
+static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic)
+{
+       int err;
+
+       if (sec_pmic->device_type != S2MPS13X)
+               return;
+
+       if (sec_pmic->pdata->disable_wrstbi) {
+               /*
+                * If WRSTBI pin is pulled down this feature must be disabled
+                * because each Suspend to RAM will trigger buck voltage reset
+                * to default values.
+                */
+               err = regmap_update_bits(sec_pmic->regmap_pmic,
+                                        S2MPS13_REG_WRSTBI,
+                                        S2MPS13_REG_WRSTBI_MASK, 0x0);
+               if (err)
+                       dev_warn(sec_pmic->dev,
+                                "Cannot initialize WRSTBI config: %d\n",
+                                err);
+       }
+}
+
 #ifdef CONFIG_OF
 /*
  * Only the common platform data elements for s5m8767 are parsed here from the
@@ -278,6 +307,10 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
         * not parsed here.
         */
 
+       pd->manual_poweroff = of_property_read_bool(dev->of_node,
+                                               "samsung,s2mps11-acokb-ground");
+       pd->disable_wrstbi = of_property_read_bool(dev->of_node,
+                                               "samsung,s2mps11-wrstbi-ground");
        return pd;
 }
 #else
@@ -423,6 +456,8 @@ static int sec_pmic_probe(struct i2c_client *i2c,
                goto err_mfd;
 
        device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
+       sec_pmic_configure(sec_pmic);
+       sec_pmic_dump_rev(sec_pmic);
 
        return ret;
 
@@ -440,6 +475,33 @@ static int sec_pmic_remove(struct i2c_client *i2c)
        return 0;
 }
 
+static void sec_pmic_shutdown(struct i2c_client *i2c)
+{
+       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+       unsigned int reg, mask;
+
+       if (!sec_pmic->pdata->manual_poweroff)
+               return;
+
+       switch (sec_pmic->device_type) {
+       case S2MPS11X:
+               reg = S2MPS11_REG_CTRL1;
+               mask = S2MPS11_CTRL1_PWRHOLD_MASK;
+               break;
+       default:
+               /*
+                * Currently only one board with S2MPS11 needs this, so just
+                * ignore the rest.
+                */
+               dev_warn(sec_pmic->dev,
+                       "Unsupported device %lu for manual power off\n",
+                       sec_pmic->device_type);
+               return;
+       }
+
+       regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int sec_pmic_suspend(struct device *dev)
 {
@@ -486,12 +548,12 @@ MODULE_DEVICE_TABLE(i2c, sec_pmic_id);
 static struct i2c_driver sec_pmic_driver = {
        .driver = {
                   .name = "sec_pmic",
-                  .owner = THIS_MODULE,
                   .pm = &sec_pmic_pm_ops,
                   .of_match_table = of_match_ptr(sec_dt_match),
        },
        .probe = sec_pmic_probe,
        .remove = sec_pmic_remove,
+       .shutdown = sec_pmic_shutdown,
        .id_table = sec_pmic_id,
 };