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