diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2017-03-30 07:20:37 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-03-30 07:20:37 -0700 |
commit | 225393f7b34b8d50f8c6131a5c6dca7c11126bbc (patch) | |
tree | 422a9f4bbd25695376765ecaa1d1e489b1b27b8c /drivers | |
parent | 1743983a435e023b1ef27726e9943a61eaeb8633 (diff) | |
parent | 688cf0d310ad8a6fe986148332f32b8224d0a32b (diff) |
Merge "power: qpnp-fg-gen3: Whitelist the values in profile integrity word"
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/power/supply/qcom/fg-core.h | 13 | ||||
-rw-r--r-- | drivers/power/supply/qcom/qpnp-fg-gen3.c | 63 |
2 files changed, 54 insertions, 22 deletions
diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h index 0e15752eb9d2..f2047592a94b 100644 --- a/drivers/power/supply/qcom/fg-core.h +++ b/drivers/power/supply/qcom/fg-core.h @@ -46,10 +46,13 @@ && (value) <= (right))) /* Awake votable reasons */ -#define SRAM_READ "fg_sram_read" -#define SRAM_WRITE "fg_sram_write" -#define PROFILE_LOAD "fg_profile_load" -#define DELTA_SOC "fg_delta_soc" +#define SRAM_READ "fg_sram_read" +#define SRAM_WRITE "fg_sram_write" +#define PROFILE_LOAD "fg_profile_load" +#define DELTA_SOC "fg_delta_soc" + +/* Delta BSOC votable reasons */ +#define DELTA_BSOC_IRQ_VOTER "fg_delta_bsoc_irq" #define DEBUG_PRINT_BUFFER_SIZE 64 /* 3 byte address + 1 space character */ @@ -330,6 +333,7 @@ struct fg_chip { struct fg_memif *sram; struct fg_irq_info *irqs; struct votable *awake_votable; + struct votable *delta_bsoc_irq_en_votable; struct fg_sram_param *sp; struct fg_alg_flag *alg_flags; int *debug_mask; @@ -370,7 +374,6 @@ struct fg_chip { bool esr_fcc_ctrl_en; bool soc_reporting_ready; bool esr_flt_cold_temp_en; - bool bsoc_delta_irq_en; bool slope_limit_en; bool use_ima_single_mode; struct completion soc_update; diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index aeffe1f154a1..59216a567662 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c @@ -1054,6 +1054,25 @@ static void fg_notify_charger(struct fg_chip *chip) fg_dbg(chip, FG_STATUS, "Notified charger on float voltage and FCC\n"); } +static int fg_delta_bsoc_irq_en_cb(struct votable *votable, void *data, + int enable, const char *client) +{ + struct fg_chip *chip = data; + + if (!chip->irqs[BSOC_DELTA_IRQ].irq) + return 0; + + if (enable) { + enable_irq(chip->irqs[BSOC_DELTA_IRQ].irq); + enable_irq_wake(chip->irqs[BSOC_DELTA_IRQ].irq); + } else { + disable_irq_wake(chip->irqs[BSOC_DELTA_IRQ].irq); + disable_irq(chip->irqs[BSOC_DELTA_IRQ].irq); + } + + return 0; +} + static int fg_awake_cb(struct votable *votable, void *data, int awake, const char *client) { @@ -1477,16 +1496,8 @@ static int fg_charge_full_update(struct fg_chip *chip) return 0; mutex_lock(&chip->charge_full_lock); - if (!chip->charge_done && chip->bsoc_delta_irq_en) { - disable_irq_wake(fg_irqs[BSOC_DELTA_IRQ].irq); - disable_irq_nosync(fg_irqs[BSOC_DELTA_IRQ].irq); - chip->bsoc_delta_irq_en = false; - } else if (chip->charge_done && !chip->bsoc_delta_irq_en) { - enable_irq(fg_irqs[BSOC_DELTA_IRQ].irq); - enable_irq_wake(fg_irqs[BSOC_DELTA_IRQ].irq); - chip->bsoc_delta_irq_en = true; - } - + vote(chip->delta_bsoc_irq_en_votable, DELTA_BSOC_IRQ_VOTER, + chip->charge_done, 0); rc = power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_HEALTH, &prop); if (rc < 0) { @@ -2198,6 +2209,17 @@ static bool is_profile_load_required(struct fg_chip *chip) /* Check if integrity bit is set */ if (val & PROFILE_LOAD_BIT) { fg_dbg(chip, FG_STATUS, "Battery profile integrity bit is set\n"); + + /* Whitelist the values */ + val &= ~PROFILE_LOAD_BIT; + if (val != HLOS_RESTART_BIT && val != BOOTLOADER_LOAD_BIT && + val != (BOOTLOADER_LOAD_BIT | BOOTLOADER_RESTART_BIT)) { + val |= PROFILE_LOAD_BIT; + pr_warn("Garbage value in profile integrity word: 0x%x\n", + val); + return true; + } + rc = fg_sram_read(chip, PROFILE_LOAD_WORD, PROFILE_LOAD_OFFSET, buf, PROFILE_COMP_LEN, FG_IMA_DEFAULT); if (rc < 0) { @@ -4023,6 +4045,9 @@ static void fg_cleanup(struct fg_chip *chip) if (chip->awake_votable) destroy_votable(chip->awake_votable); + if (chip->delta_bsoc_irq_en_votable) + destroy_votable(chip->delta_bsoc_irq_en_votable); + if (chip->batt_id_chan) iio_channel_release(chip->batt_id_chan); @@ -4064,7 +4089,15 @@ static int fg_gen3_probe(struct platform_device *pdev) chip); if (IS_ERR(chip->awake_votable)) { rc = PTR_ERR(chip->awake_votable); - return rc; + goto exit; + } + + chip->delta_bsoc_irq_en_votable = create_votable("FG_DELTA_BSOC_IRQ", + VOTE_SET_ANY, + fg_delta_bsoc_irq_en_cb, chip); + if (IS_ERR(chip->delta_bsoc_irq_en_votable)) { + rc = PTR_ERR(chip->delta_bsoc_irq_en_votable); + goto exit; } rc = fg_parse_dt(chip); @@ -4091,7 +4124,7 @@ static int fg_gen3_probe(struct platform_device *pdev) rc = fg_get_batt_id(chip); if (rc < 0) { pr_err("Error in getting battery id, rc:%d\n", rc); - return rc; + goto exit; } rc = fg_get_batt_profile(chip); @@ -4149,11 +4182,7 @@ static int fg_gen3_probe(struct platform_device *pdev) disable_irq_nosync(fg_irqs[SOC_UPDATE_IRQ].irq); /* Keep BSOC_DELTA_IRQ irq disabled until we require it */ - if (fg_irqs[BSOC_DELTA_IRQ].irq) { - disable_irq_wake(fg_irqs[BSOC_DELTA_IRQ].irq); - disable_irq_nosync(fg_irqs[BSOC_DELTA_IRQ].irq); - chip->bsoc_delta_irq_en = false; - } + rerun_election(chip->delta_bsoc_irq_en_votable); rc = fg_debugfs_create(chip); if (rc < 0) { |