From 1067f72b857e0f6af6e5343ff86e0e26fd34bdf2 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Mon, 27 Jul 2015 16:05:36 +0200 Subject: colibri-imx6: use stopmode for poweroff After the system has been shutdown with PMIC_ON_REQ and VCC_BATT is supplied from a battery it will never restart either by RESET or power cycle. So use the PMIC_STBY_REQ after shutdown to switch of power rails. --- arch/arm/mach-imx/pm-imx6.c | 17 +++++++++ drivers/regulator/pfuze100-regulator.c | 70 ++++++++++++++++++++++++++++++++++ drivers/rtc/rtc-snvs.c | 3 +- 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 587cc7e9f4e5..97f6af7dae77 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -431,6 +431,12 @@ void imx6_pm_set_ccm_base(void __iomem *base) ccm_base = base; } +void imx6_stop_mode_poweroff(void) +{ + imx6_set_lpm(STOP_POWER_OFF); + cpu_do_idle(); +} + void __init imx6_pm_init(void) { iram_paddr = MX6_SUSPEND_IRAM_ADDR; @@ -450,4 +456,15 @@ void __init imx6_pm_init(void) cpu_type = MXC_CPU_IMX6DL; else cpu_type = MXC_CPU_IMX6SL; + +#ifndef CONFIG_POWER_RESET_GPIO + /* + * if no specific power off function in board file, power off system by + * SNVS + */ + if (!pm_power_off) + if (of_machine_is_compatible("toradex,colibri_imx6dl")) + pm_power_off = imx6_stop_mode_poweroff; +#endif + } diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index 4ec8d77b9eb1..57496125cc42 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c @@ -522,6 +522,75 @@ static int pfuze100_regulator_remove(struct i2c_client *client) return 0; } +static void pfuze100_regulator_shutdown(struct i2c_client *client) +{ + if (of_machine_is_compatible("toradex,colibri_imx6dl")) { + int ret; + /* Configure all regulators to off on PMIC standby. For Colibri iMX6 + * we use the PMIC_STBY_REQ after shutdown, as the PMIC_ON_REQ signal + * together with VCC_BATT supplied from a battery leads to a + * nonbooting system. + * After the system has been shutdown with PMIC_ON_REQ it will never + * restart either by RESET or power cycle. + */ + struct pfuze_chip *pfuze_chip = i2c_get_clientdata(client); + + ret = regmap_update_bits(pfuze_chip->regmap, + PFUZE100_SW1ABVOL + PFUZE100_MODE_OFFSET, + 0x0f, 4); + if (ret < 0) + dev_err(pfuze_chip->dev, "stby config failed %d\n", ret); + + ret = regmap_update_bits(pfuze_chip->regmap, + PFUZE100_SW1CVOL + PFUZE100_MODE_OFFSET, + 0x0f, 4); + if (ret < 0) + dev_err(pfuze_chip->dev, "stby config failed %d\n", ret); + + ret = regmap_update_bits(pfuze_chip->regmap, + PFUZE100_SW3AVOL + PFUZE100_MODE_OFFSET, + 0x0f, 4); + if (ret < 0) + dev_err(pfuze_chip->dev, "stby config failed %d\n", ret); + + ret = regmap_update_bits(pfuze_chip->regmap, + PFUZE100_SW3BVOL + PFUZE100_MODE_OFFSET, + 0x0f, 4); + if (ret < 0) + dev_err(pfuze_chip->dev, "stby config failed %d\n", ret); + + ret = regmap_update_bits(pfuze_chip->regmap, + PFUZE100_SWBSTCON1, + 0x60, 0); + if (ret < 0) + dev_err(pfuze_chip->dev, "stby config failed %d\n", ret); + + ret = regmap_update_bits(pfuze_chip->regmap, + PFUZE100_VGEN2VOL, + 0x20, 0x20); + if (ret < 0) + dev_err(pfuze_chip->dev, "stby vgen config failed %d\n", ret); + + ret = regmap_update_bits(pfuze_chip->regmap, + PFUZE100_VGEN4VOL, + 0x20, 0x20); + if (ret < 0) + dev_err(pfuze_chip->dev, "stby vgen config failed %d\n", ret); + + ret = regmap_update_bits(pfuze_chip->regmap, + PFUZE100_VGEN5VOL, + 0x20, 0x20); + if (ret < 0) + dev_err(pfuze_chip->dev, "stby vgen config failed %d\n", ret); + + ret = regmap_update_bits(pfuze_chip->regmap, + PFUZE100_VGEN6VOL, + 0x20, 0x20); + if (ret < 0) + dev_err(pfuze_chip->dev, "stby vgen config failed %d\n", ret); + } +} + static struct i2c_driver pfuze_driver = { .id_table = pfuze_device_id, .driver = { @@ -531,6 +600,7 @@ static struct i2c_driver pfuze_driver = { }, .probe = pfuze100_regulator_probe, .remove = pfuze100_regulator_remove, + .shutdown = pfuze100_regulator_shutdown, }; module_i2c_driver(pfuze_driver); diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index ff2935a32db0..236d68705e48 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -309,7 +309,8 @@ static int snvs_rtc_probe(struct platform_device *pdev) * SNVS */ if (!pm_power_off) - pm_power_off = snvs_poweroff; + if (!of_machine_is_compatible("toradex,colibri_imx6dl")) + pm_power_off = snvs_poweroff; #endif return 0; -- cgit v1.2.3