aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2016-08-07 23:51:25 -0400
committerGuenter Roeck <linux@roeck-us.net>2016-12-10 00:54:16 -0500
commite159ab5cb1afb519601a961405933c61cdd5a56a (patch)
tree91cd9bcdfd7910257d29023341a7fdf2fd0007a1
parentf680b2845694a197e7bfc9f56b241f9a3f17296e (diff)
hwmon: (core) Add support for string attributes to new API
The new API is so far only suited for data attributes and does not work well for string attributes, specifically for the 'label' attributes. Provide a separate callback function for those. Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/hwmon/hwmon.c33
-rw-r--r--include/linux/hwmon.h19
2 files changed, 48 insertions, 4 deletions
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index a74c075a30ec..491231fa0580 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -178,6 +178,22 @@ static ssize_t hwmon_attr_show(struct device *dev,
178 return sprintf(buf, "%ld\n", val); 178 return sprintf(buf, "%ld\n", val);
179} 179}
180 180
181static ssize_t hwmon_attr_show_string(struct device *dev,
182 struct device_attribute *devattr,
183 char *buf)
184{
185 struct hwmon_device_attribute *hattr = to_hwmon_attr(devattr);
186 char *s;
187 int ret;
188
189 ret = hattr->ops->read_string(dev, hattr->type, hattr->attr,
190 hattr->index, &s);
191 if (ret < 0)
192 return ret;
193
194 return sprintf(buf, "%s\n", s);
195}
196
181static ssize_t hwmon_attr_store(struct device *dev, 197static ssize_t hwmon_attr_store(struct device *dev,
182 struct device_attribute *devattr, 198 struct device_attribute *devattr,
183 const char *buf, size_t count) 199 const char *buf, size_t count)
@@ -205,6 +221,17 @@ static int hwmon_attr_base(enum hwmon_sensor_types type)
205 return 1; 221 return 1;
206} 222}
207 223
224static bool is_string_attr(enum hwmon_sensor_types type, u32 attr)
225{
226 return (type == hwmon_temp && attr == hwmon_temp_label) ||
227 (type == hwmon_in && attr == hwmon_in_label) ||
228 (type == hwmon_curr && attr == hwmon_curr_label) ||
229 (type == hwmon_power && attr == hwmon_power_label) ||
230 (type == hwmon_energy && attr == hwmon_energy_label) ||
231 (type == hwmon_humidity && attr == hwmon_humidity_label) ||
232 (type == hwmon_fan && attr == hwmon_fan_label);
233}
234
208static struct attribute *hwmon_genattr(struct device *dev, 235static struct attribute *hwmon_genattr(struct device *dev,
209 const void *drvdata, 236 const void *drvdata,
210 enum hwmon_sensor_types type, 237 enum hwmon_sensor_types type,
@@ -218,6 +245,7 @@ static struct attribute *hwmon_genattr(struct device *dev,
218 struct attribute *a; 245 struct attribute *a;
219 umode_t mode; 246 umode_t mode;
220 char *name; 247 char *name;
248 bool is_string = is_string_attr(type, attr);
221 249
222 /* The attribute is invisible if there is no template string */ 250 /* The attribute is invisible if there is no template string */
223 if (!template) 251 if (!template)
@@ -227,7 +255,8 @@ static struct attribute *hwmon_genattr(struct device *dev,
227 if (!mode) 255 if (!mode)
228 return ERR_PTR(-ENOENT); 256 return ERR_PTR(-ENOENT);
229 257
230 if ((mode & S_IRUGO) && !ops->read) 258 if ((mode & S_IRUGO) && ((is_string && !ops->read_string) ||
259 (!is_string && !ops->read)))
231 return ERR_PTR(-EINVAL); 260 return ERR_PTR(-EINVAL);
232 if ((mode & S_IWUGO) && !ops->write) 261 if ((mode & S_IWUGO) && !ops->write)
233 return ERR_PTR(-EINVAL); 262 return ERR_PTR(-EINVAL);
@@ -252,7 +281,7 @@ static struct attribute *hwmon_genattr(struct device *dev,
252 hattr->ops = ops; 281 hattr->ops = ops;
253 282
254 dattr = &hattr->dev_attr; 283 dattr = &hattr->dev_attr;
255 dattr->show = hwmon_attr_show; 284 dattr->show = is_string ? hwmon_attr_show_string : hwmon_attr_show;
256 dattr->store = hwmon_attr_store; 285 dattr->store = hwmon_attr_store;
257 286
258 a = &dattr->attr; 287 a = &dattr->attr;
diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h
index b6a86aa4a9e2..e68334aede4c 100644
--- a/include/linux/hwmon.h
+++ b/include/linux/hwmon.h
@@ -298,7 +298,8 @@ enum hwmon_pwm_attributes {
298 * Channel number 298 * Channel number
299 * The function returns the file permissions. 299 * The function returns the file permissions.
300 * If the return value is 0, no attribute will be created. 300 * If the return value is 0, no attribute will be created.
301 * @read: Read callback. Mandatory if readable attributes are present. 301 * @read: Read callback for data attributes. Mandatory if readable
302 * data attributes are present.
302 * Parameters are: 303 * Parameters are:
303 * @dev: Pointer to hardware monitoring device 304 * @dev: Pointer to hardware monitoring device
304 * @type: Sensor type 305 * @type: Sensor type
@@ -307,7 +308,19 @@ enum hwmon_pwm_attributes {
307 * Channel number 308 * Channel number
308 * @val: Pointer to returned value 309 * @val: Pointer to returned value
309 * The function returns 0 on success or a negative error number. 310 * The function returns 0 on success or a negative error number.
310 * @write: Write callback. Mandatory if writeable attributes are present. 311 * @read_string:
312 * Read callback for string attributes. Mandatory if string
313 * attributes are present.
314 * Parameters are:
315 * @dev: Pointer to hardware monitoring device
316 * @type: Sensor type
317 * @attr: Sensor attribute
318 * @channel:
319 * Channel number
320 * @str: Pointer to returned string
321 * The function returns 0 on success or a negative error number.
322 * @write: Write callback for data attributes. Mandatory if writeable
323 * data attributes are present.
311 * Parameters are: 324 * Parameters are:
312 * @dev: Pointer to hardware monitoring device 325 * @dev: Pointer to hardware monitoring device
313 * @type: Sensor type 326 * @type: Sensor type
@@ -322,6 +335,8 @@ struct hwmon_ops {
322 u32 attr, int channel); 335 u32 attr, int channel);
323 int (*read)(struct device *dev, enum hwmon_sensor_types type, 336 int (*read)(struct device *dev, enum hwmon_sensor_types type,
324 u32 attr, int channel, long *val); 337 u32 attr, int channel, long *val);
338 int (*read_string)(struct device *dev, enum hwmon_sensor_types type,
339 u32 attr, int channel, char **str);
325 int (*write)(struct device *dev, enum hwmon_sensor_types type, 340 int (*write)(struct device *dev, enum hwmon_sensor_types type,
326 u32 attr, int channel, long val); 341 u32 attr, int channel, long val);
327}; 342};