137 lines · c
1/* SPDX-License-Identifier: GPL-2.0+ */2/* Copyright IBM Corp 2019 */3 4#ifndef OCC_COMMON_H5#define OCC_COMMON_H6 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 408914 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 of72 * 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 the84 * 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 poll_cmd_data; /* to perform OCC poll command */99 int (*send_cmd)(struct occ *occ, u8 *cmd, size_t len, void *resp,100 size_t resp_len);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 bool active;111 int error; /* final transfer error after retry */112 int last_error; /* latest transfer error */113 unsigned int error_count; /* number of xfr errors observed */114 unsigned long last_safe; /* time OCC entered "safe" state */115 116 /*117 * Store the previous state data for comparison in order to notify118 * sysfs readers of state changes.119 */120 int prev_error;121 u8 prev_stat;122 u8 prev_ext_stat;123 u8 prev_occs_present;124 u8 prev_ips_status;125 u8 prev_mode;126};127 128int occ_active(struct occ *occ, bool active);129int occ_setup(struct occ *occ);130int occ_setup_sysfs(struct occ *occ);131void occ_shutdown(struct occ *occ);132void occ_shutdown_sysfs(struct occ *occ);133void occ_sysfs_poll_done(struct occ *occ);134int occ_update_response(struct occ *occ);135 136#endif /* OCC_COMMON_H */137