[PATCH v2 2/8] power: supply: Add sysfs entry for system load control
From: Waqar Hameed
Date: Tue Sep 01 2026 - 16:17:48 EST
There are devices that can control the connection from power to system
load. For example, with a field-effect transistor between a battery and
the system load (BATFET). Drivers for these devices are currently
enrolling their own custom `sysfs` property to control this.
In order to unify this, add a new `sysfs` entry for controlling such
switch and corresponding `power_supply_property` with `enum` values. The
obvious states are "on" and "off", i.e. there is a connection or not,
respectively. However, many devices can also enter special modes such as
"low-power", "shipping" or "deep sleep".
Since the members in `struct power_supply_desc` already are ordered,
adding `load_switches` only increases the size with 4 bytes, as can be
seen from `pahole`:
struct power_supply_desc {
const char * name; /* 0 4 */
enum power_supply_type type; /* 4 4 */
u32 charge_types; /* 8 4 */
u32 usb_types; /* 12 4 */
u32 load_switches; /* 16 4 */
const enum power_supply_property * properties; /* 20 4 */
size_t num_properties; /* 24 4 */
int (*get_property)(...); /* 28 4 */
int (*set_property)(...); /* 32 4 */
int (*property_is_writeable)(...); /* 36 4 */
void (*external_power_changed)(...); /* 40 4 */
int (*init)(struct power_supply *); /* 44 4 */
int use_for_apm; /* 48 4 */
bool no_thermal; /* 52 1 */
u8 charge_behaviours; /* 53 1 */
/* size: 56, cachelines: 1, members: 15 */
/* padding: 2 */
/* last cacheline: 56 bytes */
};
Signed-off-by: Waqar Hameed <waqar.hameed@xxxxxxxx>
---
Documentation/ABI/testing/sysfs-class-power | 25 +++++++++++++++++++++
drivers/power/supply/power_supply_sysfs.c | 17 ++++++++++++++
include/linux/power_supply.h | 10 +++++++++
3 files changed, 52 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-class-power b/Documentation/ABI/testing/sysfs-class-power
index 5641f1fd5fd6f..93f2398125d88 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -590,6 +590,31 @@ Description:
Valid values: 0 - 100 (percent)
+What: /sys/class/power_supply/<supply_name>/load_switch
+Date: June 2026
+Contact: linux-pm@xxxxxxxxxxxxxxx
+Description:
+ Devices can control the connection from power to system load.
+ For example, with a field-effect transistor between a battery
+ and the system load (BATFET). This entry controls such switch.
+ The obvious states are "on" and "off", i.e. there is a
+ connection or not, respectively. However, many devices can also
+ enter special modes such as "low-power", "shipping" or "deep
+ sleep". In these modes the switch is usually off and the
+ quiescent current quite low.
+
+ Access: Read, Write
+
+ Valid values:
+
+ ============= ==================================
+ "Unknown" (0) Unknown mode.
+ "On" (1) Power is connected to the load.
+ "Off" (2) Power is disconnected to the load.
+ "Standby" (3) Low-power mode.
+ "Ship" (4) Ship mode.
+ ============= ==================================
+
**USB Properties**
What: /sys/class/power_supply/<supply_name>/input_current_limit
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index 9d6b24856c8b0..b0f524d152cf6 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -152,6 +152,14 @@ static const char * const POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[] = {
[POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE] = "force-discharge",
};
+static const char *const POWER_SUPPLY_LOAD_SWITCH_TEXT[] = {
+ [POWER_SUPPLY_LOAD_SWITCH_UNKNOWN] = "Unknown",
+ [POWER_SUPPLY_LOAD_SWITCH_ON] = "On",
+ [POWER_SUPPLY_LOAD_SWITCH_OFF] = "Off",
+ [POWER_SUPPLY_LOAD_SWITCH_STANDBY] = "Standby",
+ [POWER_SUPPLY_LOAD_SWITCH_SHIP] = "Ship",
+};
+
static struct power_supply_attr power_supply_attrs[] __ro_after_init = {
/* Properties of type `int' */
POWER_SUPPLY_ENUM_ATTR(STATUS),
@@ -231,6 +239,7 @@ static struct power_supply_attr power_supply_attrs[] __ro_after_init = {
POWER_SUPPLY_ATTR(MANUFACTURE_DAY),
POWER_SUPPLY_ATTR(INTERNAL_RESISTANCE),
POWER_SUPPLY_ATTR(STATE_OF_HEALTH),
+ POWER_SUPPLY_ENUM_ATTR(LOAD_SWITCH),
/* Properties of type `const char *' */
POWER_SUPPLY_ATTR(MODEL_NAME),
POWER_SUPPLY_ATTR(MANUFACTURER),
@@ -400,6 +409,14 @@ static ssize_t power_supply_format_property(struct device *dev,
ret = power_supply_show_charge_types(dev, psy,
value.intval, buf);
break;
+ case POWER_SUPPLY_PROP_LOAD_SWITCH:
+ if (uevent) /* no possible values in uevents */
+ goto default_format;
+ ret = power_supply_show_enum_with_available(
+ dev, POWER_SUPPLY_LOAD_SWITCH_TEXT,
+ ARRAY_SIZE(POWER_SUPPLY_LOAD_SWITCH_TEXT),
+ psy->desc->load_switches, value.intval, buf);
+ break;
case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER:
ret = sysfs_emit(buf, "%s\n", value.strval);
break;
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index fcd05f4a88833..f6cbeffda6534 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -104,6 +104,14 @@ enum {
POWER_SUPPLY_SCOPE_DEVICE,
};
+enum {
+ POWER_SUPPLY_LOAD_SWITCH_UNKNOWN = 0,
+ POWER_SUPPLY_LOAD_SWITCH_ON,
+ POWER_SUPPLY_LOAD_SWITCH_OFF,
+ POWER_SUPPLY_LOAD_SWITCH_STANDBY,
+ POWER_SUPPLY_LOAD_SWITCH_SHIP,
+};
+
enum power_supply_property {
/* Properties of type `int' */
POWER_SUPPLY_PROP_STATUS = 0,
@@ -182,6 +190,7 @@ enum power_supply_property {
POWER_SUPPLY_PROP_MANUFACTURE_DAY,
POWER_SUPPLY_PROP_INTERNAL_RESISTANCE,
POWER_SUPPLY_PROP_STATE_OF_HEALTH,
+ POWER_SUPPLY_PROP_LOAD_SWITCH,
/* Properties of type `const char *' */
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER,
@@ -261,6 +270,7 @@ struct power_supply_desc {
enum power_supply_type type;
u32 charge_types;
u32 usb_types;
+ u32 load_switches;
const enum power_supply_property *properties;
size_t num_properties;
--
2.43.0