Loading arch/arm64/boot/dts/qcom/smb1390.dtsi +15 −1 Original line number Diff line number Diff line /* Copyright (c) 2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -56,3 +56,17 @@ smb1390: qcom,smb1390@10 { }; }; }; smb1390_slave: qcom,smb1390_slave@18 { compatible = "qcom,i2c-pmic"; reg = <0x18>; #address-cells = <1>; #size-cells = <0>; qcom,periph-map = <0x10>; status = "disabled"; smb1390_slave_charger: qcom,charge_pump_slave { compatible = "qcom,smb1390-slave"; status = "disabled"; }; }; drivers/power/supply/qcom/pmic-voter.c +74 −4 Original line number Diff line number Diff line Loading @@ -35,12 +35,14 @@ struct client_vote { struct votable { const char *name; const char *override_client; struct list_head list; struct client_vote votes[NUM_MAX_CLIENTS]; int num_clients; int type; int effective_client_id; int effective_result; int override_result; struct mutex vote_lock; void *data; int (*callback)(struct votable *votable, Loading Loading @@ -277,6 +279,9 @@ int get_effective_result_locked(struct votable *votable) if (votable->force_active) return votable->force_val; if (votable->override_result != -EINVAL) return votable->override_result; return votable->effective_result; } Loading Loading @@ -313,6 +318,9 @@ const char *get_effective_client_locked(struct votable *votable) if (votable->force_active) return DEBUG_FORCE_CLIENT; if (votable->override_result != -EINVAL) return votable->override_client; return get_client_str(votable, votable->effective_client_id); } Loading Loading @@ -423,7 +431,8 @@ int vote(struct votable *votable, const char *client_str, bool enabled, int val) votable->name, effective_result, get_client_str(votable, effective_id), effective_id); if (votable->callback && !votable->force_active) if (votable->callback && !votable->force_active && (votable->override_result == -EINVAL)) rc = votable->callback(votable, votable->data, effective_result, get_client_str(votable, effective_id)); Loading @@ -435,6 +444,57 @@ int vote(struct votable *votable, const char *client_str, bool enabled, int val) return rc; } /** * vote_override() - * * @votable: The votable object * @override_client: The voting client that will override other client's * votes, that are already present. When force_active * and override votes are set on a votable, force_active's * client will have the higher priority and it's vote will * be the effective one. * @enabled: This provides a means for the override client to exclude * itself from election. This client's vote * (the next argument) will be considered only when * it has enabled its participation. When this is * set true, this will force a value on a MIN/MAX votable * irrespective of its current value. * @val: The vote value. This will be effective only if enabled * is set true. * Returns: * The result of vote. 0 is returned if the vote * is successfully set by the overriding client, when enabled is set. */ int vote_override(struct votable *votable, const char *override_client, bool enabled, int val) { int rc = 0; lock_votable(votable); if (votable->force_active) { votable->override_result = enabled ? val : -EINVAL; goto out; } if (enabled) { rc = votable->callback(votable, votable->data, val, override_client); if (!rc) { votable->override_client = override_client; votable->override_result = val; } } else { rc = votable->callback(votable, votable->data, votable->effective_result, get_client_str(votable, votable->effective_client_id)); votable->override_result = -EINVAL; } out: unlock_votable(votable); return rc; } int rerun_election(struct votable *votable) { int rc = 0; Loading Loading @@ -489,6 +549,8 @@ static int force_active_set(void *data, u64 val) { struct votable *votable = data; int rc = 0; int effective_result; const char *client; lock_votable(votable); votable->force_active = !!val; Loading @@ -501,9 +563,16 @@ static int force_active_set(void *data, u64 val) votable->force_val, DEBUG_FORCE_CLIENT); } else { rc = votable->callback(votable, votable->data, votable->effective_result, get_client_str(votable, votable->effective_client_id)); if (votable->override_result != -EINVAL) { effective_result = votable->override_result; client = votable->override_client; } else { effective_result = votable->effective_result; client = get_client_str(votable, votable->effective_client_id); } rc = votable->callback(votable, votable->data, effective_result, client); } out: unlock_votable(votable); Loading Loading @@ -611,6 +680,7 @@ struct votable *create_votable(const char *name, votable->callback = callback; votable->type = votable_type; votable->data = data; votable->override_result = -EINVAL; mutex_init(&votable->vote_lock); /* Loading include/linux/pmic-voter.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2016,2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -34,6 +34,8 @@ int get_effective_result_locked(struct votable *votable); const char *get_effective_client(struct votable *votable); const char *get_effective_client_locked(struct votable *votable); int vote(struct votable *votable, const char *client_str, bool state, int val); int vote_override(struct votable *votable, const char *override_client, bool state, int val); int rerun_election(struct votable *votable); struct votable *find_votable(const char *name); struct votable *create_votable(const char *name, Loading Loading
arch/arm64/boot/dts/qcom/smb1390.dtsi +15 −1 Original line number Diff line number Diff line /* Copyright (c) 2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -56,3 +56,17 @@ smb1390: qcom,smb1390@10 { }; }; }; smb1390_slave: qcom,smb1390_slave@18 { compatible = "qcom,i2c-pmic"; reg = <0x18>; #address-cells = <1>; #size-cells = <0>; qcom,periph-map = <0x10>; status = "disabled"; smb1390_slave_charger: qcom,charge_pump_slave { compatible = "qcom,smb1390-slave"; status = "disabled"; }; };
drivers/power/supply/qcom/pmic-voter.c +74 −4 Original line number Diff line number Diff line Loading @@ -35,12 +35,14 @@ struct client_vote { struct votable { const char *name; const char *override_client; struct list_head list; struct client_vote votes[NUM_MAX_CLIENTS]; int num_clients; int type; int effective_client_id; int effective_result; int override_result; struct mutex vote_lock; void *data; int (*callback)(struct votable *votable, Loading Loading @@ -277,6 +279,9 @@ int get_effective_result_locked(struct votable *votable) if (votable->force_active) return votable->force_val; if (votable->override_result != -EINVAL) return votable->override_result; return votable->effective_result; } Loading Loading @@ -313,6 +318,9 @@ const char *get_effective_client_locked(struct votable *votable) if (votable->force_active) return DEBUG_FORCE_CLIENT; if (votable->override_result != -EINVAL) return votable->override_client; return get_client_str(votable, votable->effective_client_id); } Loading Loading @@ -423,7 +431,8 @@ int vote(struct votable *votable, const char *client_str, bool enabled, int val) votable->name, effective_result, get_client_str(votable, effective_id), effective_id); if (votable->callback && !votable->force_active) if (votable->callback && !votable->force_active && (votable->override_result == -EINVAL)) rc = votable->callback(votable, votable->data, effective_result, get_client_str(votable, effective_id)); Loading @@ -435,6 +444,57 @@ int vote(struct votable *votable, const char *client_str, bool enabled, int val) return rc; } /** * vote_override() - * * @votable: The votable object * @override_client: The voting client that will override other client's * votes, that are already present. When force_active * and override votes are set on a votable, force_active's * client will have the higher priority and it's vote will * be the effective one. * @enabled: This provides a means for the override client to exclude * itself from election. This client's vote * (the next argument) will be considered only when * it has enabled its participation. When this is * set true, this will force a value on a MIN/MAX votable * irrespective of its current value. * @val: The vote value. This will be effective only if enabled * is set true. * Returns: * The result of vote. 0 is returned if the vote * is successfully set by the overriding client, when enabled is set. */ int vote_override(struct votable *votable, const char *override_client, bool enabled, int val) { int rc = 0; lock_votable(votable); if (votable->force_active) { votable->override_result = enabled ? val : -EINVAL; goto out; } if (enabled) { rc = votable->callback(votable, votable->data, val, override_client); if (!rc) { votable->override_client = override_client; votable->override_result = val; } } else { rc = votable->callback(votable, votable->data, votable->effective_result, get_client_str(votable, votable->effective_client_id)); votable->override_result = -EINVAL; } out: unlock_votable(votable); return rc; } int rerun_election(struct votable *votable) { int rc = 0; Loading Loading @@ -489,6 +549,8 @@ static int force_active_set(void *data, u64 val) { struct votable *votable = data; int rc = 0; int effective_result; const char *client; lock_votable(votable); votable->force_active = !!val; Loading @@ -501,9 +563,16 @@ static int force_active_set(void *data, u64 val) votable->force_val, DEBUG_FORCE_CLIENT); } else { rc = votable->callback(votable, votable->data, votable->effective_result, get_client_str(votable, votable->effective_client_id)); if (votable->override_result != -EINVAL) { effective_result = votable->override_result; client = votable->override_client; } else { effective_result = votable->effective_result; client = get_client_str(votable, votable->effective_client_id); } rc = votable->callback(votable, votable->data, effective_result, client); } out: unlock_votable(votable); Loading Loading @@ -611,6 +680,7 @@ struct votable *create_votable(const char *name, votable->callback = callback; votable->type = votable_type; votable->data = data; votable->override_result = -EINVAL; mutex_init(&votable->vote_lock); /* Loading
include/linux/pmic-voter.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2016,2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -34,6 +34,8 @@ int get_effective_result_locked(struct votable *votable); const char *get_effective_client(struct votable *votable); const char *get_effective_client_locked(struct votable *votable); int vote(struct votable *votable, const char *client_str, bool state, int val); int vote_override(struct votable *votable, const char *override_client, bool state, int val); int rerun_election(struct votable *votable); struct votable *find_votable(const char *name); struct votable *create_votable(const char *name, Loading