Commit | Line | Data |
---|---|---|
e2f05d60 EJ |
1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | /* Copyright IBM Corp 2019 */ | |
5b5513b8 EJ |
3 | |
4 | #ifndef OCC_COMMON_H | |
5 | #define OCC_COMMON_H | |
6 | ||
54076cb3 | 7 | #include <linux/hwmon-sysfs.h> |
c10e753d | 8 | #include <linux/mutex.h> |
54076cb3 | 9 | #include <linux/sysfs.h> |
c10e753d | 10 | |
5b5513b8 EJ |
11 | struct 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 | */ | |
19 | struct 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 | ||
aa195fe4 EJ |
28 | struct 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 | ||
36 | struct occ_sensor_data_block { | |
37 | struct occ_sensor_data_block_header header; | |
38 | u32 data; | |
39 | } __packed; | |
40 | ||
41 | struct 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 | ||
59 | struct occ_poll_response { | |
60 | struct occ_poll_response_header header; | |
61 | struct occ_sensor_data_block block; | |
62 | } __packed; | |
63 | ||
64 | struct 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 | */ | |
74 | struct 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 | ||
54076cb3 EJ |
82 | /* |
83 | * Use our own attribute struct so we can dynamically allocate space for the | |
84 | * name. | |
85 | */ | |
86 | struct occ_attribute { | |
87 | char name[32]; | |
88 | struct sensor_device_attribute_2 sensor; | |
89 | }; | |
90 | ||
5b5513b8 EJ |
91 | struct occ { |
92 | struct device *bus_dev; | |
93 | ||
94 | struct occ_response resp; | |
aa195fe4 | 95 | struct occ_sensors sensors; |
5b5513b8 | 96 | |
c10e753d | 97 | int powr_sample_time_us; /* average power sample time */ |
5b5513b8 | 98 | u8 poll_cmd_data; /* to perform OCC poll command */ |
1bbb2809 EJ |
99 | int (*send_cmd)(struct occ *occ, u8 *cmd, size_t len, void *resp, |
100 | size_t resp_len); | |
c10e753d | 101 | |
5216dff2 | 102 | unsigned long next_update; |
c10e753d | 103 | struct mutex lock; /* lock OCC access */ |
54076cb3 EJ |
104 | |
105 | struct device *hwmon; | |
106 | struct occ_attribute *attrs; | |
107 | struct attribute_group group; | |
108 | const struct attribute_group *groups[2]; | |
df04ced6 | 109 | |
849b0156 | 110 | bool active; |
b5c46a53 EJ |
111 | int error; /* final transfer error after retry */ |
112 | int last_error; /* latest transfer error */ | |
df04ced6 EJ |
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; | |
6109c3e1 | 124 | u8 prev_ips_status; |
a25126fc | 125 | u8 prev_mode; |
5b5513b8 EJ |
126 | }; |
127 | ||
849b0156 EJ |
128 | int occ_active(struct occ *occ, bool active); |
129 | int occ_setup(struct occ *occ); | |
df04ced6 EJ |
130 | int occ_setup_sysfs(struct occ *occ); |
131 | void occ_shutdown(struct occ *occ); | |
849b0156 | 132 | void occ_shutdown_sysfs(struct occ *occ); |
df04ced6 EJ |
133 | void occ_sysfs_poll_done(struct occ *occ); |
134 | int occ_update_response(struct occ *occ); | |
5b5513b8 EJ |
135 | |
136 | #endif /* OCC_COMMON_H */ |