common.h (3068B)
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 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 notify 118 * 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 */