diff options
| -rw-r--r-- | drivers/power/power_supply_sysfs.c | 38 | ||||
| -rw-r--r-- | include/linux/power_supply.h | 5 |
2 files changed, 40 insertions, 3 deletions
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 7d7593cad7d9..6a86cdfd79fa 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | { \ | 33 | { \ |
| 34 | .attr = { .name = #_name }, \ | 34 | .attr = { .name = #_name }, \ |
| 35 | .show = power_supply_show_property, \ | 35 | .show = power_supply_show_property, \ |
| 36 | .store = NULL, \ | 36 | .store = power_supply_store_property, \ |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static struct device_attribute power_supply_attrs[]; | 39 | static struct device_attribute power_supply_attrs[]; |
| @@ -99,6 +99,29 @@ static ssize_t power_supply_show_property(struct device *dev, | |||
| 99 | return sprintf(buf, "%d\n", value.intval); | 99 | return sprintf(buf, "%d\n", value.intval); |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | static ssize_t power_supply_store_property(struct device *dev, | ||
| 103 | struct device_attribute *attr, | ||
| 104 | const char *buf, size_t count) { | ||
| 105 | ssize_t ret; | ||
| 106 | struct power_supply *psy = dev_get_drvdata(dev); | ||
| 107 | const ptrdiff_t off = attr - power_supply_attrs; | ||
| 108 | union power_supply_propval value; | ||
| 109 | long long_val; | ||
| 110 | |||
| 111 | /* TODO: support other types than int */ | ||
| 112 | ret = strict_strtol(buf, 10, &long_val); | ||
| 113 | if (ret < 0) | ||
| 114 | return ret; | ||
| 115 | |||
| 116 | value.intval = long_val; | ||
| 117 | |||
| 118 | ret = psy->set_property(psy, off, &value); | ||
| 119 | if (ret < 0) | ||
| 120 | return ret; | ||
| 121 | |||
| 122 | return count; | ||
| 123 | } | ||
| 124 | |||
| 102 | /* Must be in the same order as POWER_SUPPLY_PROP_* */ | 125 | /* Must be in the same order as POWER_SUPPLY_PROP_* */ |
| 103 | static struct device_attribute power_supply_attrs[] = { | 126 | static struct device_attribute power_supply_attrs[] = { |
| 104 | /* Properties of type `int' */ | 127 | /* Properties of type `int' */ |
| @@ -159,8 +182,17 @@ static mode_t power_supply_attr_is_visible(struct kobject *kobj, | |||
| 159 | int i; | 182 | int i; |
| 160 | 183 | ||
| 161 | for (i = 0; i < psy->num_properties; i++) { | 184 | for (i = 0; i < psy->num_properties; i++) { |
| 162 | if (psy->properties[i] == attrno) | 185 | int property = psy->properties[i]; |
| 163 | return 0444; | 186 | |
| 187 | if (property == attrno) { | ||
| 188 | mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; | ||
| 189 | |||
| 190 | if (psy->property_is_writeable && | ||
| 191 | psy->property_is_writeable(psy, property) > 0) | ||
| 192 | mode |= S_IWUSR; | ||
| 193 | |||
| 194 | return mode; | ||
| 195 | } | ||
| 164 | } | 196 | } |
| 165 | 197 | ||
| 166 | return 0; | 198 | return 0; |
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index c5f73a3ab3ab..30083a896f36 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h | |||
| @@ -145,6 +145,11 @@ struct power_supply { | |||
| 145 | int (*get_property)(struct power_supply *psy, | 145 | int (*get_property)(struct power_supply *psy, |
| 146 | enum power_supply_property psp, | 146 | enum power_supply_property psp, |
| 147 | union power_supply_propval *val); | 147 | union power_supply_propval *val); |
| 148 | int (*set_property)(struct power_supply *psy, | ||
| 149 | enum power_supply_property psp, | ||
| 150 | const union power_supply_propval *val); | ||
| 151 | int (*property_is_writeable)(struct power_supply *psy, | ||
| 152 | enum power_supply_property psp); | ||
| 148 | void (*external_power_changed)(struct power_supply *psy); | 153 | void (*external_power_changed)(struct power_supply *psy); |
| 149 | void (*set_charged)(struct power_supply *psy); | 154 | void (*set_charged)(struct power_supply *psy); |
| 150 | 155 | ||
