@@ -388,7 +388,7 @@ static int __power_supply_get_supplier_property(struct device *dev, void *_data)
388388 struct psy_get_supplier_prop_data * data = _data ;
389389
390390 if (__power_supply_is_supplied_by (epsy , data -> psy ))
391- if (!epsy -> desc -> get_property (epsy , data -> psp , data -> val ))
391+ if (!power_supply_get_property (epsy , data -> psp , data -> val ))
392392 return 1 ; /* Success */
393393
394394 return 0 ; /* Continue iterating */
@@ -832,6 +832,133 @@ void power_supply_put_battery_info(struct power_supply *psy,
832832}
833833EXPORT_SYMBOL_GPL (power_supply_put_battery_info );
834834
835+ const enum power_supply_property power_supply_battery_info_properties [] = {
836+ POWER_SUPPLY_PROP_TECHNOLOGY ,
837+ POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN ,
838+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN ,
839+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN ,
840+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN ,
841+ POWER_SUPPLY_PROP_PRECHARGE_CURRENT ,
842+ POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT ,
843+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX ,
844+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX ,
845+ POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN ,
846+ POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX ,
847+ POWER_SUPPLY_PROP_TEMP_ALERT_MIN ,
848+ POWER_SUPPLY_PROP_TEMP_ALERT_MAX ,
849+ POWER_SUPPLY_PROP_TEMP_MIN ,
850+ POWER_SUPPLY_PROP_TEMP_MAX ,
851+ };
852+ EXPORT_SYMBOL_GPL (power_supply_battery_info_properties );
853+
854+ const size_t power_supply_battery_info_properties_size = ARRAY_SIZE (power_supply_battery_info_properties );
855+ EXPORT_SYMBOL_GPL (power_supply_battery_info_properties_size );
856+
857+ bool power_supply_battery_info_has_prop (struct power_supply_battery_info * info ,
858+ enum power_supply_property psp )
859+ {
860+ if (!info )
861+ return false;
862+
863+ switch (psp ) {
864+ case POWER_SUPPLY_PROP_TECHNOLOGY :
865+ return info -> technology != POWER_SUPPLY_TECHNOLOGY_UNKNOWN ;
866+ case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN :
867+ return info -> energy_full_design_uwh >= 0 ;
868+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN :
869+ return info -> charge_full_design_uah >= 0 ;
870+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN :
871+ return info -> voltage_min_design_uv >= 0 ;
872+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN :
873+ return info -> voltage_max_design_uv >= 0 ;
874+ case POWER_SUPPLY_PROP_PRECHARGE_CURRENT :
875+ return info -> precharge_current_ua >= 0 ;
876+ case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT :
877+ return info -> charge_term_current_ua >= 0 ;
878+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX :
879+ return info -> constant_charge_current_max_ua >= 0 ;
880+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX :
881+ return info -> constant_charge_voltage_max_uv >= 0 ;
882+ case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN :
883+ return info -> temp_ambient_alert_min > INT_MIN ;
884+ case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX :
885+ return info -> temp_ambient_alert_max < INT_MAX ;
886+ case POWER_SUPPLY_PROP_TEMP_ALERT_MIN :
887+ return info -> temp_alert_min > INT_MIN ;
888+ case POWER_SUPPLY_PROP_TEMP_ALERT_MAX :
889+ return info -> temp_alert_max < INT_MAX ;
890+ case POWER_SUPPLY_PROP_TEMP_MIN :
891+ return info -> temp_min > INT_MIN ;
892+ case POWER_SUPPLY_PROP_TEMP_MAX :
893+ return info -> temp_max < INT_MAX ;
894+ default :
895+ return false;
896+ }
897+ }
898+ EXPORT_SYMBOL_GPL (power_supply_battery_info_has_prop );
899+
900+ int power_supply_battery_info_get_prop (struct power_supply_battery_info * info ,
901+ enum power_supply_property psp ,
902+ union power_supply_propval * val )
903+ {
904+ if (!info )
905+ return - EINVAL ;
906+
907+ if (!power_supply_battery_info_has_prop (info , psp ))
908+ return - EINVAL ;
909+
910+ switch (psp ) {
911+ case POWER_SUPPLY_PROP_TECHNOLOGY :
912+ val -> intval = info -> technology ;
913+ return 0 ;
914+ case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN :
915+ val -> intval = info -> energy_full_design_uwh ;
916+ return 0 ;
917+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN :
918+ val -> intval = info -> charge_full_design_uah ;
919+ return 0 ;
920+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN :
921+ val -> intval = info -> voltage_min_design_uv ;
922+ return 0 ;
923+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN :
924+ val -> intval = info -> voltage_max_design_uv ;
925+ return 0 ;
926+ case POWER_SUPPLY_PROP_PRECHARGE_CURRENT :
927+ val -> intval = info -> precharge_current_ua ;
928+ return 0 ;
929+ case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT :
930+ val -> intval = info -> charge_term_current_ua ;
931+ return 0 ;
932+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX :
933+ val -> intval = info -> constant_charge_current_max_ua ;
934+ return 0 ;
935+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX :
936+ val -> intval = info -> constant_charge_voltage_max_uv ;
937+ return 0 ;
938+ case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN :
939+ val -> intval = info -> temp_ambient_alert_min ;
940+ return 0 ;
941+ case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX :
942+ val -> intval = info -> temp_ambient_alert_max ;
943+ return 0 ;
944+ case POWER_SUPPLY_PROP_TEMP_ALERT_MIN :
945+ val -> intval = info -> temp_alert_min ;
946+ return 0 ;
947+ case POWER_SUPPLY_PROP_TEMP_ALERT_MAX :
948+ val -> intval = info -> temp_alert_max ;
949+ return 0 ;
950+ case POWER_SUPPLY_PROP_TEMP_MIN :
951+ val -> intval = info -> temp_min ;
952+ return 0 ;
953+ case POWER_SUPPLY_PROP_TEMP_MAX :
954+ val -> intval = info -> temp_max ;
955+ return 0 ;
956+ default :
957+ return - EINVAL ;
958+ }
959+ }
960+ EXPORT_SYMBOL_GPL (power_supply_battery_info_get_prop );
961+
835962/**
836963 * power_supply_temp2resist_simple() - find the battery internal resistance
837964 * percent from temperature
@@ -1046,6 +1173,22 @@ bool power_supply_battery_bti_in_range(struct power_supply_battery_info *info,
10461173}
10471174EXPORT_SYMBOL_GPL (power_supply_battery_bti_in_range );
10481175
1176+ static bool psy_has_property (const struct power_supply_desc * psy_desc ,
1177+ enum power_supply_property psp )
1178+ {
1179+ bool found = false;
1180+ int i ;
1181+
1182+ for (i = 0 ; i < psy_desc -> num_properties ; i ++ ) {
1183+ if (psy_desc -> properties [i ] == psp ) {
1184+ found = true;
1185+ break ;
1186+ }
1187+ }
1188+
1189+ return found ;
1190+ }
1191+
10491192int power_supply_get_property (struct power_supply * psy ,
10501193 enum power_supply_property psp ,
10511194 union power_supply_propval * val )
@@ -1056,7 +1199,12 @@ int power_supply_get_property(struct power_supply *psy,
10561199 return - ENODEV ;
10571200 }
10581201
1059- return psy -> desc -> get_property (psy , psp , val );
1202+ if (psy_has_property (psy -> desc , psp ))
1203+ return psy -> desc -> get_property (psy , psp , val );
1204+ else if (power_supply_battery_info_has_prop (psy -> battery_info , psp ))
1205+ return power_supply_battery_info_get_prop (psy -> battery_info , psp , val );
1206+ else
1207+ return - EINVAL ;
10601208}
10611209EXPORT_SYMBOL_GPL (power_supply_get_property );
10621210
@@ -1117,22 +1265,6 @@ void power_supply_unreg_notifier(struct notifier_block *nb)
11171265}
11181266EXPORT_SYMBOL_GPL (power_supply_unreg_notifier );
11191267
1120- static bool psy_has_property (const struct power_supply_desc * psy_desc ,
1121- enum power_supply_property psp )
1122- {
1123- bool found = false;
1124- int i ;
1125-
1126- for (i = 0 ; i < psy_desc -> num_properties ; i ++ ) {
1127- if (psy_desc -> properties [i ] == psp ) {
1128- found = true;
1129- break ;
1130- }
1131- }
1132-
1133- return found ;
1134- }
1135-
11361268#ifdef CONFIG_THERMAL
11371269static int power_supply_read_temp (struct thermal_zone_device * tzd ,
11381270 int * temp )
@@ -1255,6 +1387,17 @@ __power_supply_register(struct device *parent,
12551387 goto check_supplies_failed ;
12561388 }
12571389
1390+ /*
1391+ * Expose constant battery info, if it is available. While there are
1392+ * some chargers accessing constant battery data, we only want to
1393+ * expose battery data to userspace for battery devices.
1394+ */
1395+ if (desc -> type == POWER_SUPPLY_TYPE_BATTERY ) {
1396+ rc = power_supply_get_battery_info (psy , & psy -> battery_info );
1397+ if (rc && rc != - ENODEV && rc != - ENOENT )
1398+ goto check_supplies_failed ;
1399+ }
1400+
12581401 spin_lock_init (& psy -> changed_lock );
12591402 rc = device_add (dev );
12601403 if (rc )
0 commit comments