mfd: dt: tps65910: Add power off control
authorBill Huang <bilhuang@nvidia.com>
Mon, 20 Aug 2012 01:07:56 +0000 (18:07 -0700)
committerSamuel Ortiz <sameo@linux.intel.com>
Fri, 14 Sep 2012 07:52:14 +0000 (09:52 +0200)
Add DT property "ti,system-power-controller" telling whether or not this
pmic is in charge of controlling the system power, so the power off
routine can be hooked up to system call "pm_power_off".

Based on the work by:
Dan Willemsen <dwillemsen@nvidia.com>

Signed-off-by: Bill Huang <bilhuang@nvidia.com>
Tested-by: Stephen Warren <swarren@wwwdotorg.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Documentation/devicetree/bindings/mfd/tps65910.txt
drivers/mfd/tps65910.c
include/linux/mfd/tps65910.h

index db03599ae4dcf268f0410d0b1373c3369f67351d..2e3304888ffc1c10e07b83fcec088d61dce6004d 100644 (file)
@@ -59,6 +59,8 @@ Optional properties:
   in TPS6591X datasheet)
 - ti,en-gpio-sleep: enable sleep control for gpios
   There should be 9 entries here, one for each gpio.
+- ti,system-power-controller: Telling whether or not this pmic is controlling
+  the system power.
 
 Regulator Optional properties:
 - ti,regulator-ext-sleep-control: enable external sleep
@@ -79,6 +81,8 @@ Example:
                #interrupt-cells = <2>;
                interrupt-controller;
 
+               ti,system-power-controller;
+
                ti,vmbch-threshold = 0;
                ti,vmbch2-threshold = 0;
                ti,en-ck32k-xtal;
index d3ce4d569deb57c2b707dc73d6cb7cf600962cab..ca902943cfa955e7170c06cdff9edc3505a61f12 100644 (file)
@@ -198,6 +198,8 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
 
        board_info->irq = client->irq;
        board_info->irq_base = -1;
+       board_info->pm_off = of_property_read_bool(np,
+                       "ti,system-power-controller");
 
        return board_info;
 }
@@ -210,6 +212,21 @@ struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
 }
 #endif
 
+static struct i2c_client *tps65910_i2c_client;
+static void tps65910_power_off(void)
+{
+       struct tps65910 *tps65910;
+
+       tps65910 = dev_get_drvdata(&tps65910_i2c_client->dev);
+
+       if (tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL,
+                       DEVCTRL_PWR_OFF_MASK) < 0)
+               return;
+
+       tps65910_reg_clear_bits(tps65910, TPS65910_DEVCTRL,
+                       DEVCTRL_DEV_ON_MASK);
+}
+
 static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
                                        const struct i2c_device_id *id)
 {
@@ -267,6 +284,11 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
        tps65910_ck32k_init(tps65910, pmic_plat_data);
        tps65910_sleepinit(tps65910, pmic_plat_data);
 
+       if (pmic_plat_data->pm_off && !pm_power_off) {
+               tps65910_i2c_client = i2c;
+               pm_power_off = tps65910_power_off;
+       }
+
        return ret;
 }
 
index 9bf8767818b450003dface8acf7585d4ce809059..ac772b36a1b169e47e9e5f1cb67e18f687b71b55 100644 (file)
 
 
 /*Register DEVCTRL  (0x80) register.RegisterDescription */
+#define DEVCTRL_PWR_OFF_MASK                           0x80
+#define DEVCTRL_PWR_OFF_SHIFT                          7
 #define DEVCTRL_RTC_PWDN_MASK                          0x40
 #define DEVCTRL_RTC_PWDN_SHIFT                         6
 #define DEVCTRL_CK32K_CTRL_MASK                                0x20
@@ -809,6 +811,7 @@ struct tps65910_board {
        int vmbch2_threshold;
        bool en_ck32k_xtal;
        bool en_dev_slp;
+       bool pm_off;
        struct tps65910_sleep_keepon_data *slp_keepon;
        bool en_gpio_sleep[TPS6591X_MAX_NUM_GPIO];
        unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS];