OSDN Git Service

power: supply: add helpers for charge_behaviour sysfs
authorThomas Weißschuh <linux@weissschuh.net>
Tue, 23 Nov 2021 23:27:02 +0000 (00:27 +0100)
committerHans de Goede <hdegoede@redhat.com>
Tue, 21 Dec 2021 15:27:42 +0000 (16:27 +0100)
These helper functions can be used by drivers to implement their own
sysfs-attributes.
This is useful for ACPI-drivers extending the default ACPI-battery with
their own charge_behaviour attributes.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://lore.kernel.org/r/20211123232704.25394-3-linux@weissschuh.net
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
drivers/power/supply/power_supply_sysfs.c
include/linux/power_supply.h

index c3d7cbc..5e3b8c1 100644 (file)
@@ -133,6 +133,12 @@ static const char * const POWER_SUPPLY_SCOPE_TEXT[] = {
        [POWER_SUPPLY_SCOPE_DEVICE]     = "Device",
 };
 
+static const char * const POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[] = {
+       [POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO]            = "auto",
+       [POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE]  = "inhibit-charge",
+       [POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE] = "force-discharge",
+};
+
 static struct power_supply_attr power_supply_attrs[] = {
        /* Properties of type `int' */
        POWER_SUPPLY_ENUM_ATTR(STATUS),
@@ -484,3 +490,52 @@ out:
 
        return ret;
 }
+
+ssize_t power_supply_charge_behaviour_show(struct device *dev,
+                                          unsigned int available_behaviours,
+                                          enum power_supply_charge_behaviour current_behaviour,
+                                          char *buf)
+{
+       bool match = false, available, active;
+       ssize_t count = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT); i++) {
+               available = available_behaviours & BIT(i);
+               active = i == current_behaviour;
+
+               if (available && active) {
+                       count += sysfs_emit_at(buf, count, "[%s] ",
+                                              POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[i]);
+                       match = true;
+               } else if (available) {
+                       count += sysfs_emit_at(buf, count, "%s ",
+                                              POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[i]);
+               }
+       }
+
+       if (!match) {
+               dev_warn(dev, "driver reporting unsupported charge behaviour\n");
+               return -EINVAL;
+       }
+
+       if (count)
+               buf[count - 1] = '\n';
+
+       return count;
+}
+EXPORT_SYMBOL_GPL(power_supply_charge_behaviour_show);
+
+int power_supply_charge_behaviour_parse(unsigned int available_behaviours, const char *buf)
+{
+       int i = sysfs_match_string(POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT, buf);
+
+       if (i < 0)
+               return i;
+
+       if (available_behaviours & BIT(i))
+               return i;
+
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(power_supply_charge_behaviour_parse);
index 70c333e..71f0379 100644 (file)
@@ -546,4 +546,13 @@ static inline
 void power_supply_remove_hwmon_sysfs(struct power_supply *psy) {}
 #endif
 
+#ifdef CONFIG_SYSFS
+ssize_t power_supply_charge_behaviour_show(struct device *dev,
+                                          unsigned int available_behaviours,
+                                          enum power_supply_charge_behaviour behaviour,
+                                          char *buf);
+
+int power_supply_charge_behaviour_parse(unsigned int available_behaviours, const char *buf);
+#endif
+
 #endif /* __LINUX_POWER_SUPPLY_H__ */