aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Kozlowski <k.kozlowski.k@gmail.com>2015-09-14 08:12:45 -0400
committerLee Jones <lee.jones@linaro.org>2015-10-26 10:49:04 -0400
commitd785334a0d5deff30a487c74324b842d2179553d (patch)
treeb0c19a873b50bd30e50a3ddae23ef0811346f58a
parent689d4453ed8212ab4a5d53982ac01cbe6531d18a (diff)
mfd: s2mps11: Add manual shutdown method for Odroid XU3
On Odroid XU3 board (with S2MPS11 PMIC) the PWRHOLD bit in CTRL1 register must be manually set to 0 before initiating power off sequence. One of usual power down methods for Exynos based devices looks like: 1. PWRHOLD pin of PMIC is connected to PSHOLD of Exynos SoC. 2. Exynos holds up this pin during system operation. 3. ACOKB pin of PMIC is pulled up to VBATT and optionally to pin in other device. 4. When PWRHOLD/PSHOLD goes low, the PMIC will turn off the power if ACOKB goes high. On Odroid XU3 family the difference is in (3) - the ACOKB is grounded. This means that PMIC must manually set PWRHOLD field to low and then wait for signal from Application Processor (the usual change in PWRHOLD/PSHOLD pin will actually cut off the power). The patch adds respective binding allowing Odroid XU3 device to be powered off. Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k@gmail.com> Reported-by: Anand Moon <linux.amoon@gmail.com> Tested-by: Anand Moon <linux.amoon@gmail.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/mfd/sec-core.c30
-rw-r--r--include/linux/mfd/samsung/core.h2
-rw-r--r--include/linux/mfd/samsung/s2mps11.h1
3 files changed, 33 insertions, 0 deletions
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
index d206a3e8fe87..2d1137a7a0ee 100644
--- a/drivers/mfd/sec-core.c
+++ b/drivers/mfd/sec-core.c
@@ -278,6 +278,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
278 * not parsed here. 278 * not parsed here.
279 */ 279 */
280 280
281 pd->manual_poweroff = of_property_read_bool(dev->of_node,
282 "samsung,s2mps11-acokb-ground");
281 return pd; 283 return pd;
282} 284}
283#else 285#else
@@ -440,6 +442,33 @@ static int sec_pmic_remove(struct i2c_client *i2c)
440 return 0; 442 return 0;
441} 443}
442 444
445static void sec_pmic_shutdown(struct i2c_client *i2c)
446{
447 struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
448 unsigned int reg, mask;
449
450 if (!sec_pmic->pdata->manual_poweroff)
451 return;
452
453 switch (sec_pmic->device_type) {
454 case S2MPS11X:
455 reg = S2MPS11_REG_CTRL1;
456 mask = S2MPS11_CTRL1_PWRHOLD_MASK;
457 break;
458 default:
459 /*
460 * Currently only one board with S2MPS11 needs this, so just
461 * ignore the rest.
462 */
463 dev_warn(sec_pmic->dev,
464 "Unsupported device %lu for manual power off\n",
465 sec_pmic->device_type);
466 return;
467 }
468
469 regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
470}
471
443#ifdef CONFIG_PM_SLEEP 472#ifdef CONFIG_PM_SLEEP
444static int sec_pmic_suspend(struct device *dev) 473static int sec_pmic_suspend(struct device *dev)
445{ 474{
@@ -491,6 +520,7 @@ static struct i2c_driver sec_pmic_driver = {
491 }, 520 },
492 .probe = sec_pmic_probe, 521 .probe = sec_pmic_probe,
493 .remove = sec_pmic_remove, 522 .remove = sec_pmic_remove,
523 .shutdown = sec_pmic_shutdown,
494 .id_table = sec_pmic_id, 524 .id_table = sec_pmic_id,
495}; 525};
496 526
diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h
index 75115384f3fc..aa78957e092f 100644
--- a/include/linux/mfd/samsung/core.h
+++ b/include/linux/mfd/samsung/core.h
@@ -132,6 +132,8 @@ struct sec_platform_data {
132 int buck2_init; 132 int buck2_init;
133 int buck3_init; 133 int buck3_init;
134 int buck4_init; 134 int buck4_init;
135 /* Whether or not manually set PWRHOLD to low during shutdown. */
136 bool manual_poweroff;
135}; 137};
136 138
137/** 139/**
diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h
index 7981a9d77d3f..b288965e8101 100644
--- a/include/linux/mfd/samsung/s2mps11.h
+++ b/include/linux/mfd/samsung/s2mps11.h
@@ -179,6 +179,7 @@ enum s2mps11_regulators {
179#define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1) 179#define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1)
180#define S2MPS11_RAMP_DELAY 25000 /* uV/us */ 180#define S2MPS11_RAMP_DELAY 25000 /* uV/us */
181 181
182#define S2MPS11_CTRL1_PWRHOLD_MASK BIT(4)
182 183
183#define S2MPS11_BUCK2_RAMP_SHIFT 6 184#define S2MPS11_BUCK2_RAMP_SHIFT 6
184#define S2MPS11_BUCK34_RAMP_SHIFT 4 185#define S2MPS11_BUCK34_RAMP_SHIFT 4