xref: /openbmc/linux/drivers/hwmon/ibmpowernv.c (revision 799fb82aa132fa3a3886b7872997a5a84e820062)
1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3   * IBM PowerNV platform sensors for temperature/fan/voltage/power
4   * Copyright (C) 2014 IBM
5   */
6  
7  #define DRVNAME		"ibmpowernv"
8  #define pr_fmt(fmt)	DRVNAME ": " fmt
9  
10  #include <linux/init.h>
11  #include <linux/module.h>
12  #include <linux/kernel.h>
13  #include <linux/hwmon.h>
14  #include <linux/hwmon-sysfs.h>
15  #include <linux/of.h>
16  #include <linux/slab.h>
17  
18  #include <linux/platform_device.h>
19  #include <asm/opal.h>
20  #include <linux/err.h>
21  #include <asm/cputhreads.h>
22  #include <asm/smp.h>
23  
24  #define MAX_ATTR_LEN	32
25  #define MAX_LABEL_LEN	64
26  
27  /* Sensor suffix name from DT */
28  #define DT_FAULT_ATTR_SUFFIX		"faulted"
29  #define DT_DATA_ATTR_SUFFIX		"data"
30  #define DT_THRESHOLD_ATTR_SUFFIX	"thrs"
31  
32  /*
33   * Enumerates all the types of sensors in the POWERNV platform and does index
34   * into 'struct sensor_group'
35   */
36  enum sensors {
37  	FAN,
38  	TEMP,
39  	POWER_SUPPLY,
40  	POWER_INPUT,
41  	CURRENT,
42  	ENERGY,
43  	MAX_SENSOR_TYPE,
44  };
45  
46  #define INVALID_INDEX (-1U)
47  
48  /*
49   * 'compatible' string properties for sensor types as defined in old
50   * PowerNV firmware (skiboot). These are ordered as 'enum sensors'.
51   */
52  static const char * const legacy_compatibles[] = {
53  	"ibm,opal-sensor-cooling-fan",
54  	"ibm,opal-sensor-amb-temp",
55  	"ibm,opal-sensor-power-supply",
56  	"ibm,opal-sensor-power"
57  };
58  
59  static struct sensor_group {
60  	const char *name; /* matches property 'sensor-type' */
61  	struct attribute_group group;
62  	u32 attr_count;
63  	u32 hwmon_index;
64  } sensor_groups[] = {
65  	{ "fan"   },
66  	{ "temp"  },
67  	{ "in"    },
68  	{ "power" },
69  	{ "curr"  },
70  	{ "energy" },
71  };
72  
73  struct sensor_data {
74  	u32 id; /* An opaque id of the firmware for each sensor */
75  	u32 hwmon_index;
76  	u32 opal_index;
77  	enum sensors type;
78  	char label[MAX_LABEL_LEN];
79  	char name[MAX_ATTR_LEN];
80  	struct device_attribute dev_attr;
81  	struct sensor_group_data *sgrp_data;
82  };
83  
84  struct sensor_group_data {
85  	struct mutex mutex;
86  	u32 gid;
87  	bool enable;
88  };
89  
90  struct platform_data {
91  	const struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1];
92  	struct sensor_group_data *sgrp_data;
93  	u32 sensors_count; /* Total count of sensors from each group */
94  	u32 nr_sensor_groups; /* Total number of sensor groups */
95  };
96  
97  static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
98  			   char *buf)
99  {
100  	struct sensor_data *sdata = container_of(devattr, struct sensor_data,
101  						 dev_attr);
102  	ssize_t ret;
103  	u64 x;
104  
105  	if (sdata->sgrp_data && !sdata->sgrp_data->enable)
106  		return -ENODATA;
107  
108  	ret =  opal_get_sensor_data_u64(sdata->id, &x);
109  
110  	if (ret)
111  		return ret;
112  
113  	/* Convert temperature to milli-degrees */
114  	if (sdata->type == TEMP)
115  		x *= 1000;
116  	/* Convert power to micro-watts */
117  	else if (sdata->type == POWER_INPUT)
118  		x *= 1000000;
119  
120  	return sprintf(buf, "%llu\n", x);
121  }
122  
123  static ssize_t show_enable(struct device *dev,
124  			   struct device_attribute *devattr, char *buf)
125  {
126  	struct sensor_data *sdata = container_of(devattr, struct sensor_data,
127  						 dev_attr);
128  
129  	return sprintf(buf, "%u\n", sdata->sgrp_data->enable);
130  }
131  
132  static ssize_t store_enable(struct device *dev,
133  			    struct device_attribute *devattr,
134  			    const char *buf, size_t count)
135  {
136  	struct sensor_data *sdata = container_of(devattr, struct sensor_data,
137  						 dev_attr);
138  	struct sensor_group_data *sgrp_data = sdata->sgrp_data;
139  	int ret;
140  	bool data;
141  
142  	ret = kstrtobool(buf, &data);
143  	if (ret)
144  		return ret;
145  
146  	ret = mutex_lock_interruptible(&sgrp_data->mutex);
147  	if (ret)
148  		return ret;
149  
150  	if (data != sgrp_data->enable) {
151  		ret =  sensor_group_enable(sgrp_data->gid, data);
152  		if (!ret)
153  			sgrp_data->enable = data;
154  	}
155  
156  	if (!ret)
157  		ret = count;
158  
159  	mutex_unlock(&sgrp_data->mutex);
160  	return ret;
161  }
162  
163  static ssize_t show_label(struct device *dev, struct device_attribute *devattr,
164  			  char *buf)
165  {
166  	struct sensor_data *sdata = container_of(devattr, struct sensor_data,
167  						 dev_attr);
168  
169  	return sprintf(buf, "%s\n", sdata->label);
170  }
171  
172  static int get_logical_cpu(int hwcpu)
173  {
174  	int cpu;
175  
176  	for_each_possible_cpu(cpu)
177  		if (get_hard_smp_processor_id(cpu) == hwcpu)
178  			return cpu;
179  
180  	return -ENOENT;
181  }
182  
183  static void make_sensor_label(struct device_node *np,
184  			      struct sensor_data *sdata, const char *label)
185  {
186  	u32 id;
187  	size_t n;
188  
189  	n = scnprintf(sdata->label, sizeof(sdata->label), "%s", label);
190  
191  	/*
192  	 * Core temp pretty print
193  	 */
194  	if (!of_property_read_u32(np, "ibm,pir", &id)) {
195  		int cpuid = get_logical_cpu(id);
196  
197  		if (cpuid >= 0)
198  			/*
199  			 * The digital thermal sensors are associated
200  			 * with a core.
201  			 */
202  			n += scnprintf(sdata->label + n,
203  				      sizeof(sdata->label) - n, " %d",
204  				      cpuid);
205  		else
206  			n += scnprintf(sdata->label + n,
207  				      sizeof(sdata->label) - n, " phy%d", id);
208  	}
209  
210  	/*
211  	 * Membuffer pretty print
212  	 */
213  	if (!of_property_read_u32(np, "ibm,chip-id", &id))
214  		n += scnprintf(sdata->label + n, sizeof(sdata->label) - n,
215  			      " %d", id & 0xffff);
216  }
217  
218  static int get_sensor_index_attr(const char *name, u32 *index, char *attr)
219  {
220  	char *hash_pos = strchr(name, '#');
221  	char buf[8] = { 0 };
222  	char *dash_pos;
223  	u32 copy_len;
224  	int err;
225  
226  	if (!hash_pos)
227  		return -EINVAL;
228  
229  	dash_pos = strchr(hash_pos, '-');
230  	if (!dash_pos)
231  		return -EINVAL;
232  
233  	copy_len = dash_pos - hash_pos - 1;
234  	if (copy_len >= sizeof(buf))
235  		return -EINVAL;
236  
237  	strncpy(buf, hash_pos + 1, copy_len);
238  
239  	err = kstrtou32(buf, 10, index);
240  	if (err)
241  		return err;
242  
243  	strscpy(attr, dash_pos + 1, MAX_ATTR_LEN);
244  
245  	return 0;
246  }
247  
248  static const char *convert_opal_attr_name(enum sensors type,
249  					  const char *opal_attr)
250  {
251  	const char *attr_name = NULL;
252  
253  	if (!strcmp(opal_attr, DT_FAULT_ATTR_SUFFIX)) {
254  		attr_name = "fault";
255  	} else if (!strcmp(opal_attr, DT_DATA_ATTR_SUFFIX)) {
256  		attr_name = "input";
257  	} else if (!strcmp(opal_attr, DT_THRESHOLD_ATTR_SUFFIX)) {
258  		if (type == TEMP)
259  			attr_name = "max";
260  		else if (type == FAN)
261  			attr_name = "min";
262  	}
263  
264  	return attr_name;
265  }
266  
267  /*
268   * This function translates the DT node name into the 'hwmon' attribute name.
269   * IBMPOWERNV device node appear like cooling-fan#2-data, amb-temp#1-thrs etc.
270   * which need to be mapped as fan2_input, temp1_max respectively before
271   * populating them inside hwmon device class.
272   */
273  static const char *parse_opal_node_name(const char *node_name,
274  					enum sensors type, u32 *index)
275  {
276  	char attr_suffix[MAX_ATTR_LEN];
277  	const char *attr_name;
278  	int err;
279  
280  	err = get_sensor_index_attr(node_name, index, attr_suffix);
281  	if (err)
282  		return ERR_PTR(err);
283  
284  	attr_name = convert_opal_attr_name(type, attr_suffix);
285  	if (!attr_name)
286  		return ERR_PTR(-ENOENT);
287  
288  	return attr_name;
289  }
290  
291  static int get_sensor_type(struct device_node *np)
292  {
293  	enum sensors type;
294  	const char *str;
295  
296  	for (type = 0; type < ARRAY_SIZE(legacy_compatibles); type++) {
297  		if (of_device_is_compatible(np, legacy_compatibles[type]))
298  			return type;
299  	}
300  
301  	/*
302  	 * Let's check if we have a newer device tree
303  	 */
304  	if (!of_device_is_compatible(np, "ibm,opal-sensor"))
305  		return MAX_SENSOR_TYPE;
306  
307  	if (of_property_read_string(np, "sensor-type", &str))
308  		return MAX_SENSOR_TYPE;
309  
310  	for (type = 0; type < MAX_SENSOR_TYPE; type++)
311  		if (!strcmp(str, sensor_groups[type].name))
312  			return type;
313  
314  	return MAX_SENSOR_TYPE;
315  }
316  
317  static u32 get_sensor_hwmon_index(struct sensor_data *sdata,
318  				  struct sensor_data *sdata_table, int count)
319  {
320  	int i;
321  
322  	/*
323  	 * We don't use the OPAL index on newer device trees
324  	 */
325  	if (sdata->opal_index != INVALID_INDEX) {
326  		for (i = 0; i < count; i++)
327  			if (sdata_table[i].opal_index == sdata->opal_index &&
328  			    sdata_table[i].type == sdata->type)
329  				return sdata_table[i].hwmon_index;
330  	}
331  	return ++sensor_groups[sdata->type].hwmon_index;
332  }
333  
334  static int init_sensor_group_data(struct platform_device *pdev,
335  				  struct platform_data *pdata)
336  {
337  	struct sensor_group_data *sgrp_data;
338  	struct device_node *groups, *sgrp;
339  	int count = 0, ret = 0;
340  	enum sensors type;
341  
342  	groups = of_find_compatible_node(NULL, NULL, "ibm,opal-sensor-group");
343  	if (!groups)
344  		return ret;
345  
346  	for_each_child_of_node(groups, sgrp) {
347  		type = get_sensor_type(sgrp);
348  		if (type != MAX_SENSOR_TYPE)
349  			pdata->nr_sensor_groups++;
350  	}
351  
352  	if (!pdata->nr_sensor_groups)
353  		goto out;
354  
355  	sgrp_data = devm_kcalloc(&pdev->dev, pdata->nr_sensor_groups,
356  				 sizeof(*sgrp_data), GFP_KERNEL);
357  	if (!sgrp_data) {
358  		ret = -ENOMEM;
359  		goto out;
360  	}
361  
362  	for_each_child_of_node(groups, sgrp) {
363  		u32 gid;
364  
365  		type = get_sensor_type(sgrp);
366  		if (type == MAX_SENSOR_TYPE)
367  			continue;
368  
369  		if (of_property_read_u32(sgrp, "sensor-group-id", &gid))
370  			continue;
371  
372  		if (of_count_phandle_with_args(sgrp, "sensors", NULL) <= 0)
373  			continue;
374  
375  		sensor_groups[type].attr_count++;
376  		sgrp_data[count].gid = gid;
377  		mutex_init(&sgrp_data[count].mutex);
378  		sgrp_data[count++].enable = false;
379  	}
380  
381  	pdata->sgrp_data = sgrp_data;
382  out:
383  	of_node_put(groups);
384  	return ret;
385  }
386  
387  static struct sensor_group_data *get_sensor_group(struct platform_data *pdata,
388  						  struct device_node *node,
389  						  enum sensors gtype)
390  {
391  	struct sensor_group_data *sgrp_data = pdata->sgrp_data;
392  	struct device_node *groups, *sgrp;
393  
394  	groups = of_find_compatible_node(NULL, NULL, "ibm,opal-sensor-group");
395  	if (!groups)
396  		return NULL;
397  
398  	for_each_child_of_node(groups, sgrp) {
399  		struct of_phandle_iterator it;
400  		u32 gid;
401  		int rc, i;
402  		enum sensors type;
403  
404  		type = get_sensor_type(sgrp);
405  		if (type != gtype)
406  			continue;
407  
408  		if (of_property_read_u32(sgrp, "sensor-group-id", &gid))
409  			continue;
410  
411  		of_for_each_phandle(&it, rc, sgrp, "sensors", NULL, 0)
412  			if (it.phandle == node->phandle) {
413  				of_node_put(it.node);
414  				break;
415  			}
416  
417  		if (rc)
418  			continue;
419  
420  		for (i = 0; i < pdata->nr_sensor_groups; i++)
421  			if (gid == sgrp_data[i].gid) {
422  				of_node_put(sgrp);
423  				of_node_put(groups);
424  				return &sgrp_data[i];
425  			}
426  	}
427  
428  	of_node_put(groups);
429  	return NULL;
430  }
431  
432  static int populate_attr_groups(struct platform_device *pdev)
433  {
434  	struct platform_data *pdata = platform_get_drvdata(pdev);
435  	const struct attribute_group **pgroups = pdata->attr_groups;
436  	struct device_node *opal, *np;
437  	enum sensors type;
438  	int ret;
439  
440  	ret = init_sensor_group_data(pdev, pdata);
441  	if (ret)
442  		return ret;
443  
444  	opal = of_find_node_by_path("/ibm,opal/sensors");
445  	for_each_child_of_node(opal, np) {
446  		const char *label;
447  
448  		type = get_sensor_type(np);
449  		if (type == MAX_SENSOR_TYPE)
450  			continue;
451  
452  		sensor_groups[type].attr_count++;
453  
454  		/*
455  		 * add attributes for labels, min and max
456  		 */
457  		if (!of_property_read_string(np, "label", &label))
458  			sensor_groups[type].attr_count++;
459  		if (of_find_property(np, "sensor-data-min", NULL))
460  			sensor_groups[type].attr_count++;
461  		if (of_find_property(np, "sensor-data-max", NULL))
462  			sensor_groups[type].attr_count++;
463  	}
464  
465  	of_node_put(opal);
466  
467  	for (type = 0; type < MAX_SENSOR_TYPE; type++) {
468  		sensor_groups[type].group.attrs = devm_kcalloc(&pdev->dev,
469  					sensor_groups[type].attr_count + 1,
470  					sizeof(struct attribute *),
471  					GFP_KERNEL);
472  		if (!sensor_groups[type].group.attrs)
473  			return -ENOMEM;
474  
475  		pgroups[type] = &sensor_groups[type].group;
476  		pdata->sensors_count += sensor_groups[type].attr_count;
477  		sensor_groups[type].attr_count = 0;
478  	}
479  
480  	return 0;
481  }
482  
483  static void create_hwmon_attr(struct sensor_data *sdata, const char *attr_name,
484  			      ssize_t (*show)(struct device *dev,
485  					      struct device_attribute *attr,
486  					      char *buf),
487  			    ssize_t (*store)(struct device *dev,
488  					     struct device_attribute *attr,
489  					     const char *buf, size_t count))
490  {
491  	snprintf(sdata->name, MAX_ATTR_LEN, "%s%d_%s",
492  		 sensor_groups[sdata->type].name, sdata->hwmon_index,
493  		 attr_name);
494  
495  	sysfs_attr_init(&sdata->dev_attr.attr);
496  	sdata->dev_attr.attr.name = sdata->name;
497  	sdata->dev_attr.show = show;
498  	if (store) {
499  		sdata->dev_attr.store = store;
500  		sdata->dev_attr.attr.mode = 0664;
501  	} else {
502  		sdata->dev_attr.attr.mode = 0444;
503  	}
504  }
505  
506  static void populate_sensor(struct sensor_data *sdata, int od, int hd, int sid,
507  			    const char *attr_name, enum sensors type,
508  			    const struct attribute_group *pgroup,
509  			    struct sensor_group_data *sgrp_data,
510  			    ssize_t (*show)(struct device *dev,
511  					    struct device_attribute *attr,
512  					    char *buf),
513  			    ssize_t (*store)(struct device *dev,
514  					     struct device_attribute *attr,
515  					     const char *buf, size_t count))
516  {
517  	sdata->id = sid;
518  	sdata->type = type;
519  	sdata->opal_index = od;
520  	sdata->hwmon_index = hd;
521  	create_hwmon_attr(sdata, attr_name, show, store);
522  	pgroup->attrs[sensor_groups[type].attr_count++] = &sdata->dev_attr.attr;
523  	sdata->sgrp_data = sgrp_data;
524  }
525  
526  static char *get_max_attr(enum sensors type)
527  {
528  	switch (type) {
529  	case POWER_INPUT:
530  		return "input_highest";
531  	default:
532  		return "highest";
533  	}
534  }
535  
536  static char *get_min_attr(enum sensors type)
537  {
538  	switch (type) {
539  	case POWER_INPUT:
540  		return "input_lowest";
541  	default:
542  		return "lowest";
543  	}
544  }
545  
546  /*
547   * Iterate through the device tree for each child of 'sensors' node, create
548   * a sysfs attribute file, the file is named by translating the DT node name
549   * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max
550   * etc..
551   */
552  static int create_device_attrs(struct platform_device *pdev)
553  {
554  	struct platform_data *pdata = platform_get_drvdata(pdev);
555  	const struct attribute_group **pgroups = pdata->attr_groups;
556  	struct device_node *opal, *np;
557  	struct sensor_data *sdata;
558  	u32 count = 0;
559  	u32 group_attr_id[MAX_SENSOR_TYPE] = {0};
560  
561  	sdata = devm_kcalloc(&pdev->dev,
562  			     pdata->sensors_count, sizeof(*sdata),
563  			     GFP_KERNEL);
564  	if (!sdata)
565  		return -ENOMEM;
566  
567  	opal = of_find_node_by_path("/ibm,opal/sensors");
568  	for_each_child_of_node(opal, np) {
569  		struct sensor_group_data *sgrp_data;
570  		const char *attr_name;
571  		u32 opal_index, hw_id;
572  		u32 sensor_id;
573  		const char *label;
574  		enum sensors type;
575  
576  		type = get_sensor_type(np);
577  		if (type == MAX_SENSOR_TYPE)
578  			continue;
579  
580  		/*
581  		 * Newer device trees use a "sensor-data" property
582  		 * name for input.
583  		 */
584  		if (of_property_read_u32(np, "sensor-id", &sensor_id) &&
585  		    of_property_read_u32(np, "sensor-data", &sensor_id)) {
586  			dev_info(&pdev->dev,
587  				 "'sensor-id' missing in the node '%pOFn'\n",
588  				 np);
589  			continue;
590  		}
591  
592  		sdata[count].id = sensor_id;
593  		sdata[count].type = type;
594  
595  		/*
596  		 * If we can not parse the node name, it means we are
597  		 * running on a newer device tree. We can just forget
598  		 * about the OPAL index and use a defaut value for the
599  		 * hwmon attribute name
600  		 */
601  		attr_name = parse_opal_node_name(np->name, type, &opal_index);
602  		if (IS_ERR(attr_name)) {
603  			attr_name = "input";
604  			opal_index = INVALID_INDEX;
605  		}
606  
607  		hw_id = get_sensor_hwmon_index(&sdata[count], sdata, count);
608  		sgrp_data = get_sensor_group(pdata, np, type);
609  		populate_sensor(&sdata[count], opal_index, hw_id, sensor_id,
610  				attr_name, type, pgroups[type], sgrp_data,
611  				show_sensor, NULL);
612  		count++;
613  
614  		if (!of_property_read_string(np, "label", &label)) {
615  			/*
616  			 * For the label attribute, we can reuse the
617  			 * "properties" of the previous "input"
618  			 * attribute. They are related to the same
619  			 * sensor.
620  			 */
621  
622  			make_sensor_label(np, &sdata[count], label);
623  			populate_sensor(&sdata[count], opal_index, hw_id,
624  					sensor_id, "label", type, pgroups[type],
625  					NULL, show_label, NULL);
626  			count++;
627  		}
628  
629  		if (!of_property_read_u32(np, "sensor-data-max", &sensor_id)) {
630  			attr_name = get_max_attr(type);
631  			populate_sensor(&sdata[count], opal_index, hw_id,
632  					sensor_id, attr_name, type,
633  					pgroups[type], sgrp_data, show_sensor,
634  					NULL);
635  			count++;
636  		}
637  
638  		if (!of_property_read_u32(np, "sensor-data-min", &sensor_id)) {
639  			attr_name = get_min_attr(type);
640  			populate_sensor(&sdata[count], opal_index, hw_id,
641  					sensor_id, attr_name, type,
642  					pgroups[type], sgrp_data, show_sensor,
643  					NULL);
644  			count++;
645  		}
646  
647  		if (sgrp_data && !sgrp_data->enable) {
648  			sgrp_data->enable = true;
649  			hw_id = ++group_attr_id[type];
650  			populate_sensor(&sdata[count], opal_index, hw_id,
651  					sgrp_data->gid, "enable", type,
652  					pgroups[type], sgrp_data, show_enable,
653  					store_enable);
654  			count++;
655  		}
656  	}
657  
658  	of_node_put(opal);
659  	return 0;
660  }
661  
662  static int ibmpowernv_probe(struct platform_device *pdev)
663  {
664  	struct platform_data *pdata;
665  	struct device *hwmon_dev;
666  	int err;
667  
668  	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
669  	if (!pdata)
670  		return -ENOMEM;
671  
672  	platform_set_drvdata(pdev, pdata);
673  	pdata->sensors_count = 0;
674  	pdata->nr_sensor_groups = 0;
675  	err = populate_attr_groups(pdev);
676  	if (err)
677  		return err;
678  
679  	/* Create sysfs attribute data for each sensor found in the DT */
680  	err = create_device_attrs(pdev);
681  	if (err)
682  		return err;
683  
684  	/* Finally, register with hwmon */
685  	hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, DRVNAME,
686  							   pdata,
687  							   pdata->attr_groups);
688  
689  	return PTR_ERR_OR_ZERO(hwmon_dev);
690  }
691  
692  static const struct platform_device_id opal_sensor_driver_ids[] = {
693  	{
694  		.name = "opal-sensor",
695  	},
696  	{ }
697  };
698  MODULE_DEVICE_TABLE(platform, opal_sensor_driver_ids);
699  
700  static const struct of_device_id opal_sensor_match[] = {
701  	{ .compatible	= "ibm,opal-sensor" },
702  	{ },
703  };
704  MODULE_DEVICE_TABLE(of, opal_sensor_match);
705  
706  static struct platform_driver ibmpowernv_driver = {
707  	.probe		= ibmpowernv_probe,
708  	.id_table	= opal_sensor_driver_ids,
709  	.driver		= {
710  		.name	= DRVNAME,
711  		.of_match_table	= opal_sensor_match,
712  	},
713  };
714  
715  module_platform_driver(ibmpowernv_driver);
716  
717  MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>");
718  MODULE_DESCRIPTION("IBM POWERNV platform sensors");
719  MODULE_LICENSE("GPL");
720