xref: /openbmc/linux/drivers/hwmon/occ/common.h (revision e7bae9bb)
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 
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 
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 
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 
91 struct 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 last_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 
125 int occ_setup(struct occ *occ, const char *name);
126 int occ_setup_sysfs(struct occ *occ);
127 void occ_shutdown(struct occ *occ);
128 void occ_sysfs_poll_done(struct occ *occ);
129 int occ_update_response(struct occ *occ);
130 
131 #endif /* OCC_COMMON_H */
132