/* * Copyright 2017 IBM Corp. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #ifndef OCC_COMMON_H #define OCC_COMMON_H #include #include #include struct device; #define OCC_RESP_DATA_BYTES 4089 /* Same response format for all OCC versions. * Allocate the largest possible response. */ struct occ_response { u8 seq_no; u8 cmd_type; u8 return_status; __be16 data_length; u8 data[OCC_RESP_DATA_BYTES]; __be16 checksum; } __packed; struct occ_sensor_data_block_header { u8 eye_catcher[4]; u8 reserved; u8 sensor_format; u8 sensor_length; u8 num_sensors; } __packed; struct occ_sensor_data_block { struct occ_sensor_data_block_header header; u32 data; } __packed; struct occ_poll_response_header { u8 status; u8 ext_status; u8 occs_present; u8 config_data; u8 occ_state; u8 mode; u8 ips_status; u8 error_log_id; __be32 error_log_start_address; __be16 error_log_length; u16 reserved; u8 occ_code_level[16]; u8 eye_catcher[6]; u8 num_sensor_data_blocks; u8 sensor_data_block_header_version; } __packed; struct occ_poll_response { struct occ_poll_response_header header; struct occ_sensor_data_block block; } __packed; struct occ_sensor { u8 num_sensors; u8 version; void *data; /* pointer to sensor data start within response */ }; /* OCC only provides one sensor data block of each type, but any number of * sensors within that block. */ struct occ_sensors { struct occ_sensor temp; struct occ_sensor freq; struct occ_sensor power; struct occ_sensor caps; struct occ_sensor extended; }; /* Use our own attribute struct so we can dynamically allocate space for the * name. */ struct occ_attribute { char name[32]; struct sensor_device_attribute_2 sensor; }; struct occ { struct device *bus_dev; struct occ_response resp; struct occ_sensors sensors; u8 poll_cmd_data; /* to perform OCC poll command */ int (*send_cmd)(struct occ *occ, u8 *cmd); unsigned long last_update; struct mutex lock; /* lock OCC access */ struct device *hwmon; struct occ_attribute *attrs; struct attribute_group group; const struct attribute_group *groups[2]; int error; unsigned int error_count; /* number of errors observed */ unsigned long last_safe; /* time OCC entered safe state */ /* store previous poll state to compare; notify sysfs on change */ int previous_error; u8 previous_ext_status; u8 previous_occs_present; }; int occ_setup(struct occ *occ, const char *name); void occ_shutdown(struct occ *occ); #endif /* OCC_COMMON_H */