2019-01-28 10:23:23 -06:00
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright IBM Corp 2019 */
2018-11-08 15:05:24 -06:00
# ifndef OCC_COMMON_H
# define OCC_COMMON_H
2018-11-08 15:05:28 -06:00
# include <linux/hwmon-sysfs.h>
2018-11-08 15:05:27 -06:00
# include <linux/mutex.h>
2018-11-08 15:05:28 -06:00
# include <linux/sysfs.h>
2018-11-08 15:05:27 -06:00
2018-11-08 15:05:24 -06:00
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 ;
2018-11-08 15:05:26 -06:00
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 ;
} ;
2018-11-08 15:05:28 -06:00
/*
* 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 ;
} ;
2018-11-08 15:05:24 -06:00
struct occ {
struct device * bus_dev ;
struct occ_response resp ;
2018-11-08 15:05:26 -06:00
struct occ_sensors sensors ;
2018-11-08 15:05:24 -06:00
2018-11-08 15:05:27 -06:00
int powr_sample_time_us ; /* average power sample time */
2018-11-08 15:05:24 -06:00
u8 poll_cmd_data ; /* to perform OCC poll command */
2022-06-28 15:30:29 -05:00
int ( * send_cmd ) ( struct occ * occ , u8 * cmd , size_t len , void * resp ,
size_t resp_len ) ;
2018-11-08 15:05:27 -06:00
2021-04-29 10:13:36 -05:00
unsigned long next_update ;
2018-11-08 15:05:27 -06:00
struct mutex lock ; /* lock OCC access */
2018-11-08 15:05:28 -06:00
struct device * hwmon ;
struct occ_attribute * attrs ;
struct attribute_group group ;
const struct attribute_group * groups [ 2 ] ;
2018-11-08 15:05:29 -06:00
2022-04-27 09:04:43 -05:00
bool active ;
2019-04-16 15:43:48 +00:00
int error ; /* final transfer error after retry */
int last_error ; /* latest transfer error */
2018-11-08 15:05:29 -06:00
unsigned int error_count ; /* number of xfr errors observed */
unsigned long last_safe ; /* time OCC entered "safe" state */
/*
* Store the previous state data for comparison in order to notify
* sysfs readers of state changes .
*/
int prev_error ;
u8 prev_stat ;
u8 prev_ext_stat ;
u8 prev_occs_present ;
2022-02-15 09:10:19 -06:00
u8 prev_ips_status ;
2022-02-15 09:10:20 -06:00
u8 prev_mode ;
2018-11-08 15:05:24 -06:00
} ;
2022-04-27 09:04:43 -05:00
int occ_active ( struct occ * occ , bool active ) ;
int occ_setup ( struct occ * occ ) ;
2018-11-08 15:05:29 -06:00
int occ_setup_sysfs ( struct occ * occ ) ;
void occ_shutdown ( struct occ * occ ) ;
2022-04-27 09:04:43 -05:00
void occ_shutdown_sysfs ( struct occ * occ ) ;
2018-11-08 15:05:29 -06:00
void occ_sysfs_poll_done ( struct occ * occ ) ;
int occ_update_response ( struct occ * occ ) ;
2018-11-08 15:05:24 -06:00
# endif /* OCC_COMMON_H */