mfd: pm8xxx-misc: Add pm8xxx watchdog reset control API
The API configures PMIC to either shutdown or reset
when the PS_HOLD line goes low.
Change-Id: I758531966c08ec5acafaeedea13b59019aafa8bc
Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index 73792a3..ce6a016 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -22,9 +22,7 @@
#include <linux/mfd/pm8xxx/misc.h>
/* PON CTRL 1 register */
-#define REG_PM8058_PON_CTRL_1 0x01C
-#define REG_PM8921_PON_CTRL_1 0x01C
-#define REG_PM8018_PON_CTRL_1 0x01C
+#define REG_PM8XXX_PON_CTRL_1 0x01C
#define PON_CTRL_1_PULL_UP_MASK 0xE0
#define PON_CTRL_1_USB_PWR_EN 0x10
@@ -307,7 +305,7 @@
* Also ensure that KPD, CBL0, and CBL1 pull ups are enabled and that
* USB charging is enabled.
*/
- rc = pm8xxx_misc_masked_write(chip, REG_PM8018_PON_CTRL_1,
+ rc = pm8xxx_misc_masked_write(chip, REG_PM8XXX_PON_CTRL_1,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
| PON_CTRL_1_WD_EN_MASK,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
@@ -364,7 +362,7 @@
* Also ensure that KPD, CBL0, and CBL1 pull ups are enabled and that
* USB charging is enabled.
*/
- rc = pm8xxx_misc_masked_write(chip, REG_PM8058_PON_CTRL_1,
+ rc = pm8xxx_misc_masked_write(chip, REG_PM8XXX_PON_CTRL_1,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
| PON_CTRL_1_WD_EN_MASK,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
@@ -424,7 +422,7 @@
* Also ensure that KPD, CBL0, and CBL1 pull ups are enabled and that
* USB charging is enabled.
*/
- rc = pm8xxx_misc_masked_write(chip, REG_PM8921_PON_CTRL_1,
+ rc = pm8xxx_misc_masked_write(chip, REG_PM8XXX_PON_CTRL_1,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
| PON_CTRL_1_WD_EN_MASK,
PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
@@ -677,6 +675,52 @@
}
EXPORT_SYMBOL(pm8xxx_coincell_chg_config);
+/**
+ * pm8xxx_watchdog_reset_control - enables/disables watchdog reset detection
+ * @enable: 0 = shutdown when PS_HOLD goes low, 1 = reset when PS_HOLD goes low
+ *
+ * This function enables or disables the PMIC watchdog reset detection feature.
+ * If watchdog reset detection is enabled, then the PMIC will reset itself
+ * when PS_HOLD goes low. If it is not enabled, then the PMIC will shutdown
+ * when PS_HOLD goes low.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_watchdog_reset_control(int enable)
+{
+ struct pm8xxx_misc_chip *chip;
+ unsigned long flags;
+ int rc = 0;
+
+ spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+ /* Loop over all attached PMICs and call specific functions for them. */
+ list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+ switch (chip->version) {
+ case PM8XXX_VERSION_8018:
+ case PM8XXX_VERSION_8058:
+ case PM8XXX_VERSION_8921:
+ rc = pm8xxx_misc_masked_write(chip,
+ REG_PM8XXX_PON_CTRL_1, PON_CTRL_1_WD_EN_MASK,
+ (enable ? PON_CTRL_1_WD_EN_RESET
+ : PON_CTRL_1_WD_EN_PWR_OFF));
+ break;
+ default:
+ /* WD reset control not supported */
+ break;
+ }
+ if (rc) {
+ pr_err("setting WD reset control failed, rc=%d\n", rc);
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_watchdog_reset_control);
+
/* Handle the OSC_HALT interrupt: 32 kHz XTAL oscillator has stopped. */
static irqreturn_t pm8xxx_osc_halt_isr(int irq, void *data)
{
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index af0423a..2bd2850 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -117,6 +117,19 @@
*/
int pm8xxx_smpl_set_delay(enum pm8xxx_smpl_delay delay);
+/**
+ * pm8xxx_watchdog_reset_control - enables/disables watchdog reset detection
+ * @enable: 0 = shutdown when PS_HOLD goes low, 1 = reset when PS_HOLD goes low
+ *
+ * This function enables or disables the PMIC watchdog reset detection feature.
+ * If watchdog reset detection is enabled, then the PMIC will reset itself
+ * when PS_HOLD goes low. If it is not enabled, then the PMIC will shutdown
+ * when PS_HOLD goes low.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_watchdog_reset_control(int enable);
+
#else
static inline int pm8xxx_reset_pwr_off(int reset)
@@ -141,6 +154,10 @@
{
return -ENODEV;
}
+static inline int pm8xxx_watchdog_reset_control(int enable)
+{
+ return -ENODEV;
+}
#endif