1 /* 2 * IBM PowerNV platform sensors for temperature/fan/voltage/power 3 * Copyright (C) 2014 IBM 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. 17 */ 18 19 #define DRVNAME "ibmpowernv" 20 #define pr_fmt(fmt) DRVNAME ": " fmt 21 22 #include <linux/init.h> 23 #include <linux/module.h> 24 #include <linux/kernel.h> 25 #include <linux/hwmon.h> 26 #include <linux/hwmon-sysfs.h> 27 #include <linux/of.h> 28 #include <linux/slab.h> 29 30 #include <linux/platform_device.h> 31 #include <asm/opal.h> 32 #include <linux/err.h> 33 #include <asm/cputhreads.h> 34 #include <asm/smp.h> 35 36 #define MAX_ATTR_LEN 32 37 #define MAX_LABEL_LEN 64 38 39 /* Sensor suffix name from DT */ 40 #define DT_FAULT_ATTR_SUFFIX "faulted" 41 #define DT_DATA_ATTR_SUFFIX "data" 42 #define DT_THRESHOLD_ATTR_SUFFIX "thrs" 43 44 /* 45 * Enumerates all the types of sensors in the POWERNV platform and does index 46 * into 'struct sensor_group' 47 */ 48 enum sensors { 49 FAN, 50 TEMP, 51 POWER_SUPPLY, 52 POWER_INPUT, 53 CURRENT, 54 MAX_SENSOR_TYPE, 55 }; 56 57 #define INVALID_INDEX (-1U) 58 59 /* 60 * 'compatible' string properties for sensor types as defined in old 61 * PowerNV firmware (skiboot). These are ordered as 'enum sensors'. 62 */ 63 static const char * const legacy_compatibles[] = { 64 "ibm,opal-sensor-cooling-fan", 65 "ibm,opal-sensor-amb-temp", 66 "ibm,opal-sensor-power-supply", 67 "ibm,opal-sensor-power" 68 }; 69 70 static struct sensor_group { 71 const char *name; /* matches property 'sensor-type' */ 72 struct attribute_group group; 73 u32 attr_count; 74 u32 hwmon_index; 75 } sensor_groups[] = { 76 { "fan" }, 77 { "temp" }, 78 { "in" }, 79 { "power" }, 80 { "curr" }, 81 }; 82 83 struct sensor_data { 84 u32 id; /* An opaque id of the firmware for each sensor */ 85 u32 hwmon_index; 86 u32 opal_index; 87 enum sensors type; 88 char label[MAX_LABEL_LEN]; 89 char name[MAX_ATTR_LEN]; 90 struct device_attribute dev_attr; 91 }; 92 93 struct platform_data { 94 const struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1]; 95 u32 sensors_count; /* Total count of sensors from each group */ 96 }; 97 98 static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr, 99 char *buf) 100 { 101 struct sensor_data *sdata = container_of(devattr, struct sensor_data, 102 dev_attr); 103 ssize_t ret; 104 u32 x; 105 106 ret = opal_get_sensor_data(sdata->id, &x); 107 if (ret) 108 return ret; 109 110 /* Convert temperature to milli-degrees */ 111 if (sdata->type == TEMP) 112 x *= 1000; 113 /* Convert power to micro-watts */ 114 else if (sdata->type == POWER_INPUT) 115 x *= 1000000; 116 117 return sprintf(buf, "%u\n", x); 118 } 119 120 static ssize_t show_label(struct device *dev, struct device_attribute *devattr, 121 char *buf) 122 { 123 struct sensor_data *sdata = container_of(devattr, struct sensor_data, 124 dev_attr); 125 126 return sprintf(buf, "%s\n", sdata->label); 127 } 128 129 static int __init get_logical_cpu(int hwcpu) 130 { 131 int cpu; 132 133 for_each_possible_cpu(cpu) 134 if (get_hard_smp_processor_id(cpu) == hwcpu) 135 return cpu; 136 137 return -ENOENT; 138 } 139 140 static void __init make_sensor_label(struct device_node *np, 141 struct sensor_data *sdata, 142 const char *label) 143 { 144 u32 id; 145 size_t n; 146 147 n = snprintf(sdata->label, sizeof(sdata->label), "%s", label); 148 149 /* 150 * Core temp pretty print 151 */ 152 if (!of_property_read_u32(np, "ibm,pir", &id)) { 153 int cpuid = get_logical_cpu(id); 154 155 if (cpuid >= 0) 156 /* 157 * The digital thermal sensors are associated 158 * with a core. 159 */ 160 n += snprintf(sdata->label + n, 161 sizeof(sdata->label) - n, " %d", 162 cpuid); 163 else 164 n += snprintf(sdata->label + n, 165 sizeof(sdata->label) - n, " phy%d", id); 166 } 167 168 /* 169 * Membuffer pretty print 170 */ 171 if (!of_property_read_u32(np, "ibm,chip-id", &id)) 172 n += snprintf(sdata->label + n, sizeof(sdata->label) - n, 173 " %d", id & 0xffff); 174 } 175 176 static int get_sensor_index_attr(const char *name, u32 *index, char *attr) 177 { 178 char *hash_pos = strchr(name, '#'); 179 char buf[8] = { 0 }; 180 char *dash_pos; 181 u32 copy_len; 182 int err; 183 184 if (!hash_pos) 185 return -EINVAL; 186 187 dash_pos = strchr(hash_pos, '-'); 188 if (!dash_pos) 189 return -EINVAL; 190 191 copy_len = dash_pos - hash_pos - 1; 192 if (copy_len >= sizeof(buf)) 193 return -EINVAL; 194 195 strncpy(buf, hash_pos + 1, copy_len); 196 197 err = kstrtou32(buf, 10, index); 198 if (err) 199 return err; 200 201 strncpy(attr, dash_pos + 1, MAX_ATTR_LEN); 202 203 return 0; 204 } 205 206 static const char *convert_opal_attr_name(enum sensors type, 207 const char *opal_attr) 208 { 209 const char *attr_name = NULL; 210 211 if (!strcmp(opal_attr, DT_FAULT_ATTR_SUFFIX)) { 212 attr_name = "fault"; 213 } else if (!strcmp(opal_attr, DT_DATA_ATTR_SUFFIX)) { 214 attr_name = "input"; 215 } else if (!strcmp(opal_attr, DT_THRESHOLD_ATTR_SUFFIX)) { 216 if (type == TEMP) 217 attr_name = "max"; 218 else if (type == FAN) 219 attr_name = "min"; 220 } 221 222 return attr_name; 223 } 224 225 /* 226 * This function translates the DT node name into the 'hwmon' attribute name. 227 * IBMPOWERNV device node appear like cooling-fan#2-data, amb-temp#1-thrs etc. 228 * which need to be mapped as fan2_input, temp1_max respectively before 229 * populating them inside hwmon device class. 230 */ 231 static const char *parse_opal_node_name(const char *node_name, 232 enum sensors type, u32 *index) 233 { 234 char attr_suffix[MAX_ATTR_LEN]; 235 const char *attr_name; 236 int err; 237 238 err = get_sensor_index_attr(node_name, index, attr_suffix); 239 if (err) 240 return ERR_PTR(err); 241 242 attr_name = convert_opal_attr_name(type, attr_suffix); 243 if (!attr_name) 244 return ERR_PTR(-ENOENT); 245 246 return attr_name; 247 } 248 249 static int get_sensor_type(struct device_node *np) 250 { 251 enum sensors type; 252 const char *str; 253 254 for (type = 0; type < ARRAY_SIZE(legacy_compatibles); type++) { 255 if (of_device_is_compatible(np, legacy_compatibles[type])) 256 return type; 257 } 258 259 /* 260 * Let's check if we have a newer device tree 261 */ 262 if (!of_device_is_compatible(np, "ibm,opal-sensor")) 263 return MAX_SENSOR_TYPE; 264 265 if (of_property_read_string(np, "sensor-type", &str)) 266 return MAX_SENSOR_TYPE; 267 268 for (type = 0; type < MAX_SENSOR_TYPE; type++) 269 if (!strcmp(str, sensor_groups[type].name)) 270 return type; 271 272 return MAX_SENSOR_TYPE; 273 } 274 275 static u32 get_sensor_hwmon_index(struct sensor_data *sdata, 276 struct sensor_data *sdata_table, int count) 277 { 278 int i; 279 280 /* 281 * We don't use the OPAL index on newer device trees 282 */ 283 if (sdata->opal_index != INVALID_INDEX) { 284 for (i = 0; i < count; i++) 285 if (sdata_table[i].opal_index == sdata->opal_index && 286 sdata_table[i].type == sdata->type) 287 return sdata_table[i].hwmon_index; 288 } 289 return ++sensor_groups[sdata->type].hwmon_index; 290 } 291 292 static int populate_attr_groups(struct platform_device *pdev) 293 { 294 struct platform_data *pdata = platform_get_drvdata(pdev); 295 const struct attribute_group **pgroups = pdata->attr_groups; 296 struct device_node *opal, *np; 297 enum sensors type; 298 299 opal = of_find_node_by_path("/ibm,opal/sensors"); 300 for_each_child_of_node(opal, np) { 301 const char *label; 302 303 if (np->name == NULL) 304 continue; 305 306 type = get_sensor_type(np); 307 if (type == MAX_SENSOR_TYPE) 308 continue; 309 310 sensor_groups[type].attr_count++; 311 312 /* 313 * add attributes for labels, min and max 314 */ 315 if (!of_property_read_string(np, "label", &label)) 316 sensor_groups[type].attr_count++; 317 if (of_find_property(np, "sensor-data-min", NULL)) 318 sensor_groups[type].attr_count++; 319 if (of_find_property(np, "sensor-data-max", NULL)) 320 sensor_groups[type].attr_count++; 321 } 322 323 of_node_put(opal); 324 325 for (type = 0; type < MAX_SENSOR_TYPE; type++) { 326 sensor_groups[type].group.attrs = devm_kzalloc(&pdev->dev, 327 sizeof(struct attribute *) * 328 (sensor_groups[type].attr_count + 1), 329 GFP_KERNEL); 330 if (!sensor_groups[type].group.attrs) 331 return -ENOMEM; 332 333 pgroups[type] = &sensor_groups[type].group; 334 pdata->sensors_count += sensor_groups[type].attr_count; 335 sensor_groups[type].attr_count = 0; 336 } 337 338 return 0; 339 } 340 341 static void create_hwmon_attr(struct sensor_data *sdata, const char *attr_name, 342 ssize_t (*show)(struct device *dev, 343 struct device_attribute *attr, 344 char *buf)) 345 { 346 snprintf(sdata->name, MAX_ATTR_LEN, "%s%d_%s", 347 sensor_groups[sdata->type].name, sdata->hwmon_index, 348 attr_name); 349 350 sysfs_attr_init(&sdata->dev_attr.attr); 351 sdata->dev_attr.attr.name = sdata->name; 352 sdata->dev_attr.attr.mode = S_IRUGO; 353 sdata->dev_attr.show = show; 354 } 355 356 static void populate_sensor(struct sensor_data *sdata, int od, int hd, int sid, 357 const char *attr_name, enum sensors type, 358 const struct attribute_group *pgroup, 359 ssize_t (*show)(struct device *dev, 360 struct device_attribute *attr, 361 char *buf)) 362 { 363 sdata->id = sid; 364 sdata->type = type; 365 sdata->opal_index = od; 366 sdata->hwmon_index = hd; 367 create_hwmon_attr(sdata, attr_name, show); 368 pgroup->attrs[sensor_groups[type].attr_count++] = &sdata->dev_attr.attr; 369 } 370 371 static char *get_max_attr(enum sensors type) 372 { 373 switch (type) { 374 case POWER_INPUT: 375 return "input_highest"; 376 default: 377 return "highest"; 378 } 379 } 380 381 static char *get_min_attr(enum sensors type) 382 { 383 switch (type) { 384 case POWER_INPUT: 385 return "input_lowest"; 386 default: 387 return "lowest"; 388 } 389 } 390 391 /* 392 * Iterate through the device tree for each child of 'sensors' node, create 393 * a sysfs attribute file, the file is named by translating the DT node name 394 * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max 395 * etc.. 396 */ 397 static int create_device_attrs(struct platform_device *pdev) 398 { 399 struct platform_data *pdata = platform_get_drvdata(pdev); 400 const struct attribute_group **pgroups = pdata->attr_groups; 401 struct device_node *opal, *np; 402 struct sensor_data *sdata; 403 u32 sensor_id; 404 enum sensors type; 405 u32 count = 0; 406 int err = 0; 407 408 opal = of_find_node_by_path("/ibm,opal/sensors"); 409 sdata = devm_kzalloc(&pdev->dev, pdata->sensors_count * sizeof(*sdata), 410 GFP_KERNEL); 411 if (!sdata) { 412 err = -ENOMEM; 413 goto exit_put_node; 414 } 415 416 for_each_child_of_node(opal, np) { 417 const char *attr_name; 418 u32 opal_index; 419 const char *label; 420 421 if (np->name == NULL) 422 continue; 423 424 type = get_sensor_type(np); 425 if (type == MAX_SENSOR_TYPE) 426 continue; 427 428 /* 429 * Newer device trees use a "sensor-data" property 430 * name for input. 431 */ 432 if (of_property_read_u32(np, "sensor-id", &sensor_id) && 433 of_property_read_u32(np, "sensor-data", &sensor_id)) { 434 dev_info(&pdev->dev, 435 "'sensor-id' missing in the node '%s'\n", 436 np->name); 437 continue; 438 } 439 440 sdata[count].id = sensor_id; 441 sdata[count].type = type; 442 443 /* 444 * If we can not parse the node name, it means we are 445 * running on a newer device tree. We can just forget 446 * about the OPAL index and use a defaut value for the 447 * hwmon attribute name 448 */ 449 attr_name = parse_opal_node_name(np->name, type, &opal_index); 450 if (IS_ERR(attr_name)) { 451 attr_name = "input"; 452 opal_index = INVALID_INDEX; 453 } 454 455 sdata[count].opal_index = opal_index; 456 sdata[count].hwmon_index = 457 get_sensor_hwmon_index(&sdata[count], sdata, count); 458 459 create_hwmon_attr(&sdata[count], attr_name, show_sensor); 460 461 pgroups[type]->attrs[sensor_groups[type].attr_count++] = 462 &sdata[count++].dev_attr.attr; 463 464 if (!of_property_read_string(np, "label", &label)) { 465 /* 466 * For the label attribute, we can reuse the 467 * "properties" of the previous "input" 468 * attribute. They are related to the same 469 * sensor. 470 */ 471 472 make_sensor_label(np, &sdata[count], label); 473 populate_sensor(&sdata[count], opal_index, 474 sdata[count - 1].hwmon_index, 475 sensor_id, "label", type, pgroups[type], 476 show_label); 477 count++; 478 } 479 480 if (!of_property_read_u32(np, "sensor-data-max", &sensor_id)) { 481 attr_name = get_max_attr(type); 482 populate_sensor(&sdata[count], opal_index, 483 sdata[count - 1].hwmon_index, 484 sensor_id, attr_name, type, 485 pgroups[type], show_sensor); 486 count++; 487 } 488 489 if (!of_property_read_u32(np, "sensor-data-min", &sensor_id)) { 490 attr_name = get_min_attr(type); 491 populate_sensor(&sdata[count], opal_index, 492 sdata[count - 1].hwmon_index, 493 sensor_id, attr_name, type, 494 pgroups[type], show_sensor); 495 count++; 496 } 497 } 498 499 exit_put_node: 500 of_node_put(opal); 501 return err; 502 } 503 504 static int ibmpowernv_probe(struct platform_device *pdev) 505 { 506 struct platform_data *pdata; 507 struct device *hwmon_dev; 508 int err; 509 510 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 511 if (!pdata) 512 return -ENOMEM; 513 514 platform_set_drvdata(pdev, pdata); 515 pdata->sensors_count = 0; 516 err = populate_attr_groups(pdev); 517 if (err) 518 return err; 519 520 /* Create sysfs attribute data for each sensor found in the DT */ 521 err = create_device_attrs(pdev); 522 if (err) 523 return err; 524 525 /* Finally, register with hwmon */ 526 hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, DRVNAME, 527 pdata, 528 pdata->attr_groups); 529 530 return PTR_ERR_OR_ZERO(hwmon_dev); 531 } 532 533 static const struct platform_device_id opal_sensor_driver_ids[] = { 534 { 535 .name = "opal-sensor", 536 }, 537 { } 538 }; 539 MODULE_DEVICE_TABLE(platform, opal_sensor_driver_ids); 540 541 static const struct of_device_id opal_sensor_match[] = { 542 { .compatible = "ibm,opal-sensor" }, 543 { }, 544 }; 545 MODULE_DEVICE_TABLE(of, opal_sensor_match); 546 547 static struct platform_driver ibmpowernv_driver = { 548 .probe = ibmpowernv_probe, 549 .id_table = opal_sensor_driver_ids, 550 .driver = { 551 .name = DRVNAME, 552 .of_match_table = opal_sensor_match, 553 }, 554 }; 555 556 module_platform_driver(ibmpowernv_driver); 557 558 MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>"); 559 MODULE_DESCRIPTION("IBM POWERNV platform sensors"); 560 MODULE_LICENSE("GPL"); 561