@@ -1235,9 +1235,8 @@ bool power_supply_has_property(struct power_supply *psy,
12351235 return false;
12361236}
12371237
1238- int power_supply_get_property (struct power_supply * psy ,
1239- enum power_supply_property psp ,
1240- union power_supply_propval * val )
1238+ static int __power_supply_get_property (struct power_supply * psy , enum power_supply_property psp ,
1239+ union power_supply_propval * val , bool use_extensions )
12411240{
12421241 struct power_supply_ext_registration * reg ;
12431242
@@ -1247,10 +1246,14 @@ int power_supply_get_property(struct power_supply *psy,
12471246 return - ENODEV ;
12481247 }
12491248
1250- scoped_guard (rwsem_read , & psy -> extensions_sem ) {
1251- power_supply_for_each_extension (reg , psy ) {
1252- if (power_supply_ext_has_property (reg -> ext , psp ))
1249+ if (use_extensions ) {
1250+ scoped_guard (rwsem_read , & psy -> extensions_sem ) {
1251+ power_supply_for_each_extension (reg , psy ) {
1252+ if (!power_supply_ext_has_property (reg -> ext , psp ))
1253+ continue ;
1254+
12531255 return reg -> ext -> get_property (psy , reg -> ext , reg -> data , psp , val );
1256+ }
12541257 }
12551258 }
12561259
@@ -1261,20 +1264,49 @@ int power_supply_get_property(struct power_supply *psy,
12611264 else
12621265 return - EINVAL ;
12631266}
1267+
1268+ int power_supply_get_property (struct power_supply * psy , enum power_supply_property psp ,
1269+ union power_supply_propval * val )
1270+ {
1271+ return __power_supply_get_property (psy , psp , val , true);
1272+ }
12641273EXPORT_SYMBOL_GPL (power_supply_get_property );
12651274
1266- int power_supply_set_property (struct power_supply * psy ,
1267- enum power_supply_property psp ,
1268- const union power_supply_propval * val )
1275+ /**
1276+ * power_supply_get_property_direct - Read a power supply property without checking for extensions
1277+ * @psy: The power supply
1278+ * @psp: The power supply property to read
1279+ * @val: The resulting value of the power supply property
1280+ *
1281+ * Read a power supply property without taking into account any power supply extensions registered
1282+ * on the given power supply. This is mostly useful for power supply extensions that want to access
1283+ * their own power supply as using power_supply_get_property() directly will result in a potential
1284+ * deadlock.
1285+ *
1286+ * Return: 0 on success or negative error code on failure.
1287+ */
1288+ int power_supply_get_property_direct (struct power_supply * psy , enum power_supply_property psp ,
1289+ union power_supply_propval * val )
1290+ {
1291+ return __power_supply_get_property (psy , psp , val , false);
1292+ }
1293+ EXPORT_SYMBOL_GPL (power_supply_get_property_direct );
1294+
1295+
1296+ static int __power_supply_set_property (struct power_supply * psy , enum power_supply_property psp ,
1297+ const union power_supply_propval * val , bool use_extensions )
12691298{
12701299 struct power_supply_ext_registration * reg ;
12711300
12721301 if (atomic_read (& psy -> use_cnt ) <= 0 )
12731302 return - ENODEV ;
12741303
1275- scoped_guard (rwsem_read , & psy -> extensions_sem ) {
1276- power_supply_for_each_extension (reg , psy ) {
1277- if (power_supply_ext_has_property (reg -> ext , psp )) {
1304+ if (use_extensions ) {
1305+ scoped_guard (rwsem_read , & psy -> extensions_sem ) {
1306+ power_supply_for_each_extension (reg , psy ) {
1307+ if (!power_supply_ext_has_property (reg -> ext , psp ))
1308+ continue ;
1309+
12781310 if (reg -> ext -> set_property )
12791311 return reg -> ext -> set_property (psy , reg -> ext , reg -> data ,
12801312 psp , val );
@@ -1289,8 +1321,34 @@ int power_supply_set_property(struct power_supply *psy,
12891321
12901322 return psy -> desc -> set_property (psy , psp , val );
12911323}
1324+
1325+ int power_supply_set_property (struct power_supply * psy , enum power_supply_property psp ,
1326+ const union power_supply_propval * val )
1327+ {
1328+ return __power_supply_set_property (psy , psp , val , true);
1329+ }
12921330EXPORT_SYMBOL_GPL (power_supply_set_property );
12931331
1332+ /**
1333+ * power_supply_set_property_direct - Write a power supply property without checking for extensions
1334+ * @psy: The power supply
1335+ * @psp: The power supply property to write
1336+ * @val: The value to write to the power supply property
1337+ *
1338+ * Write a power supply property without taking into account any power supply extensions registered
1339+ * on the given power supply. This is mostly useful for power supply extensions that want to access
1340+ * their own power supply as using power_supply_set_property() directly will result in a potential
1341+ * deadlock.
1342+ *
1343+ * Return: 0 on success or negative error code on failure.
1344+ */
1345+ int power_supply_set_property_direct (struct power_supply * psy , enum power_supply_property psp ,
1346+ const union power_supply_propval * val )
1347+ {
1348+ return __power_supply_set_property (psy , psp , val , false);
1349+ }
1350+ EXPORT_SYMBOL_GPL (power_supply_set_property_direct );
1351+
12941352int power_supply_property_is_writeable (struct power_supply * psy ,
12951353 enum power_supply_property psp )
12961354{
0 commit comments