0001
0002
0003
0004
0005
0006
0007 #define DRVNAME "ibmpowernv"
0008 #define pr_fmt(fmt) DRVNAME ": " fmt
0009
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012 #include <linux/kernel.h>
0013 #include <linux/hwmon.h>
0014 #include <linux/hwmon-sysfs.h>
0015 #include <linux/of.h>
0016 #include <linux/slab.h>
0017
0018 #include <linux/platform_device.h>
0019 #include <asm/opal.h>
0020 #include <linux/err.h>
0021 #include <asm/cputhreads.h>
0022 #include <asm/smp.h>
0023
0024 #define MAX_ATTR_LEN 32
0025 #define MAX_LABEL_LEN 64
0026
0027
0028 #define DT_FAULT_ATTR_SUFFIX "faulted"
0029 #define DT_DATA_ATTR_SUFFIX "data"
0030 #define DT_THRESHOLD_ATTR_SUFFIX "thrs"
0031
0032
0033
0034
0035
0036 enum sensors {
0037 FAN,
0038 TEMP,
0039 POWER_SUPPLY,
0040 POWER_INPUT,
0041 CURRENT,
0042 ENERGY,
0043 MAX_SENSOR_TYPE,
0044 };
0045
0046 #define INVALID_INDEX (-1U)
0047
0048
0049
0050
0051
0052 static const char * const legacy_compatibles[] = {
0053 "ibm,opal-sensor-cooling-fan",
0054 "ibm,opal-sensor-amb-temp",
0055 "ibm,opal-sensor-power-supply",
0056 "ibm,opal-sensor-power"
0057 };
0058
0059 static struct sensor_group {
0060 const char *name;
0061 struct attribute_group group;
0062 u32 attr_count;
0063 u32 hwmon_index;
0064 } sensor_groups[] = {
0065 { "fan" },
0066 { "temp" },
0067 { "in" },
0068 { "power" },
0069 { "curr" },
0070 { "energy" },
0071 };
0072
0073 struct sensor_data {
0074 u32 id;
0075 u32 hwmon_index;
0076 u32 opal_index;
0077 enum sensors type;
0078 char label[MAX_LABEL_LEN];
0079 char name[MAX_ATTR_LEN];
0080 struct device_attribute dev_attr;
0081 struct sensor_group_data *sgrp_data;
0082 };
0083
0084 struct sensor_group_data {
0085 struct mutex mutex;
0086 u32 gid;
0087 bool enable;
0088 };
0089
0090 struct platform_data {
0091 const struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1];
0092 struct sensor_group_data *sgrp_data;
0093 u32 sensors_count;
0094 u32 nr_sensor_groups;
0095 };
0096
0097 static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
0098 char *buf)
0099 {
0100 struct sensor_data *sdata = container_of(devattr, struct sensor_data,
0101 dev_attr);
0102 ssize_t ret;
0103 u64 x;
0104
0105 if (sdata->sgrp_data && !sdata->sgrp_data->enable)
0106 return -ENODATA;
0107
0108 ret = opal_get_sensor_data_u64(sdata->id, &x);
0109
0110 if (ret)
0111 return ret;
0112
0113
0114 if (sdata->type == TEMP)
0115 x *= 1000;
0116
0117 else if (sdata->type == POWER_INPUT)
0118 x *= 1000000;
0119
0120 return sprintf(buf, "%llu\n", x);
0121 }
0122
0123 static ssize_t show_enable(struct device *dev,
0124 struct device_attribute *devattr, char *buf)
0125 {
0126 struct sensor_data *sdata = container_of(devattr, struct sensor_data,
0127 dev_attr);
0128
0129 return sprintf(buf, "%u\n", sdata->sgrp_data->enable);
0130 }
0131
0132 static ssize_t store_enable(struct device *dev,
0133 struct device_attribute *devattr,
0134 const char *buf, size_t count)
0135 {
0136 struct sensor_data *sdata = container_of(devattr, struct sensor_data,
0137 dev_attr);
0138 struct sensor_group_data *sgrp_data = sdata->sgrp_data;
0139 int ret;
0140 bool data;
0141
0142 ret = kstrtobool(buf, &data);
0143 if (ret)
0144 return ret;
0145
0146 ret = mutex_lock_interruptible(&sgrp_data->mutex);
0147 if (ret)
0148 return ret;
0149
0150 if (data != sgrp_data->enable) {
0151 ret = sensor_group_enable(sgrp_data->gid, data);
0152 if (!ret)
0153 sgrp_data->enable = data;
0154 }
0155
0156 if (!ret)
0157 ret = count;
0158
0159 mutex_unlock(&sgrp_data->mutex);
0160 return ret;
0161 }
0162
0163 static ssize_t show_label(struct device *dev, struct device_attribute *devattr,
0164 char *buf)
0165 {
0166 struct sensor_data *sdata = container_of(devattr, struct sensor_data,
0167 dev_attr);
0168
0169 return sprintf(buf, "%s\n", sdata->label);
0170 }
0171
0172 static int get_logical_cpu(int hwcpu)
0173 {
0174 int cpu;
0175
0176 for_each_possible_cpu(cpu)
0177 if (get_hard_smp_processor_id(cpu) == hwcpu)
0178 return cpu;
0179
0180 return -ENOENT;
0181 }
0182
0183 static void make_sensor_label(struct device_node *np,
0184 struct sensor_data *sdata, const char *label)
0185 {
0186 u32 id;
0187 size_t n;
0188
0189 n = scnprintf(sdata->label, sizeof(sdata->label), "%s", label);
0190
0191
0192
0193
0194 if (!of_property_read_u32(np, "ibm,pir", &id)) {
0195 int cpuid = get_logical_cpu(id);
0196
0197 if (cpuid >= 0)
0198
0199
0200
0201
0202 n += scnprintf(sdata->label + n,
0203 sizeof(sdata->label) - n, " %d",
0204 cpuid);
0205 else
0206 n += scnprintf(sdata->label + n,
0207 sizeof(sdata->label) - n, " phy%d", id);
0208 }
0209
0210
0211
0212
0213 if (!of_property_read_u32(np, "ibm,chip-id", &id))
0214 n += scnprintf(sdata->label + n, sizeof(sdata->label) - n,
0215 " %d", id & 0xffff);
0216 }
0217
0218 static int get_sensor_index_attr(const char *name, u32 *index, char *attr)
0219 {
0220 char *hash_pos = strchr(name, '#');
0221 char buf[8] = { 0 };
0222 char *dash_pos;
0223 u32 copy_len;
0224 int err;
0225
0226 if (!hash_pos)
0227 return -EINVAL;
0228
0229 dash_pos = strchr(hash_pos, '-');
0230 if (!dash_pos)
0231 return -EINVAL;
0232
0233 copy_len = dash_pos - hash_pos - 1;
0234 if (copy_len >= sizeof(buf))
0235 return -EINVAL;
0236
0237 strncpy(buf, hash_pos + 1, copy_len);
0238
0239 err = kstrtou32(buf, 10, index);
0240 if (err)
0241 return err;
0242
0243 strscpy(attr, dash_pos + 1, MAX_ATTR_LEN);
0244
0245 return 0;
0246 }
0247
0248 static const char *convert_opal_attr_name(enum sensors type,
0249 const char *opal_attr)
0250 {
0251 const char *attr_name = NULL;
0252
0253 if (!strcmp(opal_attr, DT_FAULT_ATTR_SUFFIX)) {
0254 attr_name = "fault";
0255 } else if (!strcmp(opal_attr, DT_DATA_ATTR_SUFFIX)) {
0256 attr_name = "input";
0257 } else if (!strcmp(opal_attr, DT_THRESHOLD_ATTR_SUFFIX)) {
0258 if (type == TEMP)
0259 attr_name = "max";
0260 else if (type == FAN)
0261 attr_name = "min";
0262 }
0263
0264 return attr_name;
0265 }
0266
0267
0268
0269
0270
0271
0272
0273 static const char *parse_opal_node_name(const char *node_name,
0274 enum sensors type, u32 *index)
0275 {
0276 char attr_suffix[MAX_ATTR_LEN];
0277 const char *attr_name;
0278 int err;
0279
0280 err = get_sensor_index_attr(node_name, index, attr_suffix);
0281 if (err)
0282 return ERR_PTR(err);
0283
0284 attr_name = convert_opal_attr_name(type, attr_suffix);
0285 if (!attr_name)
0286 return ERR_PTR(-ENOENT);
0287
0288 return attr_name;
0289 }
0290
0291 static int get_sensor_type(struct device_node *np)
0292 {
0293 enum sensors type;
0294 const char *str;
0295
0296 for (type = 0; type < ARRAY_SIZE(legacy_compatibles); type++) {
0297 if (of_device_is_compatible(np, legacy_compatibles[type]))
0298 return type;
0299 }
0300
0301
0302
0303
0304 if (!of_device_is_compatible(np, "ibm,opal-sensor"))
0305 return MAX_SENSOR_TYPE;
0306
0307 if (of_property_read_string(np, "sensor-type", &str))
0308 return MAX_SENSOR_TYPE;
0309
0310 for (type = 0; type < MAX_SENSOR_TYPE; type++)
0311 if (!strcmp(str, sensor_groups[type].name))
0312 return type;
0313
0314 return MAX_SENSOR_TYPE;
0315 }
0316
0317 static u32 get_sensor_hwmon_index(struct sensor_data *sdata,
0318 struct sensor_data *sdata_table, int count)
0319 {
0320 int i;
0321
0322
0323
0324
0325 if (sdata->opal_index != INVALID_INDEX) {
0326 for (i = 0; i < count; i++)
0327 if (sdata_table[i].opal_index == sdata->opal_index &&
0328 sdata_table[i].type == sdata->type)
0329 return sdata_table[i].hwmon_index;
0330 }
0331 return ++sensor_groups[sdata->type].hwmon_index;
0332 }
0333
0334 static int init_sensor_group_data(struct platform_device *pdev,
0335 struct platform_data *pdata)
0336 {
0337 struct sensor_group_data *sgrp_data;
0338 struct device_node *groups, *sgrp;
0339 int count = 0, ret = 0;
0340 enum sensors type;
0341
0342 groups = of_find_compatible_node(NULL, NULL, "ibm,opal-sensor-group");
0343 if (!groups)
0344 return ret;
0345
0346 for_each_child_of_node(groups, sgrp) {
0347 type = get_sensor_type(sgrp);
0348 if (type != MAX_SENSOR_TYPE)
0349 pdata->nr_sensor_groups++;
0350 }
0351
0352 if (!pdata->nr_sensor_groups)
0353 goto out;
0354
0355 sgrp_data = devm_kcalloc(&pdev->dev, pdata->nr_sensor_groups,
0356 sizeof(*sgrp_data), GFP_KERNEL);
0357 if (!sgrp_data) {
0358 ret = -ENOMEM;
0359 goto out;
0360 }
0361
0362 for_each_child_of_node(groups, sgrp) {
0363 u32 gid;
0364
0365 type = get_sensor_type(sgrp);
0366 if (type == MAX_SENSOR_TYPE)
0367 continue;
0368
0369 if (of_property_read_u32(sgrp, "sensor-group-id", &gid))
0370 continue;
0371
0372 if (of_count_phandle_with_args(sgrp, "sensors", NULL) <= 0)
0373 continue;
0374
0375 sensor_groups[type].attr_count++;
0376 sgrp_data[count].gid = gid;
0377 mutex_init(&sgrp_data[count].mutex);
0378 sgrp_data[count++].enable = false;
0379 }
0380
0381 pdata->sgrp_data = sgrp_data;
0382 out:
0383 of_node_put(groups);
0384 return ret;
0385 }
0386
0387 static struct sensor_group_data *get_sensor_group(struct platform_data *pdata,
0388 struct device_node *node,
0389 enum sensors gtype)
0390 {
0391 struct sensor_group_data *sgrp_data = pdata->sgrp_data;
0392 struct device_node *groups, *sgrp;
0393
0394 groups = of_find_compatible_node(NULL, NULL, "ibm,opal-sensor-group");
0395 if (!groups)
0396 return NULL;
0397
0398 for_each_child_of_node(groups, sgrp) {
0399 struct of_phandle_iterator it;
0400 u32 gid;
0401 int rc, i;
0402 enum sensors type;
0403
0404 type = get_sensor_type(sgrp);
0405 if (type != gtype)
0406 continue;
0407
0408 if (of_property_read_u32(sgrp, "sensor-group-id", &gid))
0409 continue;
0410
0411 of_for_each_phandle(&it, rc, sgrp, "sensors", NULL, 0)
0412 if (it.phandle == node->phandle) {
0413 of_node_put(it.node);
0414 break;
0415 }
0416
0417 if (rc)
0418 continue;
0419
0420 for (i = 0; i < pdata->nr_sensor_groups; i++)
0421 if (gid == sgrp_data[i].gid) {
0422 of_node_put(sgrp);
0423 of_node_put(groups);
0424 return &sgrp_data[i];
0425 }
0426 }
0427
0428 of_node_put(groups);
0429 return NULL;
0430 }
0431
0432 static int populate_attr_groups(struct platform_device *pdev)
0433 {
0434 struct platform_data *pdata = platform_get_drvdata(pdev);
0435 const struct attribute_group **pgroups = pdata->attr_groups;
0436 struct device_node *opal, *np;
0437 enum sensors type;
0438 int ret;
0439
0440 ret = init_sensor_group_data(pdev, pdata);
0441 if (ret)
0442 return ret;
0443
0444 opal = of_find_node_by_path("/ibm,opal/sensors");
0445 for_each_child_of_node(opal, np) {
0446 const char *label;
0447
0448 type = get_sensor_type(np);
0449 if (type == MAX_SENSOR_TYPE)
0450 continue;
0451
0452 sensor_groups[type].attr_count++;
0453
0454
0455
0456
0457 if (!of_property_read_string(np, "label", &label))
0458 sensor_groups[type].attr_count++;
0459 if (of_find_property(np, "sensor-data-min", NULL))
0460 sensor_groups[type].attr_count++;
0461 if (of_find_property(np, "sensor-data-max", NULL))
0462 sensor_groups[type].attr_count++;
0463 }
0464
0465 of_node_put(opal);
0466
0467 for (type = 0; type < MAX_SENSOR_TYPE; type++) {
0468 sensor_groups[type].group.attrs = devm_kcalloc(&pdev->dev,
0469 sensor_groups[type].attr_count + 1,
0470 sizeof(struct attribute *),
0471 GFP_KERNEL);
0472 if (!sensor_groups[type].group.attrs)
0473 return -ENOMEM;
0474
0475 pgroups[type] = &sensor_groups[type].group;
0476 pdata->sensors_count += sensor_groups[type].attr_count;
0477 sensor_groups[type].attr_count = 0;
0478 }
0479
0480 return 0;
0481 }
0482
0483 static void create_hwmon_attr(struct sensor_data *sdata, const char *attr_name,
0484 ssize_t (*show)(struct device *dev,
0485 struct device_attribute *attr,
0486 char *buf),
0487 ssize_t (*store)(struct device *dev,
0488 struct device_attribute *attr,
0489 const char *buf, size_t count))
0490 {
0491 snprintf(sdata->name, MAX_ATTR_LEN, "%s%d_%s",
0492 sensor_groups[sdata->type].name, sdata->hwmon_index,
0493 attr_name);
0494
0495 sysfs_attr_init(&sdata->dev_attr.attr);
0496 sdata->dev_attr.attr.name = sdata->name;
0497 sdata->dev_attr.show = show;
0498 if (store) {
0499 sdata->dev_attr.store = store;
0500 sdata->dev_attr.attr.mode = 0664;
0501 } else {
0502 sdata->dev_attr.attr.mode = 0444;
0503 }
0504 }
0505
0506 static void populate_sensor(struct sensor_data *sdata, int od, int hd, int sid,
0507 const char *attr_name, enum sensors type,
0508 const struct attribute_group *pgroup,
0509 struct sensor_group_data *sgrp_data,
0510 ssize_t (*show)(struct device *dev,
0511 struct device_attribute *attr,
0512 char *buf),
0513 ssize_t (*store)(struct device *dev,
0514 struct device_attribute *attr,
0515 const char *buf, size_t count))
0516 {
0517 sdata->id = sid;
0518 sdata->type = type;
0519 sdata->opal_index = od;
0520 sdata->hwmon_index = hd;
0521 create_hwmon_attr(sdata, attr_name, show, store);
0522 pgroup->attrs[sensor_groups[type].attr_count++] = &sdata->dev_attr.attr;
0523 sdata->sgrp_data = sgrp_data;
0524 }
0525
0526 static char *get_max_attr(enum sensors type)
0527 {
0528 switch (type) {
0529 case POWER_INPUT:
0530 return "input_highest";
0531 default:
0532 return "highest";
0533 }
0534 }
0535
0536 static char *get_min_attr(enum sensors type)
0537 {
0538 switch (type) {
0539 case POWER_INPUT:
0540 return "input_lowest";
0541 default:
0542 return "lowest";
0543 }
0544 }
0545
0546
0547
0548
0549
0550
0551
0552 static int create_device_attrs(struct platform_device *pdev)
0553 {
0554 struct platform_data *pdata = platform_get_drvdata(pdev);
0555 const struct attribute_group **pgroups = pdata->attr_groups;
0556 struct device_node *opal, *np;
0557 struct sensor_data *sdata;
0558 u32 count = 0;
0559 u32 group_attr_id[MAX_SENSOR_TYPE] = {0};
0560
0561 sdata = devm_kcalloc(&pdev->dev,
0562 pdata->sensors_count, sizeof(*sdata),
0563 GFP_KERNEL);
0564 if (!sdata)
0565 return -ENOMEM;
0566
0567 opal = of_find_node_by_path("/ibm,opal/sensors");
0568 for_each_child_of_node(opal, np) {
0569 struct sensor_group_data *sgrp_data;
0570 const char *attr_name;
0571 u32 opal_index, hw_id;
0572 u32 sensor_id;
0573 const char *label;
0574 enum sensors type;
0575
0576 type = get_sensor_type(np);
0577 if (type == MAX_SENSOR_TYPE)
0578 continue;
0579
0580
0581
0582
0583
0584 if (of_property_read_u32(np, "sensor-id", &sensor_id) &&
0585 of_property_read_u32(np, "sensor-data", &sensor_id)) {
0586 dev_info(&pdev->dev,
0587 "'sensor-id' missing in the node '%pOFn'\n",
0588 np);
0589 continue;
0590 }
0591
0592 sdata[count].id = sensor_id;
0593 sdata[count].type = type;
0594
0595
0596
0597
0598
0599
0600
0601 attr_name = parse_opal_node_name(np->name, type, &opal_index);
0602 if (IS_ERR(attr_name)) {
0603 attr_name = "input";
0604 opal_index = INVALID_INDEX;
0605 }
0606
0607 hw_id = get_sensor_hwmon_index(&sdata[count], sdata, count);
0608 sgrp_data = get_sensor_group(pdata, np, type);
0609 populate_sensor(&sdata[count], opal_index, hw_id, sensor_id,
0610 attr_name, type, pgroups[type], sgrp_data,
0611 show_sensor, NULL);
0612 count++;
0613
0614 if (!of_property_read_string(np, "label", &label)) {
0615
0616
0617
0618
0619
0620
0621
0622 make_sensor_label(np, &sdata[count], label);
0623 populate_sensor(&sdata[count], opal_index, hw_id,
0624 sensor_id, "label", type, pgroups[type],
0625 NULL, show_label, NULL);
0626 count++;
0627 }
0628
0629 if (!of_property_read_u32(np, "sensor-data-max", &sensor_id)) {
0630 attr_name = get_max_attr(type);
0631 populate_sensor(&sdata[count], opal_index, hw_id,
0632 sensor_id, attr_name, type,
0633 pgroups[type], sgrp_data, show_sensor,
0634 NULL);
0635 count++;
0636 }
0637
0638 if (!of_property_read_u32(np, "sensor-data-min", &sensor_id)) {
0639 attr_name = get_min_attr(type);
0640 populate_sensor(&sdata[count], opal_index, hw_id,
0641 sensor_id, attr_name, type,
0642 pgroups[type], sgrp_data, show_sensor,
0643 NULL);
0644 count++;
0645 }
0646
0647 if (sgrp_data && !sgrp_data->enable) {
0648 sgrp_data->enable = true;
0649 hw_id = ++group_attr_id[type];
0650 populate_sensor(&sdata[count], opal_index, hw_id,
0651 sgrp_data->gid, "enable", type,
0652 pgroups[type], sgrp_data, show_enable,
0653 store_enable);
0654 count++;
0655 }
0656 }
0657
0658 of_node_put(opal);
0659 return 0;
0660 }
0661
0662 static int ibmpowernv_probe(struct platform_device *pdev)
0663 {
0664 struct platform_data *pdata;
0665 struct device *hwmon_dev;
0666 int err;
0667
0668 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
0669 if (!pdata)
0670 return -ENOMEM;
0671
0672 platform_set_drvdata(pdev, pdata);
0673 pdata->sensors_count = 0;
0674 pdata->nr_sensor_groups = 0;
0675 err = populate_attr_groups(pdev);
0676 if (err)
0677 return err;
0678
0679
0680 err = create_device_attrs(pdev);
0681 if (err)
0682 return err;
0683
0684
0685 hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, DRVNAME,
0686 pdata,
0687 pdata->attr_groups);
0688
0689 return PTR_ERR_OR_ZERO(hwmon_dev);
0690 }
0691
0692 static const struct platform_device_id opal_sensor_driver_ids[] = {
0693 {
0694 .name = "opal-sensor",
0695 },
0696 { }
0697 };
0698 MODULE_DEVICE_TABLE(platform, opal_sensor_driver_ids);
0699
0700 static const struct of_device_id opal_sensor_match[] = {
0701 { .compatible = "ibm,opal-sensor" },
0702 { },
0703 };
0704 MODULE_DEVICE_TABLE(of, opal_sensor_match);
0705
0706 static struct platform_driver ibmpowernv_driver = {
0707 .probe = ibmpowernv_probe,
0708 .id_table = opal_sensor_driver_ids,
0709 .driver = {
0710 .name = DRVNAME,
0711 .of_match_table = opal_sensor_match,
0712 },
0713 };
0714
0715 module_platform_driver(ibmpowernv_driver);
0716
0717 MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>");
0718 MODULE_DESCRIPTION("IBM POWERNV platform sensors");
0719 MODULE_LICENSE("GPL");