Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: dt: tps65910: Add power off control

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>

authored by

Bill Huang and committed by
Samuel Ortiz
b079fa72 004c15a6

+29
+4
Documentation/devicetree/bindings/mfd/tps65910.txt
··· 59 59 in TPS6591X datasheet) 60 60 - ti,en-gpio-sleep: enable sleep control for gpios 61 61 There should be 9 entries here, one for each gpio. 62 + - ti,system-power-controller: Telling whether or not this pmic is controlling 63 + the system power. 62 64 63 65 Regulator Optional properties: 64 66 - ti,regulator-ext-sleep-control: enable external sleep ··· 80 78 81 79 #interrupt-cells = <2>; 82 80 interrupt-controller; 81 + 82 + ti,system-power-controller; 83 83 84 84 ti,vmbch-threshold = 0; 85 85 ti,vmbch2-threshold = 0;
+22
drivers/mfd/tps65910.c
··· 198 198 199 199 board_info->irq = client->irq; 200 200 board_info->irq_base = -1; 201 + board_info->pm_off = of_property_read_bool(np, 202 + "ti,system-power-controller"); 201 203 202 204 return board_info; 203 205 } ··· 211 209 return NULL; 212 210 } 213 211 #endif 212 + 213 + static struct i2c_client *tps65910_i2c_client; 214 + static void tps65910_power_off(void) 215 + { 216 + struct tps65910 *tps65910; 217 + 218 + tps65910 = dev_get_drvdata(&tps65910_i2c_client->dev); 219 + 220 + if (tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL, 221 + DEVCTRL_PWR_OFF_MASK) < 0) 222 + return; 223 + 224 + tps65910_reg_clear_bits(tps65910, TPS65910_DEVCTRL, 225 + DEVCTRL_DEV_ON_MASK); 226 + } 214 227 215 228 static __devinit int tps65910_i2c_probe(struct i2c_client *i2c, 216 229 const struct i2c_device_id *id) ··· 283 266 tps65910_irq_init(tps65910, init_data->irq, init_data); 284 267 tps65910_ck32k_init(tps65910, pmic_plat_data); 285 268 tps65910_sleepinit(tps65910, pmic_plat_data); 269 + 270 + if (pmic_plat_data->pm_off && !pm_power_off) { 271 + tps65910_i2c_client = i2c; 272 + pm_power_off = tps65910_power_off; 273 + } 286 274 287 275 return ret; 288 276 }
+3
include/linux/mfd/tps65910.h
··· 366 366 367 367 368 368 /*Register DEVCTRL (0x80) register.RegisterDescription */ 369 + #define DEVCTRL_PWR_OFF_MASK 0x80 370 + #define DEVCTRL_PWR_OFF_SHIFT 7 369 371 #define DEVCTRL_RTC_PWDN_MASK 0x40 370 372 #define DEVCTRL_RTC_PWDN_SHIFT 6 371 373 #define DEVCTRL_CK32K_CTRL_MASK 0x20 ··· 811 809 int vmbch2_threshold; 812 810 bool en_ck32k_xtal; 813 811 bool en_dev_slp; 812 + bool pm_off; 814 813 struct tps65910_sleep_keepon_data *slp_keepon; 815 814 bool en_gpio_sleep[TPS6591X_MAX_NUM_GPIO]; 816 815 unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS];