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