linux/drivers/hwmon/occ/common.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/* Copyright IBM Corp 2019 */
   3
   4#ifndef OCC_COMMON_H
   5#define OCC_COMMON_H
   6
   7#include <linux/hwmon-sysfs.h>
   8#include <linux/mutex.h>
   9#include <linux/sysfs.h>
  10
  11struct device;
  12
  13#define OCC_RESP_DATA_BYTES             4089
  14
  15/*
  16 * Same response format for all OCC versions.
  17 * Allocate the largest possible response.
  18 */
  19struct occ_response {
  20        u8 seq_no;
  21        u8 cmd_type;
  22        u8 return_status;
  23        __be16 data_length;
  24        u8 data[OCC_RESP_DATA_BYTES];
  25        __be16 checksum;
  26} __packed;
  27
  28struct occ_sensor_data_block_header {
  29        u8 eye_catcher[4];
  30        u8 reserved;
  31        u8 sensor_format;
  32        u8 sensor_length;
  33        u8 num_sensors;
  34} __packed;
  35
  36struct occ_sensor_data_block {
  37        struct occ_sensor_data_block_header header;
  38        u32 data;
  39} __packed;
  40
  41struct occ_poll_response_header {
  42        u8 status;
  43        u8 ext_status;
  44        u8 occs_present;
  45        u8 config_data;
  46        u8 occ_state;
  47        u8 mode;
  48        u8 ips_status;
  49        u8 error_log_id;
  50        __be32 error_log_start_address;
  51        __be16 error_log_length;
  52        u16 reserved;
  53        u8 occ_code_level[16];
  54        u8 eye_catcher[6];
  55        u8 num_sensor_data_blocks;
  56        u8 sensor_data_block_header_version;
  57} __packed;
  58
  59struct occ_poll_response {
  60        struct occ_poll_response_header header;
  61        struct occ_sensor_data_block block;
  62} __packed;
  63
  64struct occ_sensor {
  65        u8 num_sensors;
  66        u8 version;
  67        void *data;     /* pointer to sensor data start within response */
  68};
  69
  70/*
  71 * OCC only provides one sensor data block of each type, but any number of
  72 * sensors within that block.
  73 */
  74struct occ_sensors {
  75        struct occ_sensor temp;
  76        struct occ_sensor freq;
  77        struct occ_sensor power;
  78        struct occ_sensor caps;
  79        struct occ_sensor extended;
  80};
  81
  82/*
  83 * Use our own attribute struct so we can dynamically allocate space for the
  84 * name.
  85 */
  86struct occ_attribute {
  87        char name[32];
  88        struct sensor_device_attribute_2 sensor;
  89};
  90
  91struct occ {
  92        struct device *bus_dev;
  93
  94        struct occ_response resp;
  95        struct occ_sensors sensors;
  96
  97        int powr_sample_time_us;        /* average power sample time */
  98        u8 seq_no;
  99        u8 poll_cmd_data;               /* to perform OCC poll command */
 100        int (*send_cmd)(struct occ *occ, u8 *cmd);
 101
 102        unsigned long next_update;
 103        struct mutex lock;              /* lock OCC access */
 104
 105        struct device *hwmon;
 106        struct occ_attribute *attrs;
 107        struct attribute_group group;
 108        const struct attribute_group *groups[2];
 109
 110        int error;                      /* final transfer error after retry */
 111        int last_error;                 /* latest transfer error */
 112        unsigned int error_count;       /* number of xfr errors observed */
 113        unsigned long last_safe;        /* time OCC entered "safe" state */
 114
 115        /*
 116         * Store the previous state data for comparison in order to notify
 117         * sysfs readers of state changes.
 118         */
 119        int prev_error;
 120        u8 prev_stat;
 121        u8 prev_ext_stat;
 122        u8 prev_occs_present;
 123};
 124
 125int occ_setup(struct occ *occ, const char *name);
 126int occ_setup_sysfs(struct occ *occ);
 127void occ_shutdown(struct occ *occ);
 128void occ_sysfs_poll_done(struct occ *occ);
 129int occ_update_response(struct occ *occ);
 130
 131#endif /* OCC_COMMON_H */
 132