(Bug 6017 - [PnP]Battery Status Update slowly.)

Notify property is changed.

Signed-off-by: Major Lee <major_lee@wistron.com>
---
--- linux-2.6.37.bak/drivers/power/intel_pmic_battery.c	2011-07-28 08:54:17.453125000 +0800
+++ linux-2.6.37/drivers/power/intel_pmic_battery.c	2011-07-28 08:55:01.054497551 +0800
@@ -109,6 +109,7 @@ struct pmic_power_info {
 	unsigned int batt_prev_charge_full;	/* in mAS */
 	unsigned int batt_charge_rate;		/* in units per second */
 	unsigned int batt_charge_full_des;	/* in mAS */
+	unsigned int batt_status_prev;
 
 	struct power_supply adap;
 	struct power_supply batt;
@@ -580,6 +581,7 @@ static void pmic_battery_read_status(str
 	 * read.
 	 */
 
+	mutex_lock(&pbi->status_lock);
 	/* set batt_is_present */
 	if (r8 & PMIC_BATT_CHR_SBATDET_MASK) {
 		pbi->batt_is_present = PMIC_BATT_PRESENT;
@@ -668,7 +670,19 @@ static void pmic_battery_read_status(str
 	else
 		pbi->batt_charge_now = 0;
 
-	pbi->is_dev_info_updated = PMIC_BATT_DRV_INFO_UPDATED;
+	if (pbi->is_dev_info_updated) {
+		/* update iff batt_status is changed */
+		if (pbi->batt_status != pbi->batt_status_prev) {
+			pbi->batt_status_prev = pbi->batt_status;
+			mutex_unlock(&pbi->status_lock);
+			power_supply_changed(&pbi->batt);
+		} else
+			mutex_unlock(&pbi->status_lock);
+	} else {
+		pbi->batt_status_prev = pbi->batt_status;
+		pbi->is_dev_info_updated = PMIC_BATT_DRV_INFO_UPDATED;
+		mutex_unlock(&pbi->status_lock);
+	}
 }
 
 /* pmic_adapter_get_property - adapter power source get property */
@@ -679,11 +693,7 @@ static int pmic_adapter_get_property(str
 	struct pmic_power_info *pbi = container_of(psy,
 				struct pmic_power_info, adap);
 
-	/* update pmic_power_info members */
 	mutex_lock(&pbi->status_lock);
-	pmic_battery_read_status(pbi, BATT_INFO_PACKET_NONE);
-	mutex_unlock(&pbi->status_lock);
-
 	switch (psp) {
 	case POWER_SUPPLY_PROP_PRESENT:
 		val->intval = pbi->adap_is_present;
@@ -692,8 +702,10 @@ static int pmic_adapter_get_property(str
 		val->intval = pbi->adap_health;
 		break;
 	default:
+		mutex_unlock(&pbi->status_lock);
 		return -EINVAL;
 	}
+	mutex_unlock(&pbi->status_lock);
 
 	return 0;
 }
@@ -731,11 +743,7 @@ static int pmic_battery_get_property(str
 	struct pmic_power_info *pbi = container_of(psy,
 				struct pmic_power_info, batt);
 
-	/* update pmic_power_info members */
 	mutex_lock(&pbi->status_lock);
-	pmic_battery_read_status(pbi, BATT_INFO_PACKET_NONE);
-	mutex_unlock(&pbi->status_lock);
-
 	switch (psp) {
 	case POWER_SUPPLY_PROP_STATUS:
 		val->intval = pbi->batt_status;
@@ -782,8 +790,10 @@ static int pmic_battery_get_property(str
 								pbi->batt_prev_charge_full);
 		break;
 	default:
+		mutex_unlock(&pbi->status_lock);
 		return -EINVAL;
 	}
+	mutex_unlock(&pbi->status_lock);
 
 	return 0;
 }
@@ -795,9 +805,7 @@ static void pmic_battery_monitor(struct 
 			struct pmic_power_info, monitor_battery.work);
 
 	/* update pmic_power_info members */
-	mutex_lock(&pbi->status_lock);
 	pmic_battery_read_status(pbi, BATT_INFO_PACKET_MONITOR);
-	mutex_unlock(&pbi->status_lock);
 
 	/* update batt_info ring buffer */
 	mutex_lock(&batt_info_rw_lock);
@@ -838,12 +846,15 @@ static void pmic_adaptor_handle_intrpt(s
 				struct pmic_power_info, adap_handler);
 	int val = gpio_get_value(PMIC_GPIO_0);
 
+	mutex_lock(&pbi->status_lock);
 	if (val) {
 		pbi->adap_is_present = PMIC_ADAP_PRESENT;
 	} else {
 		pbi->adap_is_present = PMIC_ADAP_NOT_PRESENT;
 		pbi->adap_health = POWER_SUPPLY_HEALTH_UNKNOWN;
 	}
+	mutex_unlock(&pbi->status_lock);
+	power_supply_changed(&pbi->adap);
 }
 
 /* pmic_battery_interrupt_handler - pmic battery interrupt handler */
@@ -866,6 +877,7 @@ static void pmic_battery_handle_intrpt(s
 	if (pmic_scu_ipc_ioread8(pbi, PMIC_BATT_CHR_SCHRGINT_ADDR, &r8))
 		return;
 
+	mutex_lock(&pbi->status_lock);
 	/* find the cause of the interrupt */
 	if (r8 & PMIC_BATT_CHR_SBATDET_MASK) {
 		pbi->batt_is_present = PMIC_BATT_PRESENT;
@@ -873,6 +885,8 @@ static void pmic_battery_handle_intrpt(s
 		pbi->batt_is_present = PMIC_BATT_NOT_PRESENT;
 		pbi->batt_health = POWER_SUPPLY_HEALTH_UNKNOWN;
 		pbi->batt_status = POWER_SUPPLY_STATUS_UNKNOWN;
+		mutex_unlock(&pbi->status_lock);
+		power_supply_changed(&pbi->batt);
 		return;
 	}
 
@@ -885,6 +899,9 @@ static void pmic_battery_handle_intrpt(s
 			pmic_scu_ipc_set_charger(7);
 			pmic_battery_log_event(pbi, BATT_EVENT_EXCPT);
 		}
+		mutex_unlock(&pbi->status_lock);
+		power_supply_changed(&pbi->adap);
+		power_supply_changed(&pbi->batt);
 		return;
 	} else {
 		pbi->batt_health = POWER_SUPPLY_HEALTH_GOOD;
@@ -897,12 +914,17 @@ static void pmic_battery_handle_intrpt(s
 
 		if (pmic_scu_ipc_battery_cc_read(&ccval)) {
 			dev_warn(pbi->dev, "%s: ipc config cmd failed\n", __func__);
+			mutex_unlock(&pbi->status_lock);
+			power_supply_changed(&pbi->adap);
+			power_supply_changed(&pbi->batt);
 			return;
 		}
 
 		pbi->batt_prev_charge_full = ccval & PMIC_BATT_ADC_ACCCHRGVAL_MASK;
-		return;
 	}
+	mutex_unlock(&pbi->status_lock);
+	power_supply_changed(&pbi->adap);
+	power_supply_changed(&pbi->batt);
 }
 
 /* sysfs */
@@ -1372,9 +1394,7 @@ static int __devinit platform_pmic_batte
 	pbi->batt_prev_charge_full = batt_prop.capacity;
 
 	/* update pmic_power_info members */
-	mutex_lock(&pbi->status_lock);
 	pmic_battery_read_status(pbi, BATT_INFO_PACKET_OCV);
-	mutex_unlock(&pbi->status_lock);
 
 	/* update batt_info ring buffer */
 	mutex_lock(&batt_info_rw_lock);
