[Meego-kernel] [RFC/PATCH] intel_mid_battery/intel_pmic_battery: Fix over battery charge current exception

Major_Lee at wistron.com Major_Lee at wistron.com
Fri May 13 01:22:18 PDT 2011


If over battery charge current is detected, Renesas PMIC will trigger an
interrupt and reduce charger current automatically.
Do nothing when this interrupt is triggered, and log once in
pmic_battery_read_status().
 
Adapter detection will be done in adapter detection interrupt handler,
and will also be checked in pmic_battery_read_status().
Add adapter detection in pmic_battery_read_status().
 
Signed-off-by: Major Lee <major_lee at wistron.com>
---

--- linux-2.6.37.bak/drivers/power/intel_mid_battery.c	2011-05-12
11:57:59.840232580 +0800
+++ linux-2.6.37/drivers/power/intel_mid_battery.c	2011-05-13
15:50:52.421875000 +0800
@@ -97,6 +97,8 @@ struct pmic_power_module_info {
 	unsigned int batt_prev_charge_full;	/* in mAS */
 	unsigned int batt_charge_rate;		/* in units per second
*/
 
+	bool dclmt_excpt_log_flag;
+
 	struct power_supply usb;
 	struct power_supply batt;
 	int irq;				/* GPE_ID or IRQ# */
@@ -291,10 +293,13 @@ static void pmic_battery_read_status(str
 			pmic_battery_log_event(BATT_EVENT_BATOVP_EXCPT);
 			batt_exception = 1;
 		} else if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) {
-			pbi->batt_health =
POWER_SUPPLY_HEALTH_OVERVOLTAGE;
-			pbi->batt_status =
POWER_SUPPLY_STATUS_NOT_CHARGING;
-			pmic_battery_log_event(BATT_EVENT_DCLMT_EXCPT);
-			batt_exception = 1;
+			pbi->batt_health = POWER_SUPPLY_HEALTH_GOOD;
+			if (!pbi->dclmt_excpt_log_flag) {
+				/* if over current is detected, log once
*/
+
pmic_battery_log_event(BATT_EVENT_DCLMT_EXCPT);
+				pbi->dclmt_excpt_log_flag = 1;
+			}
+			batt_exception = 0;
 		} else if (r8 & PMIC_BATT_CHR_STEMP_MASK) {
 			pbi->batt_health = POWER_SUPPLY_HEALTH_OVERHEAT;
 			pbi->batt_status =
POWER_SUPPLY_STATUS_NOT_CHARGING;
@@ -306,7 +311,7 @@ static void pmic_battery_read_status(str
 	}
 
 	/* set usb_is_present */
-	if (r8 & PMIC_BATT_CHR_SUSBDET_MASK) {
+	if ((r8 & PMIC_BATT_CHR_SUSBDET_MASK) ||
gpio_get_value(PMIC_GPIO_0)) {
 		pbi->usb_is_present = PMIC_USB_PRESENT;
 		usb_present = 1;
 	} else {
@@ -509,6 +514,7 @@ static void pmic_adaptor_handle_intrpt(s
 
 	if (val) {
 		pbi->usb_is_present = PMIC_USB_PRESENT;
+		pbi->dclmt_excpt_log_flag = 0;
 	} else {
 		pbi->usb_is_present = PMIC_USB_NOT_PRESENT;
 		pbi->usb_health = POWER_SUPPLY_HEALTH_UNKNOWN;
@@ -553,6 +559,12 @@ static void pmic_battery_handle_intrpt(s
 
__func__);
 		return;
 	}
+
+	if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) {
+		/* PMIC will reduce charger current automatically */
+		return;
+	}
+
 	/* find the cause of the interrupt */
 	if (r8 & PMIC_BATT_CHR_SBATDET_MASK) {
 		pbi->batt_is_present = PMIC_BATT_PRESENT;
--- linux-2.6.37.bak/drivers/power/intel_pmic_battery.c	2011-05-12
11:57:59.850223025 +0800
+++ linux-2.6.37/drivers/power/intel_pmic_battery.c	2011-05-13
15:51:08.937500000 +0800
@@ -30,7 +30,7 @@
 #include <asm/intel_scu_ipc.h>
 
 #define DRIVER_NAME		"pmic_battery"
-#define DRIVER_VERSION	"Version 0.2.0"
+#define DRIVER_VERSION	"Version 0.2.1"
 
 /*********************************************************************
  *		Generic defines
@@ -110,6 +110,8 @@ struct pmic_power_info {
 	unsigned int batt_charge_rate;		/* in units per second
*/
 	unsigned int batt_charge_full_des;	/* in mAS */
 
+	bool dclmt_excpt_log_flag;
+
 	struct power_supply adap;
 	struct power_supply batt;
 	int irq;
@@ -598,10 +600,13 @@ static void pmic_battery_read_status(str
 			pmic_battery_log_event(pbi,
BATT_EVENT_BATOVP_EXCPT);
 			batt_exception = 1;
 		} else if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) {
-			pbi->batt_health =
POWER_SUPPLY_HEALTH_OVERVOLTAGE;
-			pbi->batt_status =
POWER_SUPPLY_STATUS_NOT_CHARGING;
-			pmic_battery_log_event(pbi,
BATT_EVENT_DCLMT_EXCPT);
-			batt_exception = 1;
+			pbi->batt_health = POWER_SUPPLY_HEALTH_GOOD;
+			if (!pbi->dclmt_excpt_log_flag) {
+				/* if over current is detected, log once
*/
+				pmic_battery_log_event(pbi,
BATT_EVENT_DCLMT_EXCPT);
+				pbi->dclmt_excpt_log_flag = 1;
+			}
+			batt_exception = 0;
 		} else if (r8 & PMIC_BATT_CHR_STEMP_MASK) {
 			pbi->batt_health = POWER_SUPPLY_HEALTH_OVERHEAT;
 			pbi->batt_status =
POWER_SUPPLY_STATUS_NOT_CHARGING;
@@ -613,7 +618,7 @@ static void pmic_battery_read_status(str
 	}
 
 	/* set adap_is_present */
-	if (r8 & PMIC_BATT_CHR_SUSBDET_MASK) {
+	if (gpio_get_value(PMIC_GPIO_0)) {
 		pbi->adap_is_present = PMIC_ADAP_PRESENT;
 		adap_present = 1;
 	} else {
@@ -841,6 +846,7 @@ static void pmic_adaptor_handle_intrpt(s
 
 	if (val) {
 		pbi->adap_is_present = PMIC_ADAP_PRESENT;
+		pbi->dclmt_excpt_log_flag = 0;
 	} else {
 		pbi->adap_is_present = PMIC_ADAP_NOT_PRESENT;
 		pbi->adap_health = POWER_SUPPLY_HEALTH_UNKNOWN;
@@ -867,6 +873,11 @@ static void pmic_battery_handle_intrpt(s
 	if (pmic_scu_ipc_ioread8(pbi, PMIC_BATT_CHR_SCHRGINT_ADDR, &r8))
 		return;
 
+	if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) {
+		/* PMIC will reduce charger current automatically */
+		return;
+	}
+
 	/* find the cause of the interrupt */
 	if (r8 & PMIC_BATT_CHR_SBATDET_MASK) {
 		pbi->batt_is_present = PMIC_BATT_PRESENT;


More information about the MeeGo-kernel mailing list