[PATCH V2] power: twl4030_charger: attempt to power off in case of critical events

From: Nishanth Menon
Date: Wed May 28 2014 - 17:01:16 EST


Attempt to power off in case of critical events such as battery removal,
over voltage events.

There is no guarentee that we'd be in a safe scenario here, but the
very least we can try to do is to shut down the chargers and power off
the device to prevent damage to the system instead of just printing a
message and hoping for the best.

NOTE: twl4030 should attempt some form of recovery, but just depending
on that is never a safe alternative.

Signed-off-by: Nishanth Menon <nm@xxxxxx>
---
drivers/power/twl4030_charger.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 2598c58..6d92893 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -22,6 +22,7 @@
#include <linux/power_supply.h>
#include <linux/notifier.h>
#include <linux/usb/otg.h>
+#include <linux/reboot.h>
#include <linux/regulator/machine.h>

#define TWL4030_BCIMSTATEC 0x02
@@ -332,6 +333,7 @@ static irqreturn_t twl4030_bci_interrupt(int irq, void *arg)
struct twl4030_bci *bci = arg;
u8 irqs1, irqs2;
int ret;
+ bool power_off = false;

ret = twl_i2c_read_u8(TWL4030_MODULE_INTERRUPTS, &irqs1,
TWL4030_INTERRUPTS_BCIISR1A);
@@ -352,20 +354,38 @@ static irqreturn_t twl4030_bci_interrupt(int irq, void *arg)
}

/* various monitoring events, for now we just log them here */
- if (irqs1 & (TWL4030_TBATOR2 | TWL4030_TBATOR1))
+ if (irqs1 & (TWL4030_TBATOR2 | TWL4030_TBATOR1)) {
dev_warn(bci->dev, "battery temperature out of range\n");
+ power_off = true;
+ }

- if (irqs1 & TWL4030_BATSTS)
+ if (irqs1 & TWL4030_BATSTS) {
dev_crit(bci->dev, "battery disconnected\n");
+ power_off = true;
+ }

- if (irqs2 & TWL4030_VBATOV)
+ if (irqs2 & TWL4030_VBATOV) {
dev_crit(bci->dev, "VBAT overvoltage\n");
+ power_off = true;
+ }

- if (irqs2 & TWL4030_VBUSOV)
+ if (irqs2 & TWL4030_VBUSOV) {
dev_crit(bci->dev, "VBUS overvoltage\n");
+ power_off = true;
+ }

- if (irqs2 & TWL4030_ACCHGOV)
+ if (irqs2 & TWL4030_ACCHGOV) {
dev_crit(bci->dev, "Ac charger overvoltage\n");
+ power_off = true;
+ }
+
+ /* Try to shutdown the system */
+ if (power_off) {
+ /* Disable chargers before shutting off */
+ twl4030_charger_enable_ac(false);
+ twl4030_charger_enable_usb(bci, false);
+ orderly_poweroff(true);
+ }

return IRQ_HANDLED;
}
--
1.7.9.5

--
Regards,
Nishanth Menon
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/