From 8bb83bb77e1abed35bf8e3e38cba2ee883353ffd Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Fri, 3 Feb 2017 11:18:22 +0530 Subject: [PATCH 1/4] qcom: battery: fix parallel psy name Parallel charger registers to power supply framework with name "parallel" instead of "usb-parallel" thus update all references of "usb-parallel" with "parallel". While at it, remove extra NULL pointer check of pl_psy in parallel enable path. CRs-Fixed: 2001651 Change-Id: I4150808f7122cef970296553fb70671df12aced9 Signed-off-by: Ashay Jaiswal --- drivers/power/supply/qcom/battery.c | 27 ++++++++++++++------------- drivers/power/supply/qcom/smb-lib.c | 5 ++--- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index 5f1b6b294b5f..6f9fc667bc0e 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -82,7 +82,7 @@ enum { static void split_settled(struct pl_data *chip) { int slave_icl_pct; - int slave_ua; + int slave_ua = 0; union power_supply_propval pval = {0, }; int rc; @@ -94,11 +94,9 @@ static void split_settled(struct pl_data *chip) if (chip->pl_mode != POWER_SUPPLY_PARALLEL_USBIN_USBIN) return; - if (chip->main_psy) + if (!chip->main_psy) return; - slave_ua = 0; - if (!get_effective_result_locked(chip->pl_disable_votable)) { /* read the aicl settled value */ rc = power_supply_get_property(chip->main_psy, @@ -375,15 +373,17 @@ static int pl_disable_vote_callback(struct votable *votable, if (!pl_disable) { /* enable */ rerun_election(chip->fv_votable); rerun_election(chip->fcc_votable); - - if (chip->pl_psy) { - pval.intval = 0; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval); - if (rc < 0) - pr_err("Couldn't change slave suspend state rc=%d\n", - rc); - } + /* + * Enable will be called with a valid pl_psy always. The + * PARALLEL_PSY_VOTER keeps it disabled unless a pl_psy + * is seen. + */ + pval.intval = 0; + rc = power_supply_set_property(chip->pl_psy, + POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval); + if (rc < 0) + pr_err("Couldn't change slave suspend state rc=%d\n", + rc); if (chip->pl_mode == POWER_SUPPLY_PARALLEL_USBIN_USBIN) split_settled(chip); @@ -406,6 +406,7 @@ static int pl_disable_vote_callback(struct votable *votable, if (chip->pl_mode == POWER_SUPPLY_PARALLEL_USBIN_USBIN) split_settled(chip); + /* pl_psy may be NULL while in the disable branch */ if (chip->pl_psy) { pval.intval = 1; rc = power_supply_set_property(chip->pl_psy, diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 5faa05c1c270..ee87b312963f 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -505,7 +505,7 @@ static int smblib_notifier_call(struct notifier_block *nb, schedule_work(&chg->bms_update_work); } - if (!chg->pl.psy && !strcmp(psy->desc->name, "usb-parallel")) + if (!chg->pl.psy && !strcmp(psy->desc->name, "parallel")) chg->pl.psy = psy; return NOTIFY_OK; @@ -3538,8 +3538,7 @@ int smblib_init(struct smb_charger *chg) } chg->bms_psy = power_supply_get_by_name("bms"); - chg->pl.psy = power_supply_get_by_name("usb-parallel"); - + chg->pl.psy = power_supply_get_by_name("parallel"); break; case PARALLEL_SLAVE: break; From 095a8e42469cccf99867ffedd36b11cb781113bc Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Fri, 3 Feb 2017 11:25:36 +0530 Subject: [PATCH 2/4] qcom: battery: fix taper entry handling Move Taper entry check before charge enable check in "handle_main_charge_type" to make sure TAPER entry is handled properly. CRs-Fixed: 2001651 Change-Id: Id7c3f48b66ba8df20ca2be022565d8bf0e38379b Signed-off-by: Ashay Jaiswal --- drivers/power/supply/qcom/battery.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index 6f9fc667bc0e..78c51e563953 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -501,15 +501,6 @@ static void handle_main_charge_type(struct pl_data *chip) return; } - /* handle fast/taper charge entry */ - if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER - || pval.intval == POWER_SUPPLY_CHARGE_TYPE_FAST) { - pl_dbg(chip, PR_PARALLEL, "chg_state enabling parallel\n"); - vote(chip->pl_disable_votable, CHG_STATE_VOTER, false, 0); - chip->charge_type = pval.intval; - return; - } - /* handle taper charge entry */ if (chip->charge_type == POWER_SUPPLY_CHARGE_TYPE_FAST && (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER)) { @@ -519,6 +510,15 @@ static void handle_main_charge_type(struct pl_data *chip) return; } + /* handle fast/taper charge entry */ + if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER + || pval.intval == POWER_SUPPLY_CHARGE_TYPE_FAST) { + pl_dbg(chip, PR_PARALLEL, "chg_state enabling parallel\n"); + vote(chip->pl_disable_votable, CHG_STATE_VOTER, false, 0); + chip->charge_type = pval.intval; + return; + } + /* remember the new state only if it isn't any of the above */ chip->charge_type = pval.intval; } From 060f26470afc1f3d5d45f373bc4b7c0c2bb1aefb Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Fri, 3 Feb 2017 11:35:27 +0530 Subject: [PATCH 3/4] qcom: battery: add voting support for handling wakeup source Add a new votable in parallel driver to support wakeup source handling via pmic-voter framework. CRs-Fixed: 2001651 Change-Id: Ia2c67d76081c36508d1ad3c3cb3a0be4c1a55814 Signed-off-by: Ashay Jaiswal --- drivers/power/supply/qcom/battery.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index 78c51e563953..34add97b55d2 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -42,6 +42,7 @@ struct pl_data { struct votable *fcc_votable; struct votable *fv_votable; struct votable *pl_disable_votable; + struct votable *pl_awake_votable; struct work_struct status_change_work; struct delayed_work pl_taper_work; struct power_supply *main_psy; @@ -212,7 +213,7 @@ static void pl_taper_work(struct work_struct *work) if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) { pl_dbg(chip, PR_PARALLEL, "master is taper charging; reducing slave FCC\n"); - __pm_stay_awake(chip->pl_ws); + vote(chip->pl_awake_votable, TAPER_END_VOTER, true, 0); /* Reduce the taper percent by 25 percent */ chip->taper_pct = chip->taper_pct * TAPER_RESIDUAL_PCT / 100; rerun_election(chip->fcc_votable); @@ -229,7 +230,7 @@ static void pl_taper_work(struct work_struct *work) pl_dbg(chip, PR_PARALLEL, "master is fast charging; waiting for next taper\n"); done: - __pm_relax(chip->pl_ws); + vote(chip->pl_awake_votable, TAPER_END_VOTER, false, 0); } /********* @@ -425,6 +426,20 @@ static int pl_disable_vote_callback(struct votable *votable, return 0; } +static int pl_awake_vote_callback(struct votable *votable, + void *data, int awake, const char *client) +{ + struct pl_data *chip = data; + + if (awake) + __pm_stay_awake(chip->pl_ws); + else + __pm_relax(chip->pl_ws); + + pr_debug("client: %s awake: %d\n", client, awake); + return 0; +} + static bool is_main_available(struct pl_data *chip) { if (!chip->main_psy) @@ -672,6 +687,14 @@ static int pl_init(void) vote(chip->pl_disable_votable, TAPER_END_VOTER, false, 0); vote(chip->pl_disable_votable, PARALLEL_PSY_VOTER, true, 0); + chip->pl_awake_votable = create_votable("PL_AWAKE", VOTE_SET_ANY, + pl_awake_vote_callback, + chip); + if (IS_ERR(chip->pl_awake_votable)) { + rc = PTR_ERR(chip->pl_disable_votable); + goto destroy_votable; + } + INIT_WORK(&chip->status_change_work, status_change_work); INIT_DELAYED_WORK(&chip->pl_taper_work, pl_taper_work); @@ -702,6 +725,7 @@ static int pl_init(void) unreg_notifier: power_supply_unreg_notifier(&chip->nb); destroy_votable: + destroy_votable(chip->pl_awake_votable); destroy_votable(chip->pl_disable_votable); destroy_votable(chip->fv_votable); destroy_votable(chip->fcc_votable); @@ -717,6 +741,7 @@ static void pl_deinit(void) struct pl_data *chip = the_chip; power_supply_unreg_notifier(&chip->nb); + destroy_votable(chip->pl_awake_votable); destroy_votable(chip->pl_disable_votable); destroy_votable(chip->fv_votable); destroy_votable(chip->fcc_votable); From 846583572adbf074e5a8dd1480b8e6e727170651 Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Fri, 3 Feb 2017 11:37:28 +0530 Subject: [PATCH 4/4] qcom: battery: reorganize creation of votables in SMB library Move all "find_votable" requests before any voter creation in smb library to prevent multiple creation/destruction of votables due to probe-deferrals. CRs-Fixed: 2001651 Change-Id: I03cb30775720a53ad24e1c5d5e075d7442b2729c Signed-off-by: Ashay Jaiswal --- drivers/power/supply/qcom/smb-lib.c | 38 ++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index ee87b312963f..6bb8f6b9abf9 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -3338,6 +3338,25 @@ static int smblib_create_votables(struct smb_charger *chg) { int rc = 0; + chg->fcc_votable = find_votable("FCC"); + if (!chg->fcc_votable) { + rc = -EPROBE_DEFER; + return rc; + } + + chg->fv_votable = find_votable("FV"); + if (!chg->fv_votable) { + rc = -EPROBE_DEFER; + return rc; + } + + chg->pl_disable_votable = find_votable("PL_DISABLE"); + if (!chg->pl_disable_votable) { + rc = -EPROBE_DEFER; + return rc; + } + vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0); + chg->usb_suspend_votable = create_votable("USB_SUSPEND", VOTE_SET_ANY, smblib_usb_suspend_vote_callback, chg); @@ -3362,18 +3381,6 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } - chg->fcc_votable = find_votable("FCC"); - if (!chg->fcc_votable) { - rc = -EPROBE_DEFER; - return rc; - } - - chg->fv_votable = find_votable("FV"); - if (!chg->fv_votable) { - rc = -EPROBE_DEFER; - return rc; - } - chg->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN, smblib_usb_icl_vote_callback, chg); @@ -3413,13 +3420,6 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } - chg->pl_disable_votable = find_votable("PL_DISABLE"); - if (!chg->pl_disable_votable) { - rc = -EPROBE_DEFER; - return rc; - } - vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0); - chg->chg_disable_votable = create_votable("CHG_DISABLE", VOTE_SET_ANY, smblib_chg_disable_vote_callback, chg);