1252 lines · c
1// SPDX-License-Identifier: GPL-2.0+2// Copyright IBM Corp 20193 4#include <linux/device.h>5#include <linux/export.h>6#include <linux/hwmon.h>7#include <linux/hwmon-sysfs.h>8#include <linux/jiffies.h>9#include <linux/kernel.h>10#include <linux/math64.h>11#include <linux/module.h>12#include <linux/mutex.h>13#include <linux/property.h>14#include <linux/sysfs.h>15#include <linux/unaligned.h>16 17#include "common.h"18 19#define EXTN_FLAG_SENSOR_ID BIT(7)20 21#define OCC_ERROR_COUNT_THRESHOLD 2 /* required by OCC spec */22 23#define OCC_STATE_SAFE 424#define OCC_SAFE_TIMEOUT msecs_to_jiffies(60000) /* 1 min */25 26#define OCC_UPDATE_FREQUENCY msecs_to_jiffies(1000)27 28#define OCC_TEMP_SENSOR_FAULT 0xFF29 30#define OCC_FRU_TYPE_VRM 331 32/* OCC sensor type and version definitions */33 34struct temp_sensor_1 {35 u16 sensor_id;36 u16 value;37} __packed;38 39struct temp_sensor_2 {40 u32 sensor_id;41 u8 fru_type;42 u8 value;43} __packed;44 45struct temp_sensor_10 {46 u32 sensor_id;47 u8 fru_type;48 u8 value;49 u8 throttle;50 u8 reserved;51} __packed;52 53struct freq_sensor_1 {54 u16 sensor_id;55 u16 value;56} __packed;57 58struct freq_sensor_2 {59 u32 sensor_id;60 u16 value;61} __packed;62 63struct power_sensor_1 {64 u16 sensor_id;65 u32 update_tag;66 u32 accumulator;67 u16 value;68} __packed;69 70struct power_sensor_2 {71 u32 sensor_id;72 u8 function_id;73 u8 apss_channel;74 u16 reserved;75 u32 update_tag;76 u64 accumulator;77 u16 value;78} __packed;79 80struct power_sensor_data {81 u16 value;82 u32 update_tag;83 u64 accumulator;84} __packed;85 86struct power_sensor_data_and_time {87 u16 update_time;88 u16 value;89 u32 update_tag;90 u64 accumulator;91} __packed;92 93struct power_sensor_a0 {94 u32 sensor_id;95 struct power_sensor_data_and_time system;96 u32 reserved;97 struct power_sensor_data_and_time proc;98 struct power_sensor_data vdd;99 struct power_sensor_data vdn;100} __packed;101 102struct caps_sensor_2 {103 u16 cap;104 u16 system_power;105 u16 n_cap;106 u16 max;107 u16 min;108 u16 user;109 u8 user_source;110} __packed;111 112struct caps_sensor_3 {113 u16 cap;114 u16 system_power;115 u16 n_cap;116 u16 max;117 u16 hard_min;118 u16 soft_min;119 u16 user;120 u8 user_source;121} __packed;122 123struct extended_sensor {124 union {125 u8 name[4];126 u32 sensor_id;127 };128 u8 flags;129 u8 reserved;130 u8 data[6];131} __packed;132 133static int occ_poll(struct occ *occ)134{135 int rc;136 u8 cmd[7];137 struct occ_poll_response_header *header;138 139 /* big endian */140 cmd[0] = 0; /* sequence number */141 cmd[1] = 0; /* cmd type */142 cmd[2] = 0; /* data length msb */143 cmd[3] = 1; /* data length lsb */144 cmd[4] = occ->poll_cmd_data; /* data */145 cmd[5] = 0; /* checksum msb */146 cmd[6] = 0; /* checksum lsb */147 148 /* mutex should already be locked if necessary */149 rc = occ->send_cmd(occ, cmd, sizeof(cmd), &occ->resp, sizeof(occ->resp));150 if (rc) {151 occ->last_error = rc;152 if (occ->error_count++ > OCC_ERROR_COUNT_THRESHOLD)153 occ->error = rc;154 155 goto done;156 }157 158 /* clear error since communication was successful */159 occ->error_count = 0;160 occ->last_error = 0;161 occ->error = 0;162 163 /* check for safe state */164 header = (struct occ_poll_response_header *)occ->resp.data;165 if (header->occ_state == OCC_STATE_SAFE) {166 if (occ->last_safe) {167 if (time_after(jiffies,168 occ->last_safe + OCC_SAFE_TIMEOUT))169 occ->error = -EHOSTDOWN;170 } else {171 occ->last_safe = jiffies;172 }173 } else {174 occ->last_safe = 0;175 }176 177done:178 occ_sysfs_poll_done(occ);179 return rc;180}181 182static int occ_set_user_power_cap(struct occ *occ, u16 user_power_cap)183{184 int rc;185 u8 cmd[8];186 u8 resp[8];187 __be16 user_power_cap_be = cpu_to_be16(user_power_cap);188 189 cmd[0] = 0; /* sequence number */190 cmd[1] = 0x22; /* cmd type */191 cmd[2] = 0; /* data length msb */192 cmd[3] = 2; /* data length lsb */193 194 memcpy(&cmd[4], &user_power_cap_be, 2);195 196 cmd[6] = 0; /* checksum msb */197 cmd[7] = 0; /* checksum lsb */198 199 rc = mutex_lock_interruptible(&occ->lock);200 if (rc)201 return rc;202 203 rc = occ->send_cmd(occ, cmd, sizeof(cmd), resp, sizeof(resp));204 205 mutex_unlock(&occ->lock);206 207 return rc;208}209 210int occ_update_response(struct occ *occ)211{212 int rc = mutex_lock_interruptible(&occ->lock);213 214 if (rc)215 return rc;216 217 /* limit the maximum rate of polling the OCC */218 if (time_after(jiffies, occ->next_update)) {219 rc = occ_poll(occ);220 occ->next_update = jiffies + OCC_UPDATE_FREQUENCY;221 } else {222 rc = occ->last_error;223 }224 225 mutex_unlock(&occ->lock);226 return rc;227}228 229static ssize_t occ_show_temp_1(struct device *dev,230 struct device_attribute *attr, char *buf)231{232 int rc;233 u32 val = 0;234 struct temp_sensor_1 *temp;235 struct occ *occ = dev_get_drvdata(dev);236 struct occ_sensors *sensors = &occ->sensors;237 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);238 239 rc = occ_update_response(occ);240 if (rc)241 return rc;242 243 temp = ((struct temp_sensor_1 *)sensors->temp.data) + sattr->index;244 245 switch (sattr->nr) {246 case 0:247 val = get_unaligned_be16(&temp->sensor_id);248 break;249 case 1:250 /*251 * If a sensor reading has expired and couldn't be refreshed,252 * OCC returns 0xFFFF for that sensor.253 */254 if (temp->value == 0xFFFF)255 return -EREMOTEIO;256 val = get_unaligned_be16(&temp->value) * 1000;257 break;258 default:259 return -EINVAL;260 }261 262 return sysfs_emit(buf, "%u\n", val);263}264 265static ssize_t occ_show_temp_2(struct device *dev,266 struct device_attribute *attr, char *buf)267{268 int rc;269 u32 val = 0;270 struct temp_sensor_2 *temp;271 struct occ *occ = dev_get_drvdata(dev);272 struct occ_sensors *sensors = &occ->sensors;273 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);274 275 rc = occ_update_response(occ);276 if (rc)277 return rc;278 279 temp = ((struct temp_sensor_2 *)sensors->temp.data) + sattr->index;280 281 switch (sattr->nr) {282 case 0:283 val = get_unaligned_be32(&temp->sensor_id);284 break;285 case 1:286 val = temp->value;287 if (val == OCC_TEMP_SENSOR_FAULT)288 return -EREMOTEIO;289 290 /*291 * VRM doesn't return temperature, only alarm bit. This292 * attribute maps to tempX_alarm instead of tempX_input for293 * VRM294 */295 if (temp->fru_type != OCC_FRU_TYPE_VRM) {296 /* sensor not ready */297 if (val == 0)298 return -EAGAIN;299 300 val *= 1000;301 }302 break;303 case 2:304 val = temp->fru_type;305 break;306 case 3:307 val = temp->value == OCC_TEMP_SENSOR_FAULT;308 break;309 default:310 return -EINVAL;311 }312 313 return sysfs_emit(buf, "%u\n", val);314}315 316static ssize_t occ_show_temp_10(struct device *dev,317 struct device_attribute *attr, char *buf)318{319 int rc;320 u32 val = 0;321 struct temp_sensor_10 *temp;322 struct occ *occ = dev_get_drvdata(dev);323 struct occ_sensors *sensors = &occ->sensors;324 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);325 326 rc = occ_update_response(occ);327 if (rc)328 return rc;329 330 temp = ((struct temp_sensor_10 *)sensors->temp.data) + sattr->index;331 332 switch (sattr->nr) {333 case 0:334 val = get_unaligned_be32(&temp->sensor_id);335 break;336 case 1:337 val = temp->value;338 if (val == OCC_TEMP_SENSOR_FAULT)339 return -EREMOTEIO;340 341 /* sensor not ready */342 if (val == 0)343 return -EAGAIN;344 345 val *= 1000;346 break;347 case 2:348 val = temp->fru_type;349 break;350 case 3:351 val = temp->value == OCC_TEMP_SENSOR_FAULT;352 break;353 case 4:354 val = temp->throttle * 1000;355 break;356 default:357 return -EINVAL;358 }359 360 return sysfs_emit(buf, "%u\n", val);361}362 363static ssize_t occ_show_freq_1(struct device *dev,364 struct device_attribute *attr, char *buf)365{366 int rc;367 u16 val = 0;368 struct freq_sensor_1 *freq;369 struct occ *occ = dev_get_drvdata(dev);370 struct occ_sensors *sensors = &occ->sensors;371 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);372 373 rc = occ_update_response(occ);374 if (rc)375 return rc;376 377 freq = ((struct freq_sensor_1 *)sensors->freq.data) + sattr->index;378 379 switch (sattr->nr) {380 case 0:381 val = get_unaligned_be16(&freq->sensor_id);382 break;383 case 1:384 val = get_unaligned_be16(&freq->value);385 break;386 default:387 return -EINVAL;388 }389 390 return sysfs_emit(buf, "%u\n", val);391}392 393static ssize_t occ_show_freq_2(struct device *dev,394 struct device_attribute *attr, char *buf)395{396 int rc;397 u32 val = 0;398 struct freq_sensor_2 *freq;399 struct occ *occ = dev_get_drvdata(dev);400 struct occ_sensors *sensors = &occ->sensors;401 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);402 403 rc = occ_update_response(occ);404 if (rc)405 return rc;406 407 freq = ((struct freq_sensor_2 *)sensors->freq.data) + sattr->index;408 409 switch (sattr->nr) {410 case 0:411 val = get_unaligned_be32(&freq->sensor_id);412 break;413 case 1:414 val = get_unaligned_be16(&freq->value);415 break;416 default:417 return -EINVAL;418 }419 420 return sysfs_emit(buf, "%u\n", val);421}422 423static ssize_t occ_show_power_1(struct device *dev,424 struct device_attribute *attr, char *buf)425{426 int rc;427 u64 val = 0;428 struct power_sensor_1 *power;429 struct occ *occ = dev_get_drvdata(dev);430 struct occ_sensors *sensors = &occ->sensors;431 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);432 433 rc = occ_update_response(occ);434 if (rc)435 return rc;436 437 power = ((struct power_sensor_1 *)sensors->power.data) + sattr->index;438 439 switch (sattr->nr) {440 case 0:441 val = get_unaligned_be16(&power->sensor_id);442 break;443 case 1:444 val = get_unaligned_be32(&power->accumulator) /445 get_unaligned_be32(&power->update_tag);446 val *= 1000000ULL;447 break;448 case 2:449 val = (u64)get_unaligned_be32(&power->update_tag) *450 occ->powr_sample_time_us;451 break;452 case 3:453 val = get_unaligned_be16(&power->value) * 1000000ULL;454 break;455 default:456 return -EINVAL;457 }458 459 return sysfs_emit(buf, "%llu\n", val);460}461 462static u64 occ_get_powr_avg(u64 *accum, u32 *samples)463{464 u64 divisor = get_unaligned_be32(samples);465 466 return (divisor == 0) ? 0 :467 div64_u64(get_unaligned_be64(accum) * 1000000ULL, divisor);468}469 470static ssize_t occ_show_power_2(struct device *dev,471 struct device_attribute *attr, char *buf)472{473 int rc;474 u64 val = 0;475 struct power_sensor_2 *power;476 struct occ *occ = dev_get_drvdata(dev);477 struct occ_sensors *sensors = &occ->sensors;478 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);479 480 rc = occ_update_response(occ);481 if (rc)482 return rc;483 484 power = ((struct power_sensor_2 *)sensors->power.data) + sattr->index;485 486 switch (sattr->nr) {487 case 0:488 return sysfs_emit(buf, "%u_%u_%u\n",489 get_unaligned_be32(&power->sensor_id),490 power->function_id, power->apss_channel);491 case 1:492 val = occ_get_powr_avg(&power->accumulator,493 &power->update_tag);494 break;495 case 2:496 val = (u64)get_unaligned_be32(&power->update_tag) *497 occ->powr_sample_time_us;498 break;499 case 3:500 val = get_unaligned_be16(&power->value) * 1000000ULL;501 break;502 default:503 return -EINVAL;504 }505 506 return sysfs_emit(buf, "%llu\n", val);507}508 509static ssize_t occ_show_power_a0(struct device *dev,510 struct device_attribute *attr, char *buf)511{512 int rc;513 u64 val = 0;514 struct power_sensor_a0 *power;515 struct occ *occ = dev_get_drvdata(dev);516 struct occ_sensors *sensors = &occ->sensors;517 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);518 519 rc = occ_update_response(occ);520 if (rc)521 return rc;522 523 power = ((struct power_sensor_a0 *)sensors->power.data) + sattr->index;524 525 switch (sattr->nr) {526 case 0:527 return sysfs_emit(buf, "%u_system\n",528 get_unaligned_be32(&power->sensor_id));529 case 1:530 val = occ_get_powr_avg(&power->system.accumulator,531 &power->system.update_tag);532 break;533 case 2:534 val = (u64)get_unaligned_be32(&power->system.update_tag) *535 occ->powr_sample_time_us;536 break;537 case 3:538 val = get_unaligned_be16(&power->system.value) * 1000000ULL;539 break;540 case 4:541 return sysfs_emit(buf, "%u_proc\n",542 get_unaligned_be32(&power->sensor_id));543 case 5:544 val = occ_get_powr_avg(&power->proc.accumulator,545 &power->proc.update_tag);546 break;547 case 6:548 val = (u64)get_unaligned_be32(&power->proc.update_tag) *549 occ->powr_sample_time_us;550 break;551 case 7:552 val = get_unaligned_be16(&power->proc.value) * 1000000ULL;553 break;554 case 8:555 return sysfs_emit(buf, "%u_vdd\n",556 get_unaligned_be32(&power->sensor_id));557 case 9:558 val = occ_get_powr_avg(&power->vdd.accumulator,559 &power->vdd.update_tag);560 break;561 case 10:562 val = (u64)get_unaligned_be32(&power->vdd.update_tag) *563 occ->powr_sample_time_us;564 break;565 case 11:566 val = get_unaligned_be16(&power->vdd.value) * 1000000ULL;567 break;568 case 12:569 return sysfs_emit(buf, "%u_vdn\n",570 get_unaligned_be32(&power->sensor_id));571 case 13:572 val = occ_get_powr_avg(&power->vdn.accumulator,573 &power->vdn.update_tag);574 break;575 case 14:576 val = (u64)get_unaligned_be32(&power->vdn.update_tag) *577 occ->powr_sample_time_us;578 break;579 case 15:580 val = get_unaligned_be16(&power->vdn.value) * 1000000ULL;581 break;582 default:583 return -EINVAL;584 }585 586 return sysfs_emit(buf, "%llu\n", val);587}588 589static ssize_t occ_show_caps_1_2(struct device *dev,590 struct device_attribute *attr, char *buf)591{592 int rc;593 u64 val = 0;594 struct caps_sensor_2 *caps;595 struct occ *occ = dev_get_drvdata(dev);596 struct occ_sensors *sensors = &occ->sensors;597 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);598 599 rc = occ_update_response(occ);600 if (rc)601 return rc;602 603 caps = ((struct caps_sensor_2 *)sensors->caps.data) + sattr->index;604 605 switch (sattr->nr) {606 case 0:607 return sysfs_emit(buf, "system\n");608 case 1:609 val = get_unaligned_be16(&caps->cap) * 1000000ULL;610 break;611 case 2:612 val = get_unaligned_be16(&caps->system_power) * 1000000ULL;613 break;614 case 3:615 val = get_unaligned_be16(&caps->n_cap) * 1000000ULL;616 break;617 case 4:618 val = get_unaligned_be16(&caps->max) * 1000000ULL;619 break;620 case 5:621 val = get_unaligned_be16(&caps->min) * 1000000ULL;622 break;623 case 6:624 val = get_unaligned_be16(&caps->user) * 1000000ULL;625 break;626 case 7:627 if (occ->sensors.caps.version == 1)628 return -EINVAL;629 630 val = caps->user_source;631 break;632 default:633 return -EINVAL;634 }635 636 return sysfs_emit(buf, "%llu\n", val);637}638 639static ssize_t occ_show_caps_3(struct device *dev,640 struct device_attribute *attr, char *buf)641{642 int rc;643 u64 val = 0;644 struct caps_sensor_3 *caps;645 struct occ *occ = dev_get_drvdata(dev);646 struct occ_sensors *sensors = &occ->sensors;647 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);648 649 rc = occ_update_response(occ);650 if (rc)651 return rc;652 653 caps = ((struct caps_sensor_3 *)sensors->caps.data) + sattr->index;654 655 switch (sattr->nr) {656 case 0:657 return sysfs_emit(buf, "system\n");658 case 1:659 val = get_unaligned_be16(&caps->cap) * 1000000ULL;660 break;661 case 2:662 val = get_unaligned_be16(&caps->system_power) * 1000000ULL;663 break;664 case 3:665 val = get_unaligned_be16(&caps->n_cap) * 1000000ULL;666 break;667 case 4:668 val = get_unaligned_be16(&caps->max) * 1000000ULL;669 break;670 case 5:671 val = get_unaligned_be16(&caps->hard_min) * 1000000ULL;672 break;673 case 6:674 val = get_unaligned_be16(&caps->user) * 1000000ULL;675 break;676 case 7:677 val = caps->user_source;678 break;679 case 8:680 val = get_unaligned_be16(&caps->soft_min) * 1000000ULL;681 break;682 default:683 return -EINVAL;684 }685 686 return sysfs_emit(buf, "%llu\n", val);687}688 689static ssize_t occ_store_caps_user(struct device *dev,690 struct device_attribute *attr,691 const char *buf, size_t count)692{693 int rc;694 u16 user_power_cap;695 unsigned long long value;696 struct occ *occ = dev_get_drvdata(dev);697 698 rc = kstrtoull(buf, 0, &value);699 if (rc)700 return rc;701 702 user_power_cap = div64_u64(value, 1000000ULL); /* microwatt to watt */703 704 rc = occ_set_user_power_cap(occ, user_power_cap);705 if (rc)706 return rc;707 708 return count;709}710 711static ssize_t occ_show_extended(struct device *dev,712 struct device_attribute *attr, char *buf)713{714 int rc;715 struct extended_sensor *extn;716 struct occ *occ = dev_get_drvdata(dev);717 struct occ_sensors *sensors = &occ->sensors;718 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);719 720 rc = occ_update_response(occ);721 if (rc)722 return rc;723 724 extn = ((struct extended_sensor *)sensors->extended.data) +725 sattr->index;726 727 switch (sattr->nr) {728 case 0:729 if (extn->flags & EXTN_FLAG_SENSOR_ID) {730 rc = sysfs_emit(buf, "%u",731 get_unaligned_be32(&extn->sensor_id));732 } else {733 rc = sysfs_emit(buf, "%4phN\n", extn->name);734 }735 break;736 case 1:737 rc = sysfs_emit(buf, "%02x\n", extn->flags);738 break;739 case 2:740 rc = sysfs_emit(buf, "%6phN\n", extn->data);741 break;742 default:743 return -EINVAL;744 }745 746 return rc;747}748 749/*750 * Some helper macros to make it easier to define an occ_attribute. Since these751 * are dynamically allocated, we shouldn't use the existing kernel macros which752 * stringify the name argument.753 */754#define ATTR_OCC(_name, _mode, _show, _store) { \755 .attr = { \756 .name = _name, \757 .mode = VERIFY_OCTAL_PERMISSIONS(_mode), \758 }, \759 .show = _show, \760 .store = _store, \761}762 763#define SENSOR_ATTR_OCC(_name, _mode, _show, _store, _nr, _index) { \764 .dev_attr = ATTR_OCC(_name, _mode, _show, _store), \765 .index = _index, \766 .nr = _nr, \767}768 769#define OCC_INIT_ATTR(_name, _mode, _show, _store, _nr, _index) \770 ((struct sensor_device_attribute_2) \771 SENSOR_ATTR_OCC(_name, _mode, _show, _store, _nr, _index))772 773/*774 * Allocate and instatiate sensor_device_attribute_2s. It's most efficient to775 * use our own instead of the built-in hwmon attribute types.776 */777static int occ_setup_sensor_attrs(struct occ *occ)778{779 unsigned int i, s, num_attrs = 0;780 struct device *dev = occ->bus_dev;781 struct occ_sensors *sensors = &occ->sensors;782 struct occ_attribute *attr;783 struct temp_sensor_2 *temp;784 ssize_t (*show_temp)(struct device *, struct device_attribute *,785 char *) = occ_show_temp_1;786 ssize_t (*show_freq)(struct device *, struct device_attribute *,787 char *) = occ_show_freq_1;788 ssize_t (*show_power)(struct device *, struct device_attribute *,789 char *) = occ_show_power_1;790 ssize_t (*show_caps)(struct device *, struct device_attribute *,791 char *) = occ_show_caps_1_2;792 793 switch (sensors->temp.version) {794 case 1:795 num_attrs += (sensors->temp.num_sensors * 2);796 break;797 case 2:798 num_attrs += (sensors->temp.num_sensors * 4);799 show_temp = occ_show_temp_2;800 break;801 case 0x10:802 num_attrs += (sensors->temp.num_sensors * 5);803 show_temp = occ_show_temp_10;804 break;805 default:806 sensors->temp.num_sensors = 0;807 }808 809 switch (sensors->freq.version) {810 case 2:811 show_freq = occ_show_freq_2;812 fallthrough;813 case 1:814 num_attrs += (sensors->freq.num_sensors * 2);815 break;816 default:817 sensors->freq.num_sensors = 0;818 }819 820 switch (sensors->power.version) {821 case 2:822 show_power = occ_show_power_2;823 fallthrough;824 case 1:825 num_attrs += (sensors->power.num_sensors * 4);826 break;827 case 0xA0:828 num_attrs += (sensors->power.num_sensors * 16);829 show_power = occ_show_power_a0;830 break;831 default:832 sensors->power.num_sensors = 0;833 }834 835 switch (sensors->caps.version) {836 case 1:837 num_attrs += (sensors->caps.num_sensors * 7);838 break;839 case 2:840 num_attrs += (sensors->caps.num_sensors * 8);841 break;842 case 3:843 show_caps = occ_show_caps_3;844 num_attrs += (sensors->caps.num_sensors * 9);845 break;846 default:847 sensors->caps.num_sensors = 0;848 }849 850 switch (sensors->extended.version) {851 case 1:852 num_attrs += (sensors->extended.num_sensors * 3);853 break;854 default:855 sensors->extended.num_sensors = 0;856 }857 858 occ->attrs = devm_kzalloc(dev, sizeof(*occ->attrs) * num_attrs,859 GFP_KERNEL);860 if (!occ->attrs)861 return -ENOMEM;862 863 /* null-terminated list */864 occ->group.attrs = devm_kzalloc(dev, sizeof(*occ->group.attrs) *865 num_attrs + 1, GFP_KERNEL);866 if (!occ->group.attrs)867 return -ENOMEM;868 869 attr = occ->attrs;870 871 for (i = 0; i < sensors->temp.num_sensors; ++i) {872 s = i + 1;873 temp = ((struct temp_sensor_2 *)sensors->temp.data) + i;874 875 snprintf(attr->name, sizeof(attr->name), "temp%d_label", s);876 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_temp, NULL,877 0, i);878 attr++;879 880 if (sensors->temp.version == 2 &&881 temp->fru_type == OCC_FRU_TYPE_VRM) {882 snprintf(attr->name, sizeof(attr->name),883 "temp%d_alarm", s);884 } else {885 snprintf(attr->name, sizeof(attr->name),886 "temp%d_input", s);887 }888 889 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_temp, NULL,890 1, i);891 attr++;892 893 if (sensors->temp.version > 1) {894 snprintf(attr->name, sizeof(attr->name),895 "temp%d_fru_type", s);896 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,897 show_temp, NULL, 2, i);898 attr++;899 900 snprintf(attr->name, sizeof(attr->name),901 "temp%d_fault", s);902 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,903 show_temp, NULL, 3, i);904 attr++;905 906 if (sensors->temp.version == 0x10) {907 snprintf(attr->name, sizeof(attr->name),908 "temp%d_max", s);909 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,910 show_temp, NULL,911 4, i);912 attr++;913 }914 }915 }916 917 for (i = 0; i < sensors->freq.num_sensors; ++i) {918 s = i + 1;919 920 snprintf(attr->name, sizeof(attr->name), "freq%d_label", s);921 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_freq, NULL,922 0, i);923 attr++;924 925 snprintf(attr->name, sizeof(attr->name), "freq%d_input", s);926 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_freq, NULL,927 1, i);928 attr++;929 }930 931 if (sensors->power.version == 0xA0) {932 /*933 * Special case for many-attribute power sensor. Split it into934 * a sensor number per power type, emulating several sensors.935 */936 for (i = 0; i < sensors->power.num_sensors; ++i) {937 unsigned int j;938 unsigned int nr = 0;939 940 s = (i * 4) + 1;941 942 for (j = 0; j < 4; ++j) {943 snprintf(attr->name, sizeof(attr->name),944 "power%d_label", s);945 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,946 show_power, NULL,947 nr++, i);948 attr++;949 950 snprintf(attr->name, sizeof(attr->name),951 "power%d_average", s);952 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,953 show_power, NULL,954 nr++, i);955 attr++;956 957 snprintf(attr->name, sizeof(attr->name),958 "power%d_average_interval", s);959 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,960 show_power, NULL,961 nr++, i);962 attr++;963 964 snprintf(attr->name, sizeof(attr->name),965 "power%d_input", s);966 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,967 show_power, NULL,968 nr++, i);969 attr++;970 971 s++;972 }973 }974 975 s = (sensors->power.num_sensors * 4) + 1;976 } else {977 for (i = 0; i < sensors->power.num_sensors; ++i) {978 s = i + 1;979 980 snprintf(attr->name, sizeof(attr->name),981 "power%d_label", s);982 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,983 show_power, NULL, 0, i);984 attr++;985 986 snprintf(attr->name, sizeof(attr->name),987 "power%d_average", s);988 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,989 show_power, NULL, 1, i);990 attr++;991 992 snprintf(attr->name, sizeof(attr->name),993 "power%d_average_interval", s);994 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,995 show_power, NULL, 2, i);996 attr++;997 998 snprintf(attr->name, sizeof(attr->name),999 "power%d_input", s);1000 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,1001 show_power, NULL, 3, i);1002 attr++;1003 }1004 1005 s = sensors->power.num_sensors + 1;1006 }1007 1008 if (sensors->caps.num_sensors >= 1) {1009 snprintf(attr->name, sizeof(attr->name), "power%d_label", s);1010 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,1011 0, 0);1012 attr++;1013 1014 snprintf(attr->name, sizeof(attr->name), "power%d_cap", s);1015 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,1016 1, 0);1017 attr++;1018 1019 snprintf(attr->name, sizeof(attr->name), "power%d_input", s);1020 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,1021 2, 0);1022 attr++;1023 1024 snprintf(attr->name, sizeof(attr->name),1025 "power%d_cap_not_redundant", s);1026 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,1027 3, 0);1028 attr++;1029 1030 snprintf(attr->name, sizeof(attr->name), "power%d_cap_max", s);1031 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,1032 4, 0);1033 attr++;1034 1035 snprintf(attr->name, sizeof(attr->name), "power%d_cap_min", s);1036 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,1037 5, 0);1038 attr++;1039 1040 snprintf(attr->name, sizeof(attr->name), "power%d_cap_user",1041 s);1042 attr->sensor = OCC_INIT_ATTR(attr->name, 0644, show_caps,1043 occ_store_caps_user, 6, 0);1044 attr++;1045 1046 if (sensors->caps.version > 1) {1047 snprintf(attr->name, sizeof(attr->name),1048 "power%d_cap_user_source", s);1049 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,1050 show_caps, NULL, 7, 0);1051 attr++;1052 1053 if (sensors->caps.version > 2) {1054 snprintf(attr->name, sizeof(attr->name),1055 "power%d_cap_min_soft", s);1056 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,1057 show_caps, NULL,1058 8, 0);1059 attr++;1060 }1061 }1062 }1063 1064 for (i = 0; i < sensors->extended.num_sensors; ++i) {1065 s = i + 1;1066 1067 snprintf(attr->name, sizeof(attr->name), "extn%d_label", s);1068 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,1069 occ_show_extended, NULL, 0, i);1070 attr++;1071 1072 snprintf(attr->name, sizeof(attr->name), "extn%d_flags", s);1073 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,1074 occ_show_extended, NULL, 1, i);1075 attr++;1076 1077 snprintf(attr->name, sizeof(attr->name), "extn%d_input", s);1078 attr->sensor = OCC_INIT_ATTR(attr->name, 0444,1079 occ_show_extended, NULL, 2, i);1080 attr++;1081 }1082 1083 /* put the sensors in the group */1084 for (i = 0; i < num_attrs; ++i) {1085 sysfs_attr_init(&occ->attrs[i].sensor.dev_attr.attr);1086 occ->group.attrs[i] = &occ->attrs[i].sensor.dev_attr.attr;1087 }1088 1089 return 0;1090}1091 1092/* only need to do this once at startup, as OCC won't change sensors on us */1093static void occ_parse_poll_response(struct occ *occ)1094{1095 unsigned int i, old_offset, offset = 0, size = 0;1096 struct occ_sensor *sensor;1097 struct occ_sensors *sensors = &occ->sensors;1098 struct occ_response *resp = &occ->resp;1099 struct occ_poll_response *poll =1100 (struct occ_poll_response *)&resp->data[0];1101 struct occ_poll_response_header *header = &poll->header;1102 struct occ_sensor_data_block *block = &poll->block;1103 1104 dev_info(occ->bus_dev, "OCC found, code level: %.16s\n",1105 header->occ_code_level);1106 1107 for (i = 0; i < header->num_sensor_data_blocks; ++i) {1108 block = (struct occ_sensor_data_block *)((u8 *)block + offset);1109 old_offset = offset;1110 offset = (block->header.num_sensors *1111 block->header.sensor_length) + sizeof(block->header);1112 size += offset;1113 1114 /* validate all the length/size fields */1115 if ((size + sizeof(*header)) >= OCC_RESP_DATA_BYTES) {1116 dev_warn(occ->bus_dev, "exceeded response buffer\n");1117 return;1118 }1119 1120 dev_dbg(occ->bus_dev, " %04x..%04x: %.4s (%d sensors)\n",1121 old_offset, offset - 1, block->header.eye_catcher,1122 block->header.num_sensors);1123 1124 /* match sensor block type */1125 if (strncmp(block->header.eye_catcher, "TEMP", 4) == 0)1126 sensor = &sensors->temp;1127 else if (strncmp(block->header.eye_catcher, "FREQ", 4) == 0)1128 sensor = &sensors->freq;1129 else if (strncmp(block->header.eye_catcher, "POWR", 4) == 0)1130 sensor = &sensors->power;1131 else if (strncmp(block->header.eye_catcher, "CAPS", 4) == 0)1132 sensor = &sensors->caps;1133 else if (strncmp(block->header.eye_catcher, "EXTN", 4) == 0)1134 sensor = &sensors->extended;1135 else {1136 dev_warn(occ->bus_dev, "sensor not supported %.4s\n",1137 block->header.eye_catcher);1138 continue;1139 }1140 1141 sensor->num_sensors = block->header.num_sensors;1142 sensor->version = block->header.sensor_format;1143 sensor->data = &block->data;1144 }1145 1146 dev_dbg(occ->bus_dev, "Max resp size: %u+%zd=%zd\n", size,1147 sizeof(*header), size + sizeof(*header));1148}1149 1150int occ_active(struct occ *occ, bool active)1151{1152 int rc = mutex_lock_interruptible(&occ->lock);1153 1154 if (rc)1155 return rc;1156 1157 if (active) {1158 if (occ->active) {1159 rc = -EALREADY;1160 goto unlock;1161 }1162 1163 occ->error_count = 0;1164 occ->last_safe = 0;1165 1166 rc = occ_poll(occ);1167 if (rc < 0) {1168 dev_err(occ->bus_dev,1169 "failed to get OCC poll response=%02x: %d\n",1170 occ->resp.return_status, rc);1171 goto unlock;1172 }1173 1174 occ->active = true;1175 occ->next_update = jiffies + OCC_UPDATE_FREQUENCY;1176 occ_parse_poll_response(occ);1177 1178 rc = occ_setup_sensor_attrs(occ);1179 if (rc) {1180 dev_err(occ->bus_dev,1181 "failed to setup sensor attrs: %d\n", rc);1182 goto unlock;1183 }1184 1185 occ->hwmon = hwmon_device_register_with_groups(occ->bus_dev,1186 "occ", occ,1187 occ->groups);1188 if (IS_ERR(occ->hwmon)) {1189 rc = PTR_ERR(occ->hwmon);1190 occ->hwmon = NULL;1191 dev_err(occ->bus_dev,1192 "failed to register hwmon device: %d\n", rc);1193 goto unlock;1194 }1195 } else {1196 if (!occ->active) {1197 rc = -EALREADY;1198 goto unlock;1199 }1200 1201 if (occ->hwmon)1202 hwmon_device_unregister(occ->hwmon);1203 occ->active = false;1204 occ->hwmon = NULL;1205 }1206 1207unlock:1208 mutex_unlock(&occ->lock);1209 return rc;1210}1211 1212int occ_setup(struct occ *occ)1213{1214 int rc;1215 1216 mutex_init(&occ->lock);1217 occ->groups[0] = &occ->group;1218 1219 rc = occ_setup_sysfs(occ);1220 if (rc) {1221 dev_err(occ->bus_dev, "failed to setup sysfs: %d\n", rc);1222 return rc;1223 }1224 1225 if (!device_property_read_bool(occ->bus_dev, "ibm,no-poll-on-init")) {1226 rc = occ_active(occ, true);1227 if (rc)1228 occ_shutdown_sysfs(occ);1229 }1230 1231 return rc;1232}1233EXPORT_SYMBOL_GPL(occ_setup);1234 1235void occ_shutdown(struct occ *occ)1236{1237 mutex_lock(&occ->lock);1238 1239 occ_shutdown_sysfs(occ);1240 1241 if (occ->hwmon)1242 hwmon_device_unregister(occ->hwmon);1243 occ->hwmon = NULL;1244 1245 mutex_unlock(&occ->lock);1246}1247EXPORT_SYMBOL_GPL(occ_shutdown);1248 1249MODULE_AUTHOR("Eddie James <eajames@linux.ibm.com>");1250MODULE_DESCRIPTION("Common OCC hwmon code");1251MODULE_LICENSE("GPL");1252