]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/commitdiff
MFD: Don't set TPS65217 STATUS_OFF until an actual power off event.
authorRuss Dill <Russ.Dill@ti.com>
Tue, 26 Aug 2014 05:43:20 +0000 (11:13 +0530)
committerTero Kristo <t-kristo@ti.com>
Mon, 1 Sep 2014 07:55:09 +0000 (10:55 +0300)
This allows the TPS to be used with RTC only suspend/resume, otherwise
it powers off when attempting suspend.

Signed-off-by: Russ Dill <Russ.Dill@ti.com>
[j-keerthy@ti.com] ported to 3.14 with minor fixes
Signed-off-by: Keerthy <j-keerthy@ti.com>
drivers/mfd/tps65217.c
include/linux/mfd/tps65217.h

index 21eea218c080877c9ab7337825a4a2e11d779eb2..4353047f7793bbedb5f20c19afa6dfd6e49e374a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/regmap.h>
 #include <linux/err.h>
+#include <linux/reboot.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 
@@ -149,6 +150,27 @@ static struct regmap_config tps65217_regmap_config = {
        .max_register = 0x1e,
 };
 
+static int tps65217_reboot_handler(struct notifier_block *this,
+                                  unsigned long code,
+                                  void *unused)
+{
+       struct tps65217 *tps = container_of(this, struct tps65217,
+                                           reboot_notifier);
+
+       if (code == SYS_POWER_OFF && tps->write_status_off) {
+               int ret;
+               dev_info(tps->dev, "%s: Enabling STATUS_OFF\n", __func__);
+               ret = tps65217_set_bits(tps, TPS65217_REG_STATUS,
+                                       TPS65217_STATUS_OFF,
+                                       TPS65217_STATUS_OFF,
+                                       TPS65217_PROTECT_NONE);
+               if (ret < 0)
+                       dev_err(tps->dev, "Failed to set status OFF\n");
+       }
+
+       return NOTIFY_OK;
+}
+
 static const struct of_device_id tps65217_of_match[] = {
        { .compatible = "ti,tps65217", .data = (void *)TPS65217 },
        { /* sentinel */ },
@@ -213,11 +235,20 @@ static int tps65217_probe(struct i2c_client *client,
 
        /* Set the PMIC to shutdown on PWR_EN toggle */
        if (status_off) {
-               ret = tps65217_set_bits(tps, TPS65217_REG_STATUS,
-                               TPS65217_STATUS_OFF, TPS65217_STATUS_OFF,
-                               TPS65217_PROTECT_NONE);
-               if (ret)
-                       dev_warn(tps->dev, "unable to set the status OFF\n");
+               tps->write_status_off = 1;
+               tps->reboot_notifier.notifier_call = tps65217_reboot_handler;
+               ret = register_reboot_notifier(&tps->reboot_notifier);
+               if (ret < 0) {
+                       dev_err(tps->dev, "Failed to register reboot handler\n");
+                       return ret;
+               }
+               ret = tps65217_clear_bits(tps, TPS65217_REG_STATUS,
+                                         TPS65217_STATUS_OFF,
+                                         TPS65217_PROTECT_NONE);
+               if (ret < 0) {
+                       dev_err(tps->dev, "Failed to clear status-off bit\n");
+                       return ret;
+               }
        }
 
        dev_info(tps->dev, "TPS65217 ID %#x version 1.%d\n",
@@ -231,6 +262,9 @@ static int tps65217_remove(struct i2c_client *client)
 {
        struct tps65217 *tps = i2c_get_clientdata(client);
 
+       if (tps->write_status_off)
+               unregister_reboot_notifier(&tps->reboot_notifier);
+
        mfd_remove_devices(tps->dev);
 
        return 0;
index 54b5458ec084a50ec06cc9f418d4e623e0aaf7bc..4c809137525cd1fcd3d411cbf24dbb56fdde659e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/i2c.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/notifier.h>
 
 /* TPS chip id list */
 #define TPS65217                       0xF0
@@ -256,6 +257,9 @@ struct tps65217 {
        struct regulator_desc desc[TPS65217_NUM_REGULATOR];
        struct regulator_dev *rdev[TPS65217_NUM_REGULATOR];
        struct regmap *regmap;
+
+       int write_status_off;
+       struct notifier_block reboot_notifier;
 };
 
 static inline struct tps65217 *dev_to_tps65217(struct device *dev)