Loading drivers/power/pmic-voter.c +42 −15 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct votable { int type; int effective_client_id; int effective_result; int default_result; struct mutex vote_lock; int (*callback)(struct device *dev, int effective_result, Loading @@ -46,7 +47,7 @@ static int vote_set_any(struct votable *votable) int i; for (i = 0; i < votable->num_clients; i++) if (votable->votes[i].state) if (votable->votes[i].state == 1) return 1; return 0; } Loading @@ -54,11 +55,11 @@ static int vote_set_any(struct votable *votable) static int vote_min(struct votable *votable) { int min_vote = INT_MAX; int client_index; int client_index = -EINVAL; int i; for (i = 0; i < votable->num_clients; i++) { if (votable->votes[i].state && if (votable->votes[i].state == 1 && min_vote > votable->votes[i].value) { min_vote = votable->votes[i].value; client_index = i; Loading @@ -71,11 +72,11 @@ static int vote_min(struct votable *votable) static int vote_max(struct votable *votable) { int max_vote = INT_MIN; int client_index; int client_index = -EINVAL; int i; for (i = 0; i < votable->num_clients; i++) { if (votable->votes[i].state && if (votable->votes[i].state == 1 && max_vote < votable->votes[i].value) { max_vote = votable->votes[i].value; client_index = i; Loading Loading @@ -107,6 +108,9 @@ int get_client_vote(struct votable *votable, int client_id) int get_client_vote_locked(struct votable *votable, int client_id) { if (votable->votes[client_id].state < 0) return votable->default_result; return votable->votes[client_id].value; } Loading @@ -122,6 +126,9 @@ int get_effective_result(struct votable *votable) int get_effective_result_locked(struct votable *votable) { if (votable->effective_result < 0) return votable->default_result; return votable->effective_result; } Loading @@ -140,13 +147,19 @@ int get_effective_client_id_locked(struct votable *votable) return votable->effective_client_id; } int vote(struct votable *votable, int client_id, int state, int val) int vote(struct votable *votable, int client_id, bool state, int val) { int effective_id, effective_result; int rc = 0; lock_votable(votable); if (votable->votes[client_id].state == state && votable->votes[client_id].value == val) { pr_debug("%s: votes unchanged; skipping\n", votable->name); goto out; } votable->votes[client_id].state = state; votable->votes[client_id].value = val; Loading @@ -171,9 +184,15 @@ int vote(struct votable *votable, int client_id, int state, int val) state, client_id); } goto out; default: rc = -EINVAL; goto vote_err; } /* * If the votable does not have any votes it will maintain the last * known effective_result and effective_client_id */ if (effective_id < 0) { pr_debug("%s: no votes; skipping callback\n", votable->name); goto out; } effective_result = votable->votes[effective_id].value; Loading @@ -181,15 +200,12 @@ int vote(struct votable *votable, int client_id, int state, int val) if (effective_result != votable->effective_result) { votable->effective_client_id = effective_id; votable->effective_result = effective_result; pr_debug("%s: effective vote is now %d voted by %d", pr_debug("%s: effective vote is now %d voted by %d\n", votable->name, effective_result, effective_id); rc = votable->callback(votable->dev, effective_result, effective_id, val, client_id); } goto out; vote_err: pr_err("Invalid votable type specified for voter\n"); out: unlock_votable(votable); return rc; Loading @@ -198,6 +214,7 @@ out: struct votable *create_votable(struct device *dev, const char *name, int votable_type, int num_clients, int default_result, int (*callback)(struct device *dev, int effective_result, int effective_client, Loading @@ -205,6 +222,7 @@ struct votable *create_votable(struct device *dev, const char *name, int last_client) ) { int i; struct votable *votable = devm_kzalloc(dev, sizeof(struct votable), GFP_KERNEL); Loading @@ -231,9 +249,18 @@ struct votable *create_votable(struct device *dev, const char *name, votable->num_clients = num_clients; votable->callback = callback; votable->type = votable_type; votable->effective_result = -1; votable->default_result = default_result; mutex_init(&votable->vote_lock); /* * Because effective_result and client states are invalid * before the first vote, initialize them to -EINVAL */ votable->effective_result = -EINVAL; votable->effective_client_id = -EINVAL; for (i = 0; i < votable->num_clients; i++) votable->votes[i].state = -EINVAL; return votable; } drivers/power/pmic-voter.h +8 −7 Original line number Diff line number Diff line Loading @@ -27,9 +27,10 @@ int get_effective_result(struct votable *votable); int get_effective_result_locked(struct votable *votable); int get_effective_client_id(struct votable *votable); int get_effective_client_id_locked(struct votable *votable); int vote(struct votable *votable, int client_id, int state, int val); int vote(struct votable *votable, int client_id, bool state, int val); struct votable *create_votable(struct device *dev, const char *name, int votable_type, int num_clients, int default_result, int (*callback)(struct device *dev, int effective_result, int effective_client, Loading drivers/power/qpnp-smbcharger.c +16 −17 Original line number Diff line number Diff line Loading @@ -7347,45 +7347,44 @@ static int smbchg_probe(struct spmi_device *spmi) chip->fcc_votable = create_votable(&spmi->dev, "SMBCHG: fcc", VOTE_MIN, NUM_FCC_VOTER, set_fastchg_current_vote_cb); VOTE_MIN, NUM_FCC_VOTER, 2000, set_fastchg_current_vote_cb); if (IS_ERR(chip->fcc_votable)) return PTR_ERR(chip->fcc_votable); chip->usb_icl_votable = create_votable(&spmi->dev, "SMBCHG: usb_icl", VOTE_MIN, NUM_ICL_VOTER, set_usb_current_limit_vote_cb); VOTE_MIN, NUM_ICL_VOTER, 3000, set_usb_current_limit_vote_cb); if (IS_ERR(chip->usb_icl_votable)) return PTR_ERR(chip->usb_icl_votable); chip->dc_icl_votable = create_votable(&spmi->dev, "SMBCHG: dcl_icl", VOTE_MIN, NUM_ICL_VOTER, set_dc_current_limit_vote_cb); VOTE_MIN, NUM_ICL_VOTER, 3000, set_dc_current_limit_vote_cb); if (IS_ERR(chip->dc_icl_votable)) return PTR_ERR(chip->dc_icl_votable); chip->usb_suspend_votable = create_votable(&spmi->dev, "SMBCHG: usb_suspend", VOTE_SET_ANY, NUM_EN_VOTERS, usb_suspend_vote_cb); VOTE_SET_ANY, NUM_EN_VOTERS, 0, usb_suspend_vote_cb); if (IS_ERR(chip->usb_suspend_votable)) return PTR_ERR(chip->usb_suspend_votable); chip->dc_suspend_votable = create_votable(&spmi->dev, "SMBCHG: dc_suspend", VOTE_SET_ANY, NUM_EN_VOTERS, dc_suspend_vote_cb); VOTE_SET_ANY, NUM_EN_VOTERS, 0, dc_suspend_vote_cb); if (IS_ERR(chip->dc_suspend_votable)) return PTR_ERR(chip->dc_suspend_votable); chip->battchg_suspend_votable = create_votable(&spmi->dev, "SMBCHG: battchg_en", VOTE_SET_ANY, NUM_BATTCHG_EN_VOTERS, "SMBCHG: battchg_suspend", VOTE_SET_ANY, NUM_BATTCHG_EN_VOTERS, 0, charging_suspend_vote_cb); if (IS_ERR(chip->dc_suspend_votable)) if (IS_ERR(chip->battchg_suspend_votable)) return PTR_ERR(chip->battchg_suspend_votable); INIT_WORK(&chip->usb_set_online_work, smbchg_usb_update_online_work); Loading Loading
drivers/power/pmic-voter.c +42 −15 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct votable { int type; int effective_client_id; int effective_result; int default_result; struct mutex vote_lock; int (*callback)(struct device *dev, int effective_result, Loading @@ -46,7 +47,7 @@ static int vote_set_any(struct votable *votable) int i; for (i = 0; i < votable->num_clients; i++) if (votable->votes[i].state) if (votable->votes[i].state == 1) return 1; return 0; } Loading @@ -54,11 +55,11 @@ static int vote_set_any(struct votable *votable) static int vote_min(struct votable *votable) { int min_vote = INT_MAX; int client_index; int client_index = -EINVAL; int i; for (i = 0; i < votable->num_clients; i++) { if (votable->votes[i].state && if (votable->votes[i].state == 1 && min_vote > votable->votes[i].value) { min_vote = votable->votes[i].value; client_index = i; Loading @@ -71,11 +72,11 @@ static int vote_min(struct votable *votable) static int vote_max(struct votable *votable) { int max_vote = INT_MIN; int client_index; int client_index = -EINVAL; int i; for (i = 0; i < votable->num_clients; i++) { if (votable->votes[i].state && if (votable->votes[i].state == 1 && max_vote < votable->votes[i].value) { max_vote = votable->votes[i].value; client_index = i; Loading Loading @@ -107,6 +108,9 @@ int get_client_vote(struct votable *votable, int client_id) int get_client_vote_locked(struct votable *votable, int client_id) { if (votable->votes[client_id].state < 0) return votable->default_result; return votable->votes[client_id].value; } Loading @@ -122,6 +126,9 @@ int get_effective_result(struct votable *votable) int get_effective_result_locked(struct votable *votable) { if (votable->effective_result < 0) return votable->default_result; return votable->effective_result; } Loading @@ -140,13 +147,19 @@ int get_effective_client_id_locked(struct votable *votable) return votable->effective_client_id; } int vote(struct votable *votable, int client_id, int state, int val) int vote(struct votable *votable, int client_id, bool state, int val) { int effective_id, effective_result; int rc = 0; lock_votable(votable); if (votable->votes[client_id].state == state && votable->votes[client_id].value == val) { pr_debug("%s: votes unchanged; skipping\n", votable->name); goto out; } votable->votes[client_id].state = state; votable->votes[client_id].value = val; Loading @@ -171,9 +184,15 @@ int vote(struct votable *votable, int client_id, int state, int val) state, client_id); } goto out; default: rc = -EINVAL; goto vote_err; } /* * If the votable does not have any votes it will maintain the last * known effective_result and effective_client_id */ if (effective_id < 0) { pr_debug("%s: no votes; skipping callback\n", votable->name); goto out; } effective_result = votable->votes[effective_id].value; Loading @@ -181,15 +200,12 @@ int vote(struct votable *votable, int client_id, int state, int val) if (effective_result != votable->effective_result) { votable->effective_client_id = effective_id; votable->effective_result = effective_result; pr_debug("%s: effective vote is now %d voted by %d", pr_debug("%s: effective vote is now %d voted by %d\n", votable->name, effective_result, effective_id); rc = votable->callback(votable->dev, effective_result, effective_id, val, client_id); } goto out; vote_err: pr_err("Invalid votable type specified for voter\n"); out: unlock_votable(votable); return rc; Loading @@ -198,6 +214,7 @@ out: struct votable *create_votable(struct device *dev, const char *name, int votable_type, int num_clients, int default_result, int (*callback)(struct device *dev, int effective_result, int effective_client, Loading @@ -205,6 +222,7 @@ struct votable *create_votable(struct device *dev, const char *name, int last_client) ) { int i; struct votable *votable = devm_kzalloc(dev, sizeof(struct votable), GFP_KERNEL); Loading @@ -231,9 +249,18 @@ struct votable *create_votable(struct device *dev, const char *name, votable->num_clients = num_clients; votable->callback = callback; votable->type = votable_type; votable->effective_result = -1; votable->default_result = default_result; mutex_init(&votable->vote_lock); /* * Because effective_result and client states are invalid * before the first vote, initialize them to -EINVAL */ votable->effective_result = -EINVAL; votable->effective_client_id = -EINVAL; for (i = 0; i < votable->num_clients; i++) votable->votes[i].state = -EINVAL; return votable; }
drivers/power/pmic-voter.h +8 −7 Original line number Diff line number Diff line Loading @@ -27,9 +27,10 @@ int get_effective_result(struct votable *votable); int get_effective_result_locked(struct votable *votable); int get_effective_client_id(struct votable *votable); int get_effective_client_id_locked(struct votable *votable); int vote(struct votable *votable, int client_id, int state, int val); int vote(struct votable *votable, int client_id, bool state, int val); struct votable *create_votable(struct device *dev, const char *name, int votable_type, int num_clients, int default_result, int (*callback)(struct device *dev, int effective_result, int effective_client, Loading
drivers/power/qpnp-smbcharger.c +16 −17 Original line number Diff line number Diff line Loading @@ -7347,45 +7347,44 @@ static int smbchg_probe(struct spmi_device *spmi) chip->fcc_votable = create_votable(&spmi->dev, "SMBCHG: fcc", VOTE_MIN, NUM_FCC_VOTER, set_fastchg_current_vote_cb); VOTE_MIN, NUM_FCC_VOTER, 2000, set_fastchg_current_vote_cb); if (IS_ERR(chip->fcc_votable)) return PTR_ERR(chip->fcc_votable); chip->usb_icl_votable = create_votable(&spmi->dev, "SMBCHG: usb_icl", VOTE_MIN, NUM_ICL_VOTER, set_usb_current_limit_vote_cb); VOTE_MIN, NUM_ICL_VOTER, 3000, set_usb_current_limit_vote_cb); if (IS_ERR(chip->usb_icl_votable)) return PTR_ERR(chip->usb_icl_votable); chip->dc_icl_votable = create_votable(&spmi->dev, "SMBCHG: dcl_icl", VOTE_MIN, NUM_ICL_VOTER, set_dc_current_limit_vote_cb); VOTE_MIN, NUM_ICL_VOTER, 3000, set_dc_current_limit_vote_cb); if (IS_ERR(chip->dc_icl_votable)) return PTR_ERR(chip->dc_icl_votable); chip->usb_suspend_votable = create_votable(&spmi->dev, "SMBCHG: usb_suspend", VOTE_SET_ANY, NUM_EN_VOTERS, usb_suspend_vote_cb); VOTE_SET_ANY, NUM_EN_VOTERS, 0, usb_suspend_vote_cb); if (IS_ERR(chip->usb_suspend_votable)) return PTR_ERR(chip->usb_suspend_votable); chip->dc_suspend_votable = create_votable(&spmi->dev, "SMBCHG: dc_suspend", VOTE_SET_ANY, NUM_EN_VOTERS, dc_suspend_vote_cb); VOTE_SET_ANY, NUM_EN_VOTERS, 0, dc_suspend_vote_cb); if (IS_ERR(chip->dc_suspend_votable)) return PTR_ERR(chip->dc_suspend_votable); chip->battchg_suspend_votable = create_votable(&spmi->dev, "SMBCHG: battchg_en", VOTE_SET_ANY, NUM_BATTCHG_EN_VOTERS, "SMBCHG: battchg_suspend", VOTE_SET_ANY, NUM_BATTCHG_EN_VOTERS, 0, charging_suspend_vote_cb); if (IS_ERR(chip->dc_suspend_votable)) if (IS_ERR(chip->battchg_suspend_votable)) return PTR_ERR(chip->battchg_suspend_votable); INIT_WORK(&chip->usb_set_online_work, smbchg_usb_update_online_work); Loading