Merge changes I2e8fcb4a,I0bbad22c,I22d2dbda,I3e5e92e3 into msm-3.4

* changes:
  power: pm8921-bms: use restart reason for usb detection
  mfd: pm8xxx: provide api to read restart reason
  power: pm8921-bms: report higher soc even when called within a second
  power: pm8921-bms: use consistent temperature units
diff --git a/drivers/mfd/pm8018-core.c b/drivers/mfd/pm8018-core.c
index b1b64cb..a91152f 100644
--- a/drivers/mfd/pm8018-core.c
+++ b/drivers/mfd/pm8018-core.c
@@ -45,7 +45,6 @@
 #define PM8018_REVISION_MASK	0x000F
 
 #define REG_PM8018_PON_CNTRL_3	0x01D
-#define PM8018_RESTART_REASON_MASK	0x07
 
 #define SINGLE_IRQ_RESOURCE(_name, _irq) \
 { \
@@ -61,6 +60,7 @@
 	struct mfd_cell					*mfd_regulators;
 	struct pm8xxx_regulator_core_platform_data	*regulator_cdata;
 	u32						rev_registers;
+	u8						restart_reason;
 };
 
 static int pm8018_readb(const struct device *dev, u16 addr, u8 *val)
@@ -125,6 +125,14 @@
 	return pmic->rev_registers & PM8018_REVISION_MASK;
 }
 
+static u8 pm8018_restart_reason(const struct device *dev)
+{
+	const struct pm8xxx_drvdata *pm8018_drvdata = dev_get_drvdata(dev);
+	const struct pm8018 *pmic = pm8018_drvdata->pm_chip_data;
+
+	return pmic->restart_reason;
+}
+
 static struct pm8xxx_drvdata pm8018_drvdata = {
 	.pmic_readb		= pm8018_readb,
 	.pmic_writeb		= pm8018_writeb,
@@ -133,6 +141,7 @@
 	.pmic_read_irq_stat	= pm8018_read_irq_stat,
 	.pmic_get_version	= pm8018_get_version,
 	.pmic_get_revision	= pm8018_get_revision,
+	.pmic_restart_reason	= pm8018_restart_reason,
 };
 
 static const struct resource gpio_cell_resources[] __devinitconst = {
@@ -516,17 +525,6 @@
 	return ret;
 }
 
-static const char * const pm8018_restart_reason[] = {
-	[0] = "Unknown",
-	[1] = "Triggered from CBL (external charger)",
-	[2] = "Triggered from KPD (power key press)",
-	[3] = "Triggered from CHG (usb charger insertion)",
-	[4] = "Triggered from SMPL (sudden momentary power loss)",
-	[5] = "Triggered from RTC (real time clock)",
-	[6] = "Triggered by Hard Reset",
-	[7] = "Triggered by General Purpose Trigger",
-};
-
 static const char * const pm8018_rev_names[] = {
 	[PM8XXX_REVISION_8018_TEST]	= "test",
 	[PM8XXX_REVISION_8018_1p0]	= "1.0",
@@ -594,8 +592,9 @@
 		pr_err("Cannot read restart reason rc=%d\n", rc);
 		goto err_read_rev;
 	}
-	val &= PM8018_RESTART_REASON_MASK;
-	pr_info("PMIC Restart Reason: %s\n", pm8018_restart_reason[val]);
+	val &= PM8XXX_RESTART_REASON_MASK;
+	pr_info("PMIC Restart Reason: %s\n", pm8xxx_restart_reason_str[val]);
+	pmic->restart_reason = val;
 
 	rc = pm8018_add_subdevices(pdata, pmic);
 	if (rc) {
diff --git a/drivers/mfd/pm8038-core.c b/drivers/mfd/pm8038-core.c
index b32932b..712a772 100644
--- a/drivers/mfd/pm8038-core.c
+++ b/drivers/mfd/pm8038-core.c
@@ -44,7 +44,6 @@
 #define PM8038_REVISION_MASK	0x000F
 
 #define REG_PM8038_PON_CNTRL_3	0x01D
-#define PM8038_RESTART_REASON_MASK	0x07
 
 #define SINGLE_IRQ_RESOURCE(_name, _irq) \
 { \
@@ -60,6 +59,7 @@
 	struct mfd_cell					*mfd_regulators;
 	struct pm8xxx_regulator_core_platform_data	*regulator_cdata;
 	u32						rev_registers;
+	u8						restart_reason;
 };
 
 static int pm8038_readb(const struct device *dev, u16 addr, u8 *val)
@@ -124,6 +124,14 @@
 	return pmic->rev_registers & PM8038_REVISION_MASK;
 }
 
+static u8 pm8038_restart_reason(const struct device *dev)
+{
+	const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
+	const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
+
+	return pmic->restart_reason;
+}
+
 static struct pm8xxx_drvdata pm8038_drvdata = {
 	.pmic_readb		= pm8038_readb,
 	.pmic_writeb		= pm8038_writeb,
@@ -132,6 +140,7 @@
 	.pmic_read_irq_stat	= pm8038_read_irq_stat,
 	.pmic_get_version	= pm8038_get_version,
 	.pmic_get_revision	= pm8038_get_revision,
+	.pmic_restart_reason	= pm8038_restart_reason,
 };
 
 static const struct resource gpio_cell_resources[] __devinitconst = {
@@ -674,17 +683,6 @@
 	return ret;
 }
 
-static const char * const pm8038_restart_reason[] = {
-	[0] = "Unknown",
-	[1] = "Triggered from CBL (external charger)",
-	[2] = "Triggered from KPD (power key press)",
-	[3] = "Triggered from CHG (usb charger insertion)",
-	[4] = "Triggered from SMPL (sudden momentary power loss)",
-	[5] = "Triggered from RTC (real time clock)",
-	[6] = "Triggered by Hard Reset",
-	[7] = "Triggered by General Purpose Trigger",
-};
-
 static const char * const pm8038_rev_names[] = {
 	[PM8XXX_REVISION_8038_TEST]	= "test",
 	[PM8XXX_REVISION_8038_1p0]	= "1.0",
@@ -753,8 +751,9 @@
 		pr_err("Cannot read restart reason rc=%d\n", rc);
 		goto err_read_rev;
 	}
-	val &= PM8038_RESTART_REASON_MASK;
-	pr_info("PMIC Restart Reason: %s\n", pm8038_restart_reason[val]);
+	val &= PM8XXX_RESTART_REASON_MASK;
+	pr_info("PMIC Restart Reason: %s\n", pm8xxx_restart_reason_str[val]);
+	pmic->restart_reason = val;
 
 	rc = pm8038_add_subdevices(pdata, pmic);
 	if (rc) {
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index f39a19f..7d63129 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -63,6 +63,7 @@
 	struct mfd_cell					*mfd_regulators;
 	struct pm8xxx_regulator_core_platform_data	*regulator_cdata;
 	u32						rev_registers;
+	u8						restart_reason;
 };
 
 static int pm8921_readb(const struct device *dev, u16 addr, u8 *val)
@@ -133,6 +134,14 @@
 	return pmic->rev_registers & PM8921_REVISION_MASK;
 }
 
+static u8 pm8921_restart_reason(const struct device *dev)
+{
+	const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
+	const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
+
+	return pmic->restart_reason;
+}
+
 static struct pm8xxx_drvdata pm8921_drvdata = {
 	.pmic_readb		= pm8921_readb,
 	.pmic_writeb		= pm8921_writeb,
@@ -141,6 +150,7 @@
 	.pmic_read_irq_stat	= pm8921_read_irq_stat,
 	.pmic_get_version	= pm8921_get_version,
 	.pmic_get_revision	= pm8921_get_revision,
+	.pmic_restart_reason	= pm8921_restart_reason,
 };
 
 static struct resource gpio_cell_resources[] = {
@@ -815,17 +825,6 @@
 	return ret;
 }
 
-static const char * const pm8921_restart_reason[] = {
-	[0] = "Unknown",
-	[1] = "Triggered from CBL (external charger)",
-	[2] = "Triggered from KPD (power key press)",
-	[3] = "Triggered from CHG (usb charger insertion)",
-	[4] = "Triggered from SMPL (sudden momentary power loss)",
-	[5] = "Triggered from RTC (real time clock)",
-	[6] = "Triggered by Hard Reset",
-	[7] = "Triggered by General Purpose Trigger",
-};
-
 static const char * const pm8921_rev_names[] = {
 	[PM8XXX_REVISION_8921_TEST]	= "test",
 	[PM8XXX_REVISION_8921_1p0]	= "1.0",
@@ -918,8 +917,9 @@
 		pr_err("Cannot read restart reason rc=%d\n", rc);
 		goto err_read_rev;
 	}
-	val &= PM8921_RESTART_REASON_MASK;
-	pr_info("PMIC Restart Reason: %s\n", pm8921_restart_reason[val]);
+	val &= PM8XXX_RESTART_REASON_MASK;
+	pr_info("PMIC Restart Reason: %s\n", pm8xxx_restart_reason_str[val]);
+	pmic->restart_reason = val;
 
 	rc = pm8921_add_subdevices(pdata, pmic);
 	if (rc) {
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 2868d61..16d04a1 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -346,13 +346,18 @@
 	return 0;
 }
 
-static int usb_chg_plugged_in(void)
+static int usb_chg_plugged_in(struct pm8921_bms_chip *chip)
 {
 	int val = pm8921_is_usb_chg_plugged_in();
 
-	/* treat as if usb is not present in case of error */
-	if (val == -EINVAL)
-		val = 0;
+	/* if the charger driver was not initialized, use the restart reason */
+	if (val == -EINVAL) {
+		if (pm8xxx_restart_reason(chip->dev->parent)
+				== PM8XXX_RESTART_CHG)
+			val = 1;
+		else
+			val = 0;
+	}
 
 	return val;
 }
@@ -814,28 +819,26 @@
 }
 
 static int interpolate_pc(struct pm8921_bms_chip *chip,
-				int batt_temp, int ocv)
+				int batt_temp_degc, int ocv)
 {
 	int i, j, pcj, pcj_minus_one, pc;
 	int rows = chip->pc_temp_ocv_lut->rows;
 	int cols = chip->pc_temp_ocv_lut->cols;
 
-	/* batt_temp is in tenths of degC - convert it to degC for lookups */
-	batt_temp = batt_temp/10;
 
-	if (batt_temp < chip->pc_temp_ocv_lut->temp[0]) {
-		pr_debug("batt_temp %d < known temp range for pc\n", batt_temp);
-		batt_temp = chip->pc_temp_ocv_lut->temp[0];
+	if (batt_temp_degc < chip->pc_temp_ocv_lut->temp[0]) {
+		pr_debug("batt_temp %d < known temp range\n", batt_temp_degc);
+		batt_temp_degc = chip->pc_temp_ocv_lut->temp[0];
 	}
-	if (batt_temp > chip->pc_temp_ocv_lut->temp[cols - 1]) {
-		pr_debug("batt_temp %d > known temp range for pc\n", batt_temp);
-		batt_temp = chip->pc_temp_ocv_lut->temp[cols - 1];
+	if (batt_temp_degc > chip->pc_temp_ocv_lut->temp[cols - 1]) {
+		pr_debug("batt_temp %d > known temp range\n", batt_temp_degc);
+		batt_temp_degc = chip->pc_temp_ocv_lut->temp[cols - 1];
 	}
 
 	for (j = 0; j < cols; j++)
-		if (batt_temp <= chip->pc_temp_ocv_lut->temp[j])
+		if (batt_temp_degc <= chip->pc_temp_ocv_lut->temp[j])
 			break;
-	if (batt_temp == chip->pc_temp_ocv_lut->temp[j]) {
+	if (batt_temp_degc == chip->pc_temp_ocv_lut->temp[j]) {
 		/* found an exact match for temp in the table */
 		if (ocv >= chip->pc_temp_ocv_lut->ocv[0][j])
 			return chip->pc_temp_ocv_lut->percent[0];
@@ -858,7 +861,7 @@
 	}
 
 	/*
-	 * batt_temp is within temperature for
+	 * batt_temp_degc is within temperature for
 	 * column j-1 and j
 	 */
 	if (ocv >= chip->pc_temp_ocv_lut->ocv[0][j])
@@ -898,7 +901,7 @@
 				chip->pc_temp_ocv_lut->temp[j-1],
 				pcj,
 				chip->pc_temp_ocv_lut->temp[j],
-				batt_temp);
+				batt_temp_degc);
 			return pc;
 		}
 	}
@@ -910,7 +913,7 @@
 		return pcj_minus_one;
 
 	pr_debug("%d ocv wasn't found for temp %d in the LUT returning 100%%",
-							ocv, batt_temp);
+							ocv, batt_temp_degc);
 	return 100;
 }
 
@@ -944,7 +947,7 @@
 
 	mutex_unlock(&the_chip->bms_output_lock);
 
-	usb_chg = usb_chg_plugged_in();
+	usb_chg = usb_chg_plugged_in(the_chip);
 
 	convert_vbatt_raw_to_uv(the_chip, usb_chg, vbat_raw, vbat_uv);
 	convert_vsense_to_uv(the_chip, vsense_raw, &vsense_uv);
@@ -985,7 +988,7 @@
 	pm_bms_unlock_output_data(chip);
 	mutex_unlock(&chip->bms_output_lock);
 
-	usb_chg =  usb_chg_plugged_in();
+	usb_chg =  usb_chg_plugged_in(chip);
 
 	if (chip->prev_last_good_ocv_raw == 0) {
 		chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
@@ -1120,7 +1123,7 @@
 {
 	int pc, scalefactor;
 
-	pc = interpolate_pc(chip, batt_temp, ocv_uv / 1000);
+	pc = interpolate_pc(chip, batt_temp / 10, ocv_uv / 1000);
 	pr_debug("pc = %u for ocv = %dmicroVolts batt_temp = %d\n",
 					pc, ocv_uv, batt_temp);
 
@@ -1876,10 +1879,6 @@
 	if (the_chip->start_percent == -EINVAL)
 		return prev_soc;
 
-	/* if soc is called in quick succession return the last soc */
-	if (delta_time_us < USEC_PER_SEC)
-		return prev_soc;
-
 	chg_time_sec = DIV_ROUND_UP(the_chip->charge_time_us, USEC_PER_SEC);
 	catch_up_sec = DIV_ROUND_UP(the_chip->catch_up_time_us, USEC_PER_SEC);
 	pr_debug("cts= %d catch_up_sec = %d\n", chg_time_sec, catch_up_sec);
@@ -2251,7 +2250,7 @@
 	}
 	voltage = xoadc_reading_to_microvolt(result.adc_code);
 
-	usb_chg = usb_chg_plugged_in();
+	usb_chg = usb_chg_plugged_in(chip);
 	pr_debug("result 0.625V = 0x%x, voltage = %duV adc_meas = %lld "
 				"usb_chg = %d\n",
 				result.adc_code, voltage, result.measurement,
@@ -2738,7 +2737,7 @@
 	 */
 	ocv_uv = 0;
 	pm_bms_read_output_data(chip, LAST_GOOD_OCV_VALUE, &ocv_raw);
-	usb_chg = usb_chg_plugged_in();
+	usb_chg = usb_chg_plugged_in(chip);
 	rc = convert_vbatt_raw_to_uv(chip, usb_chg, ocv_raw, &ocv_uv);
 	if (rc || ocv_uv == 0) {
 		rc = adc_based_ocv(chip, &ocv_uv);
diff --git a/include/linux/mfd/pm8xxx/core.h b/include/linux/mfd/pm8xxx/core.h
index 08e9014..38c589d 100644
--- a/include/linux/mfd/pm8xxx/core.h
+++ b/include/linux/mfd/pm8xxx/core.h
@@ -75,6 +75,27 @@
 #define PM8XXX_REVISION_8917_TEST	0
 #define PM8XXX_REVISION_8917_1p0	1
 
+#define PM8XXX_RESTART_UNKNOWN		0
+#define PM8XXX_RESTART_CBL		1
+#define PM8XXX_RESTART_KPD		2
+#define PM8XXX_RESTART_CHG		3
+#define PM8XXX_RESTART_SMPL		4
+#define PM8XXX_RESTART_RTC		5
+#define PM8XXX_RESTART_HARD_RESET	6
+#define PM8XXX_RESTART_GEN_PURPOSE	7
+#define PM8XXX_RESTART_REASON_MASK	0x07
+
+static const char * const pm8xxx_restart_reason_str[] = {
+	[0] = "Unknown",
+	[1] = "Triggered from CBL (external charger)",
+	[2] = "Triggered from KPD (power key press)",
+	[3] = "Triggered from CHG (usb charger insertion)",
+	[4] = "Triggered from SMPL (sudden momentary power loss)",
+	[5] = "Triggered from RTC (real time clock)",
+	[6] = "Triggered by Hard Reset",
+	[7] = "Triggered by General Purpose Trigger",
+};
+
 struct pm8xxx_drvdata {
 	int			(*pmic_readb) (const struct device *dev,
 						u16 addr, u8 *val);
@@ -88,6 +109,8 @@
 						int irq);
 	enum pm8xxx_version	(*pmic_get_version) (const struct device *dev);
 	int			(*pmic_get_revision) (const struct device *dev);
+	u8			(*pmic_restart_reason)
+						(const struct device *dev);
 	void			*pm_chip_data;
 };
 
@@ -156,4 +179,12 @@
 	return dd->pmic_get_revision(dev);
 }
 
+static inline u8 pm8xxx_restart_reason(const struct device *dev)
+{
+	struct pm8xxx_drvdata *dd = dev_get_drvdata(dev);
+
+	if (!dd)
+		return -EINVAL;
+	return dd->pmic_restart_reason(dev);
+}
 #endif