hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/power/supply/power_supply_core.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Universal power supply monitor class
34 *
....@@ -6,8 +7,6 @@
67 * Copyright © 2003 Ian Molton <spyro@f2s.com>
78 *
89 * Modified: 2004, Oct Szabolcs Gyurko
9
- *
10
- * You may use this code as per GPL version 2
1110 */
1211
1312 #include <linux/module.h>
....@@ -32,6 +31,13 @@
3231 EXPORT_SYMBOL_GPL(power_supply_notifier);
3332
3433 static struct device_type power_supply_dev_type;
34
+
35
+struct match_device_node_array_param {
36
+ struct device_node *parent_of_node;
37
+ struct power_supply **psy;
38
+ ssize_t psy_size;
39
+ ssize_t psy_count;
40
+};
3541
3642 #define POWER_SUPPLY_DEFERRED_REGISTER_TIME msecs_to_jiffies(10)
3743
....@@ -126,6 +132,7 @@
126132 }
127133 EXPORT_SYMBOL_GPL(power_supply_changed);
128134
135
+static int psy_register_cooler(struct power_supply *psy);
129136 /*
130137 * Notify that power supply was registered after parent finished the probing.
131138 *
....@@ -133,6 +140,8 @@
133140 * calling power_supply_changed() directly from power_supply_register()
134141 * would lead to execution of get_property() function provided by the driver
135142 * too early - before the probe ends.
143
+ * Also, registering cooling device from the probe will execute the
144
+ * get_property() function. So register the cooling device after the probe.
136145 *
137146 * Avoid that by waiting on parent's mutex.
138147 */
....@@ -150,14 +159,13 @@
150159 }
151160
152161 power_supply_changed(psy);
162
+ psy_register_cooler(psy);
153163
154164 if (psy->dev.parent)
155165 mutex_unlock(&psy->dev.parent->mutex);
156166 }
157167
158168 #ifdef CONFIG_OF
159
-#include <linux/of.h>
160
-
161169 static int __power_supply_populate_supplied_from(struct device *dev,
162170 void *data)
163171 {
....@@ -525,6 +533,77 @@
525533 }
526534 EXPORT_SYMBOL_GPL(power_supply_get_by_phandle);
527535
536
+static int power_supply_match_device_node_array(struct device *dev,
537
+ void *data)
538
+{
539
+ struct match_device_node_array_param *param =
540
+ (struct match_device_node_array_param *)data;
541
+ struct power_supply **psy = param->psy;
542
+ ssize_t size = param->psy_size;
543
+ ssize_t *count = &param->psy_count;
544
+
545
+ if (!dev->parent || dev->parent->of_node != param->parent_of_node)
546
+ return 0;
547
+
548
+ if (*count >= size)
549
+ return -EOVERFLOW;
550
+
551
+ psy[*count] = dev_get_drvdata(dev);
552
+ atomic_inc(&psy[*count]->use_cnt);
553
+ (*count)++;
554
+
555
+ return 0;
556
+}
557
+
558
+/**
559
+ * power_supply_get_by_phandle_array() - Similar to
560
+ * power_supply_get_by_phandle but returns an array of power supply
561
+ * objects which are associated with the phandle.
562
+ * @np: Pointer to device node holding phandle property.
563
+ * @property: Name of property holding a power supply name.
564
+ * @psy: Array of power_supply pointers provided by the client which is
565
+ * filled by power_supply_get_by_phandle_array.
566
+ * @size: size of power_supply pointer array.
567
+ *
568
+ * If power supply was found, it increases reference count for the
569
+ * internal power supply's device. The user should power_supply_put()
570
+ * after usage.
571
+ *
572
+ * Return: On success returns the number of power supply objects filled
573
+ * in the @psy array.
574
+ * -EOVERFLOW when size of @psy array is not suffice.
575
+ * -EINVAL when @psy is NULL or @size is 0.
576
+ * -ENODEV when matching device_node is not found.
577
+ */
578
+int power_supply_get_by_phandle_array(struct device_node *np,
579
+ const char *property,
580
+ struct power_supply **psy,
581
+ ssize_t size)
582
+{
583
+ struct device_node *power_supply_np;
584
+ int ret;
585
+ struct match_device_node_array_param param;
586
+
587
+ if (!psy || !size)
588
+ return -EINVAL;
589
+
590
+ power_supply_np = of_parse_phandle(np, property, 0);
591
+ if (!power_supply_np)
592
+ return -ENODEV;
593
+
594
+ param.parent_of_node = power_supply_np;
595
+ param.psy = psy;
596
+ param.psy_size = size;
597
+ param.psy_count = 0;
598
+ ret = class_for_each_device(power_supply_class, NULL, &param,
599
+ power_supply_match_device_node_array);
600
+
601
+ of_node_put(power_supply_np);
602
+
603
+ return param.psy_count;
604
+}
605
+EXPORT_SYMBOL_GPL(power_supply_get_by_phandle_array);
606
+
528607 static void devm_power_supply_put(struct device *dev, void *res)
529608 {
530609 struct power_supply **psy = res;
....@@ -568,17 +647,34 @@
568647 int power_supply_get_battery_info(struct power_supply *psy,
569648 struct power_supply_battery_info *info)
570649 {
650
+ struct power_supply_resistance_temp_table *resist_table;
571651 struct device_node *battery_np;
572652 const char *value;
573
- int err;
653
+ int err, len, index;
654
+ const __be32 *list;
574655
575656 info->energy_full_design_uwh = -EINVAL;
576657 info->charge_full_design_uah = -EINVAL;
577658 info->voltage_min_design_uv = -EINVAL;
659
+ info->voltage_max_design_uv = -EINVAL;
578660 info->precharge_current_ua = -EINVAL;
579661 info->charge_term_current_ua = -EINVAL;
580662 info->constant_charge_current_max_ua = -EINVAL;
581663 info->constant_charge_voltage_max_uv = -EINVAL;
664
+ info->temp_ambient_alert_min = INT_MIN;
665
+ info->temp_ambient_alert_max = INT_MAX;
666
+ info->temp_alert_min = INT_MIN;
667
+ info->temp_alert_max = INT_MAX;
668
+ info->temp_min = INT_MIN;
669
+ info->temp_max = INT_MAX;
670
+ info->factory_internal_resistance_uohm = -EINVAL;
671
+ info->resist_table = NULL;
672
+
673
+ for (index = 0; index < POWER_SUPPLY_OCV_TEMP_MAX; index++) {
674
+ info->ocv_table[index] = NULL;
675
+ info->ocv_temp[index] = -EINVAL;
676
+ info->ocv_table_size[index] = -EINVAL;
677
+ }
582678
583679 if (!psy->of_node) {
584680 dev_warn(&psy->dev, "%s currently only supports devicetree\n",
....@@ -592,14 +688,16 @@
592688
593689 err = of_property_read_string(battery_np, "compatible", &value);
594690 if (err)
595
- return err;
691
+ goto out_put_node;
596692
597
- if (strcmp("simple-battery", value))
598
- return -ENODEV;
693
+ if (strcmp("simple-battery", value)) {
694
+ err = -ENODEV;
695
+ goto out_put_node;
696
+ }
599697
600698 /* The property and field names below must correspond to elements
601699 * in enum power_supply_property. For reasoning, see
602
- * Documentation/power/power_supply_class.txt.
700
+ * Documentation/power/power_supply_class.rst.
603701 */
604702
605703 of_property_read_u32(battery_np, "energy-full-design-microwatt-hours",
....@@ -608,18 +706,246 @@
608706 &info->charge_full_design_uah);
609707 of_property_read_u32(battery_np, "voltage-min-design-microvolt",
610708 &info->voltage_min_design_uv);
709
+ of_property_read_u32(battery_np, "voltage-max-design-microvolt",
710
+ &info->voltage_max_design_uv);
711
+ of_property_read_u32(battery_np, "trickle-charge-current-microamp",
712
+ &info->tricklecharge_current_ua);
611713 of_property_read_u32(battery_np, "precharge-current-microamp",
612714 &info->precharge_current_ua);
715
+ of_property_read_u32(battery_np, "precharge-upper-limit-microvolt",
716
+ &info->precharge_voltage_max_uv);
613717 of_property_read_u32(battery_np, "charge-term-current-microamp",
614718 &info->charge_term_current_ua);
615
- of_property_read_u32(battery_np, "constant_charge_current_max_microamp",
719
+ of_property_read_u32(battery_np, "re-charge-voltage-microvolt",
720
+ &info->charge_restart_voltage_uv);
721
+ of_property_read_u32(battery_np, "over-voltage-threshold-microvolt",
722
+ &info->overvoltage_limit_uv);
723
+ of_property_read_u32(battery_np, "constant-charge-current-max-microamp",
616724 &info->constant_charge_current_max_ua);
617
- of_property_read_u32(battery_np, "constant_charge_voltage_max_microvolt",
725
+ of_property_read_u32(battery_np, "constant-charge-voltage-max-microvolt",
618726 &info->constant_charge_voltage_max_uv);
727
+ of_property_read_u32(battery_np, "factory-internal-resistance-micro-ohms",
728
+ &info->factory_internal_resistance_uohm);
619729
620
- return 0;
730
+ of_property_read_u32_index(battery_np, "ambient-celsius",
731
+ 0, &info->temp_ambient_alert_min);
732
+ of_property_read_u32_index(battery_np, "ambient-celsius",
733
+ 1, &info->temp_ambient_alert_max);
734
+ of_property_read_u32_index(battery_np, "alert-celsius",
735
+ 0, &info->temp_alert_min);
736
+ of_property_read_u32_index(battery_np, "alert-celsius",
737
+ 1, &info->temp_alert_max);
738
+ of_property_read_u32_index(battery_np, "operating-range-celsius",
739
+ 0, &info->temp_min);
740
+ of_property_read_u32_index(battery_np, "operating-range-celsius",
741
+ 1, &info->temp_max);
742
+
743
+ len = of_property_count_u32_elems(battery_np, "ocv-capacity-celsius");
744
+ if (len < 0 && len != -EINVAL) {
745
+ err = len;
746
+ goto out_put_node;
747
+ } else if (len > POWER_SUPPLY_OCV_TEMP_MAX) {
748
+ dev_err(&psy->dev, "Too many temperature values\n");
749
+ err = -EINVAL;
750
+ goto out_put_node;
751
+ } else if (len > 0) {
752
+ of_property_read_u32_array(battery_np, "ocv-capacity-celsius",
753
+ info->ocv_temp, len);
754
+ }
755
+
756
+ for (index = 0; index < len; index++) {
757
+ struct power_supply_battery_ocv_table *table;
758
+ char *propname;
759
+ int i, tab_len, size;
760
+
761
+ propname = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", index);
762
+ list = of_get_property(battery_np, propname, &size);
763
+ if (!list || !size) {
764
+ dev_err(&psy->dev, "failed to get %s\n", propname);
765
+ kfree(propname);
766
+ power_supply_put_battery_info(psy, info);
767
+ err = -EINVAL;
768
+ goto out_put_node;
769
+ }
770
+
771
+ kfree(propname);
772
+ tab_len = size / (2 * sizeof(__be32));
773
+ info->ocv_table_size[index] = tab_len;
774
+
775
+ table = info->ocv_table[index] =
776
+ devm_kcalloc(&psy->dev, tab_len, sizeof(*table), GFP_KERNEL);
777
+ if (!info->ocv_table[index]) {
778
+ power_supply_put_battery_info(psy, info);
779
+ err = -ENOMEM;
780
+ goto out_put_node;
781
+ }
782
+
783
+ for (i = 0; i < tab_len; i++) {
784
+ table[i].ocv = be32_to_cpu(*list);
785
+ list++;
786
+ table[i].capacity = be32_to_cpu(*list);
787
+ list++;
788
+ }
789
+ }
790
+
791
+ list = of_get_property(battery_np, "resistance-temp-table", &len);
792
+ if (!list || !len)
793
+ goto out_put_node;
794
+
795
+ info->resist_table_size = len / (2 * sizeof(__be32));
796
+ resist_table = info->resist_table = devm_kcalloc(&psy->dev,
797
+ info->resist_table_size,
798
+ sizeof(*resist_table),
799
+ GFP_KERNEL);
800
+ if (!info->resist_table) {
801
+ power_supply_put_battery_info(psy, info);
802
+ err = -ENOMEM;
803
+ goto out_put_node;
804
+ }
805
+
806
+ for (index = 0; index < info->resist_table_size; index++) {
807
+ resist_table[index].temp = be32_to_cpu(*list++);
808
+ resist_table[index].resistance = be32_to_cpu(*list++);
809
+ }
810
+
811
+out_put_node:
812
+ of_node_put(battery_np);
813
+ return err;
621814 }
622815 EXPORT_SYMBOL_GPL(power_supply_get_battery_info);
816
+
817
+void power_supply_put_battery_info(struct power_supply *psy,
818
+ struct power_supply_battery_info *info)
819
+{
820
+ int i;
821
+
822
+ for (i = 0; i < POWER_SUPPLY_OCV_TEMP_MAX; i++) {
823
+ if (info->ocv_table[i])
824
+ devm_kfree(&psy->dev, info->ocv_table[i]);
825
+ }
826
+
827
+ if (info->resist_table)
828
+ devm_kfree(&psy->dev, info->resist_table);
829
+}
830
+EXPORT_SYMBOL_GPL(power_supply_put_battery_info);
831
+
832
+/**
833
+ * power_supply_temp2resist_simple() - find the battery internal resistance
834
+ * percent
835
+ * @table: Pointer to battery resistance temperature table
836
+ * @table_len: The table length
837
+ * @temp: Current temperature
838
+ *
839
+ * This helper function is used to look up battery internal resistance percent
840
+ * according to current temperature value from the resistance temperature table,
841
+ * and the table must be ordered descending. Then the actual battery internal
842
+ * resistance = the ideal battery internal resistance * percent / 100.
843
+ *
844
+ * Return: the battery internal resistance percent
845
+ */
846
+int power_supply_temp2resist_simple(struct power_supply_resistance_temp_table *table,
847
+ int table_len, int temp)
848
+{
849
+ int i, resist;
850
+
851
+ for (i = 0; i < table_len; i++)
852
+ if (temp > table[i].temp)
853
+ break;
854
+
855
+ if (i > 0 && i < table_len) {
856
+ int tmp;
857
+
858
+ tmp = (table[i - 1].resistance - table[i].resistance) *
859
+ (temp - table[i].temp);
860
+ tmp /= table[i - 1].temp - table[i].temp;
861
+ resist = tmp + table[i].resistance;
862
+ } else if (i == 0) {
863
+ resist = table[0].resistance;
864
+ } else {
865
+ resist = table[table_len - 1].resistance;
866
+ }
867
+
868
+ return resist;
869
+}
870
+EXPORT_SYMBOL_GPL(power_supply_temp2resist_simple);
871
+
872
+/**
873
+ * power_supply_ocv2cap_simple() - find the battery capacity
874
+ * @table: Pointer to battery OCV lookup table
875
+ * @table_len: OCV table length
876
+ * @ocv: Current OCV value
877
+ *
878
+ * This helper function is used to look up battery capacity according to
879
+ * current OCV value from one OCV table, and the OCV table must be ordered
880
+ * descending.
881
+ *
882
+ * Return: the battery capacity.
883
+ */
884
+int power_supply_ocv2cap_simple(struct power_supply_battery_ocv_table *table,
885
+ int table_len, int ocv)
886
+{
887
+ int i, cap, tmp;
888
+
889
+ for (i = 0; i < table_len; i++)
890
+ if (ocv > table[i].ocv)
891
+ break;
892
+
893
+ if (i > 0 && i < table_len) {
894
+ tmp = (table[i - 1].capacity - table[i].capacity) *
895
+ (ocv - table[i].ocv);
896
+ tmp /= table[i - 1].ocv - table[i].ocv;
897
+ cap = tmp + table[i].capacity;
898
+ } else if (i == 0) {
899
+ cap = table[0].capacity;
900
+ } else {
901
+ cap = table[table_len - 1].capacity;
902
+ }
903
+
904
+ return cap;
905
+}
906
+EXPORT_SYMBOL_GPL(power_supply_ocv2cap_simple);
907
+
908
+struct power_supply_battery_ocv_table *
909
+power_supply_find_ocv2cap_table(struct power_supply_battery_info *info,
910
+ int temp, int *table_len)
911
+{
912
+ int best_temp_diff = INT_MAX, temp_diff;
913
+ u8 i, best_index = 0;
914
+
915
+ if (!info->ocv_table[0])
916
+ return NULL;
917
+
918
+ for (i = 0; i < POWER_SUPPLY_OCV_TEMP_MAX; i++) {
919
+ /* Out of capacity tables */
920
+ if (!info->ocv_table[i])
921
+ break;
922
+
923
+ temp_diff = abs(info->ocv_temp[i] - temp);
924
+
925
+ if (temp_diff < best_temp_diff) {
926
+ best_temp_diff = temp_diff;
927
+ best_index = i;
928
+ }
929
+ }
930
+
931
+ *table_len = info->ocv_table_size[best_index];
932
+ return info->ocv_table[best_index];
933
+}
934
+EXPORT_SYMBOL_GPL(power_supply_find_ocv2cap_table);
935
+
936
+int power_supply_batinfo_ocv2cap(struct power_supply_battery_info *info,
937
+ int ocv, int temp)
938
+{
939
+ struct power_supply_battery_ocv_table *table;
940
+ int table_len;
941
+
942
+ table = power_supply_find_ocv2cap_table(info, temp, &table_len);
943
+ if (!table)
944
+ return -EINVAL;
945
+
946
+ return power_supply_ocv2cap_simple(table, table_len, ocv);
947
+}
948
+EXPORT_SYMBOL_GPL(power_supply_batinfo_ocv2cap);
623949
624950 int power_supply_get_property(struct power_supply *psy,
625951 enum power_supply_property psp,
....@@ -718,7 +1044,7 @@
7181044
7191045 static int psy_register_thermal(struct power_supply *psy)
7201046 {
721
- int i;
1047
+ int i, ret;
7221048
7231049 if (psy->desc->no_thermal)
7241050 return 0;
....@@ -728,7 +1054,12 @@
7281054 if (psy->desc->properties[i] == POWER_SUPPLY_PROP_TEMP) {
7291055 psy->tzd = thermal_zone_device_register(psy->desc->name,
7301056 0, 0, psy, &psy_tzd_ops, NULL, 0, 0);
731
- return PTR_ERR_OR_ZERO(psy->tzd);
1057
+ if (IS_ERR(psy->tzd))
1058
+ return PTR_ERR(psy->tzd);
1059
+ ret = thermal_zone_device_enable(psy->tzd);
1060
+ if (ret)
1061
+ thermal_zone_device_unregister(psy->tzd);
1062
+ return ret;
7321063 }
7331064 }
7341065 return 0;
....@@ -760,7 +1091,7 @@
7601091 return ret;
7611092 }
7621093
763
-static int ps_get_cur_chrage_cntl_limit(struct thermal_cooling_device *tcd,
1094
+static int ps_get_cur_charge_cntl_limit(struct thermal_cooling_device *tcd,
7641095 unsigned long *state)
7651096 {
7661097 struct power_supply *psy;
....@@ -795,7 +1126,7 @@
7951126
7961127 static const struct thermal_cooling_device_ops psy_tcd_ops = {
7971128 .get_max_state = ps_get_max_charge_cntl_limit,
798
- .get_cur_state = ps_get_cur_chrage_cntl_limit,
1129
+ .get_cur_state = ps_get_cur_charge_cntl_limit,
7991130 .set_cur_state = ps_set_cur_charge_cntl_limit,
8001131 };
8011132
....@@ -807,9 +1138,15 @@
8071138 for (i = 0; i < psy->desc->num_properties; i++) {
8081139 if (psy->desc->properties[i] ==
8091140 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT) {
810
- psy->tcd = thermal_cooling_device_register(
811
- (char *)psy->desc->name,
812
- psy, &psy_tcd_ops);
1141
+ if (psy->dev.parent)
1142
+ psy->tcd = thermal_of_cooling_device_register(
1143
+ dev_of_node(psy->dev.parent),
1144
+ (char *)psy->desc->name,
1145
+ psy, &psy_tcd_ops);
1146
+ else
1147
+ psy->tcd = thermal_cooling_device_register(
1148
+ (char *)psy->desc->name,
1149
+ psy, &psy_tcd_ops);
8131150 return PTR_ERR_OR_ZERO(psy->tcd);
8141151 }
8151152 }
....@@ -880,6 +1217,7 @@
8801217 dev_set_drvdata(dev, psy);
8811218 psy->desc = desc;
8821219 if (cfg) {
1220
+ dev->groups = cfg->attr_grp;
8831221 psy->drv_data = cfg->drv_data;
8841222 psy->of_node =
8851223 cfg->fwnode ? to_of_node(cfg->fwnode) : cfg->of_node;
....@@ -914,13 +1252,13 @@
9141252 if (rc)
9151253 goto register_thermal_failed;
9161254
917
- rc = psy_register_cooler(psy);
918
- if (rc)
919
- goto register_cooler_failed;
920
-
9211255 rc = power_supply_create_triggers(psy);
9221256 if (rc)
9231257 goto create_triggers_failed;
1258
+
1259
+ rc = power_supply_add_hwmon_sysfs(psy);
1260
+ if (rc)
1261
+ goto add_hwmon_sysfs_failed;
9241262
9251263 /*
9261264 * Update use_cnt after any uevents (most notably from device_add()).
....@@ -940,9 +1278,9 @@
9401278
9411279 return psy;
9421280
1281
+add_hwmon_sysfs_failed:
1282
+ power_supply_remove_triggers(psy);
9431283 create_triggers_failed:
944
- psy_unregister_cooler(psy);
945
-register_cooler_failed:
9461284 psy_unregister_thermal(psy);
9471285 register_thermal_failed:
9481286 device_del(dev);
....@@ -1092,6 +1430,7 @@
10921430 cancel_work_sync(&psy->changed_work);
10931431 cancel_delayed_work_sync(&psy->deferred_register_work);
10941432 sysfs_remove_link(&psy->dev.kobj, "powers");
1433
+ power_supply_remove_hwmon_sysfs(psy);
10951434 power_supply_remove_triggers(psy);
10961435 psy_unregister_cooler(psy);
10971436 psy_unregister_thermal(psy);