cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sensors.c (30646B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * System Control and Management Interface (SCMI) Sensor Protocol
      4 *
      5 * Copyright (C) 2018-2022 ARM Ltd.
      6 */
      7
      8#define pr_fmt(fmt) "SCMI Notifications SENSOR - " fmt
      9
     10#include <linux/bitfield.h>
     11#include <linux/module.h>
     12#include <linux/scmi_protocol.h>
     13
     14#include "protocols.h"
     15#include "notify.h"
     16
     17#define SCMI_MAX_NUM_SENSOR_AXIS	63
     18#define	SCMIv2_SENSOR_PROTOCOL		0x10000
     19
     20enum scmi_sensor_protocol_cmd {
     21	SENSOR_DESCRIPTION_GET = 0x3,
     22	SENSOR_TRIP_POINT_NOTIFY = 0x4,
     23	SENSOR_TRIP_POINT_CONFIG = 0x5,
     24	SENSOR_READING_GET = 0x6,
     25	SENSOR_AXIS_DESCRIPTION_GET = 0x7,
     26	SENSOR_LIST_UPDATE_INTERVALS = 0x8,
     27	SENSOR_CONFIG_GET = 0x9,
     28	SENSOR_CONFIG_SET = 0xA,
     29	SENSOR_CONTINUOUS_UPDATE_NOTIFY = 0xB,
     30	SENSOR_NAME_GET = 0xC,
     31	SENSOR_AXIS_NAME_GET = 0xD,
     32};
     33
     34struct scmi_msg_resp_sensor_attributes {
     35	__le16 num_sensors;
     36	u8 max_requests;
     37	u8 reserved;
     38	__le32 reg_addr_low;
     39	__le32 reg_addr_high;
     40	__le32 reg_size;
     41};
     42
     43/* v3 attributes_low macros */
     44#define SUPPORTS_UPDATE_NOTIFY(x)	FIELD_GET(BIT(30), (x))
     45#define SENSOR_TSTAMP_EXP(x)		FIELD_GET(GENMASK(14, 10), (x))
     46#define SUPPORTS_TIMESTAMP(x)		FIELD_GET(BIT(9), (x))
     47#define SUPPORTS_EXTEND_ATTRS(x)	FIELD_GET(BIT(8), (x))
     48
     49/* v2 attributes_high macros */
     50#define SENSOR_UPDATE_BASE(x)		FIELD_GET(GENMASK(31, 27), (x))
     51#define SENSOR_UPDATE_SCALE(x)		FIELD_GET(GENMASK(26, 22), (x))
     52
     53/* v3 attributes_high macros */
     54#define SENSOR_AXIS_NUMBER(x)		FIELD_GET(GENMASK(21, 16), (x))
     55#define SUPPORTS_AXIS(x)		FIELD_GET(BIT(8), (x))
     56
     57/* v3 resolution macros */
     58#define SENSOR_RES(x)			FIELD_GET(GENMASK(26, 0), (x))
     59#define SENSOR_RES_EXP(x)		FIELD_GET(GENMASK(31, 27), (x))
     60
     61struct scmi_msg_resp_attrs {
     62	__le32 min_range_low;
     63	__le32 min_range_high;
     64	__le32 max_range_low;
     65	__le32 max_range_high;
     66};
     67
     68struct scmi_msg_sensor_description {
     69	__le32 desc_index;
     70};
     71
     72struct scmi_msg_resp_sensor_description {
     73	__le16 num_returned;
     74	__le16 num_remaining;
     75	struct scmi_sensor_descriptor {
     76		__le32 id;
     77		__le32 attributes_low;
     78/* Common attributes_low macros */
     79#define SUPPORTS_ASYNC_READ(x)		FIELD_GET(BIT(31), (x))
     80#define SUPPORTS_EXTENDED_NAMES(x)	FIELD_GET(BIT(29), (x))
     81#define NUM_TRIP_POINTS(x)		FIELD_GET(GENMASK(7, 0), (x))
     82		__le32 attributes_high;
     83/* Common attributes_high macros */
     84#define SENSOR_SCALE(x)			FIELD_GET(GENMASK(15, 11), (x))
     85#define SENSOR_SCALE_SIGN		BIT(4)
     86#define SENSOR_SCALE_EXTEND		GENMASK(31, 5)
     87#define SENSOR_TYPE(x)			FIELD_GET(GENMASK(7, 0), (x))
     88		u8 name[SCMI_SHORT_NAME_MAX_SIZE];
     89		/* only for version > 2.0 */
     90		__le32 power;
     91		__le32 resolution;
     92		struct scmi_msg_resp_attrs scalar_attrs;
     93	} desc[];
     94};
     95
     96/* Base scmi_sensor_descriptor size excluding extended attrs after name */
     97#define SCMI_MSG_RESP_SENS_DESCR_BASE_SZ	28
     98
     99/* Sign extend to a full s32 */
    100#define	S32_EXT(v)							\
    101	({								\
    102		int __v = (v);						\
    103									\
    104		if (__v & SENSOR_SCALE_SIGN)				\
    105			__v |= SENSOR_SCALE_EXTEND;			\
    106		__v;							\
    107	})
    108
    109struct scmi_msg_sensor_axis_description_get {
    110	__le32 id;
    111	__le32 axis_desc_index;
    112};
    113
    114struct scmi_msg_resp_sensor_axis_description {
    115	__le32 num_axis_flags;
    116#define NUM_AXIS_RETURNED(x)		FIELD_GET(GENMASK(5, 0), (x))
    117#define NUM_AXIS_REMAINING(x)		FIELD_GET(GENMASK(31, 26), (x))
    118	struct scmi_axis_descriptor {
    119		__le32 id;
    120		__le32 attributes_low;
    121#define SUPPORTS_EXTENDED_AXIS_NAMES(x)	FIELD_GET(BIT(9), (x))
    122		__le32 attributes_high;
    123		u8 name[SCMI_SHORT_NAME_MAX_SIZE];
    124		__le32 resolution;
    125		struct scmi_msg_resp_attrs attrs;
    126	} desc[];
    127};
    128
    129struct scmi_msg_resp_sensor_axis_names_description {
    130	__le32 num_axis_flags;
    131	struct scmi_sensor_axis_name_descriptor {
    132		__le32 axis_id;
    133		u8 name[SCMI_MAX_STR_SIZE];
    134	} desc[];
    135};
    136
    137/* Base scmi_axis_descriptor size excluding extended attrs after name */
    138#define SCMI_MSG_RESP_AXIS_DESCR_BASE_SZ	28
    139
    140struct scmi_msg_sensor_list_update_intervals {
    141	__le32 id;
    142	__le32 index;
    143};
    144
    145struct scmi_msg_resp_sensor_list_update_intervals {
    146	__le32 num_intervals_flags;
    147#define NUM_INTERVALS_RETURNED(x)	FIELD_GET(GENMASK(11, 0), (x))
    148#define SEGMENTED_INTVL_FORMAT(x)	FIELD_GET(BIT(12), (x))
    149#define NUM_INTERVALS_REMAINING(x)	FIELD_GET(GENMASK(31, 16), (x))
    150	__le32 intervals[];
    151};
    152
    153struct scmi_msg_sensor_request_notify {
    154	__le32 id;
    155	__le32 event_control;
    156#define SENSOR_NOTIFY_ALL	BIT(0)
    157};
    158
    159struct scmi_msg_set_sensor_trip_point {
    160	__le32 id;
    161	__le32 event_control;
    162#define SENSOR_TP_EVENT_MASK	(0x3)
    163#define SENSOR_TP_DISABLED	0x0
    164#define SENSOR_TP_POSITIVE	0x1
    165#define SENSOR_TP_NEGATIVE	0x2
    166#define SENSOR_TP_BOTH		0x3
    167#define SENSOR_TP_ID(x)		(((x) & 0xff) << 4)
    168	__le32 value_low;
    169	__le32 value_high;
    170};
    171
    172struct scmi_msg_sensor_config_set {
    173	__le32 id;
    174	__le32 sensor_config;
    175};
    176
    177struct scmi_msg_sensor_reading_get {
    178	__le32 id;
    179	__le32 flags;
    180#define SENSOR_READ_ASYNC	BIT(0)
    181};
    182
    183struct scmi_resp_sensor_reading_complete {
    184	__le32 id;
    185	__le32 readings_low;
    186	__le32 readings_high;
    187};
    188
    189struct scmi_sensor_reading_resp {
    190	__le32 sensor_value_low;
    191	__le32 sensor_value_high;
    192	__le32 timestamp_low;
    193	__le32 timestamp_high;
    194};
    195
    196struct scmi_resp_sensor_reading_complete_v3 {
    197	__le32 id;
    198	struct scmi_sensor_reading_resp readings[];
    199};
    200
    201struct scmi_sensor_trip_notify_payld {
    202	__le32 agent_id;
    203	__le32 sensor_id;
    204	__le32 trip_point_desc;
    205};
    206
    207struct scmi_sensor_update_notify_payld {
    208	__le32 agent_id;
    209	__le32 sensor_id;
    210	struct scmi_sensor_reading_resp readings[];
    211};
    212
    213struct sensors_info {
    214	u32 version;
    215	int num_sensors;
    216	int max_requests;
    217	u64 reg_addr;
    218	u32 reg_size;
    219	struct scmi_sensor_info *sensors;
    220};
    221
    222static int scmi_sensor_attributes_get(const struct scmi_protocol_handle *ph,
    223				      struct sensors_info *si)
    224{
    225	int ret;
    226	struct scmi_xfer *t;
    227	struct scmi_msg_resp_sensor_attributes *attr;
    228
    229	ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES,
    230				      0, sizeof(*attr), &t);
    231	if (ret)
    232		return ret;
    233
    234	attr = t->rx.buf;
    235
    236	ret = ph->xops->do_xfer(ph, t);
    237	if (!ret) {
    238		si->num_sensors = le16_to_cpu(attr->num_sensors);
    239		si->max_requests = attr->max_requests;
    240		si->reg_addr = le32_to_cpu(attr->reg_addr_low) |
    241				(u64)le32_to_cpu(attr->reg_addr_high) << 32;
    242		si->reg_size = le32_to_cpu(attr->reg_size);
    243	}
    244
    245	ph->xops->xfer_put(ph, t);
    246	return ret;
    247}
    248
    249static inline void scmi_parse_range_attrs(struct scmi_range_attrs *out,
    250					  const struct scmi_msg_resp_attrs *in)
    251{
    252	out->min_range = get_unaligned_le64((void *)&in->min_range_low);
    253	out->max_range = get_unaligned_le64((void *)&in->max_range_low);
    254}
    255
    256struct scmi_sens_ipriv {
    257	void *priv;
    258	struct device *dev;
    259};
    260
    261static void iter_intervals_prepare_message(void *message,
    262					   unsigned int desc_index,
    263					   const void *p)
    264{
    265	struct scmi_msg_sensor_list_update_intervals *msg = message;
    266	const struct scmi_sensor_info *s;
    267
    268	s = ((const struct scmi_sens_ipriv *)p)->priv;
    269	/* Set the number of sensors to be skipped/already read */
    270	msg->id = cpu_to_le32(s->id);
    271	msg->index = cpu_to_le32(desc_index);
    272}
    273
    274static int iter_intervals_update_state(struct scmi_iterator_state *st,
    275				       const void *response, void *p)
    276{
    277	u32 flags;
    278	struct scmi_sensor_info *s = ((struct scmi_sens_ipriv *)p)->priv;
    279	struct device *dev = ((struct scmi_sens_ipriv *)p)->dev;
    280	const struct scmi_msg_resp_sensor_list_update_intervals *r = response;
    281
    282	flags = le32_to_cpu(r->num_intervals_flags);
    283	st->num_returned = NUM_INTERVALS_RETURNED(flags);
    284	st->num_remaining = NUM_INTERVALS_REMAINING(flags);
    285
    286	/*
    287	 * Max intervals is not declared previously anywhere so we
    288	 * assume it's returned+remaining on first call.
    289	 */
    290	if (!st->max_resources) {
    291		s->intervals.segmented = SEGMENTED_INTVL_FORMAT(flags);
    292		s->intervals.count = st->num_returned + st->num_remaining;
    293		/* segmented intervals are reported in one triplet */
    294		if (s->intervals.segmented &&
    295		    (st->num_remaining || st->num_returned != 3)) {
    296			dev_err(dev,
    297				"Sensor ID:%d advertises an invalid segmented interval (%d)\n",
    298				s->id, s->intervals.count);
    299			s->intervals.segmented = false;
    300			s->intervals.count = 0;
    301			return -EINVAL;
    302		}
    303		/* Direct allocation when exceeding pre-allocated */
    304		if (s->intervals.count >= SCMI_MAX_PREALLOC_POOL) {
    305			s->intervals.desc =
    306				devm_kcalloc(dev,
    307					     s->intervals.count,
    308					     sizeof(*s->intervals.desc),
    309					     GFP_KERNEL);
    310			if (!s->intervals.desc) {
    311				s->intervals.segmented = false;
    312				s->intervals.count = 0;
    313				return -ENOMEM;
    314			}
    315		}
    316
    317		st->max_resources = s->intervals.count;
    318	}
    319
    320	return 0;
    321}
    322
    323static int
    324iter_intervals_process_response(const struct scmi_protocol_handle *ph,
    325				const void *response,
    326				struct scmi_iterator_state *st, void *p)
    327{
    328	const struct scmi_msg_resp_sensor_list_update_intervals *r = response;
    329	struct scmi_sensor_info *s = ((struct scmi_sens_ipriv *)p)->priv;
    330
    331	s->intervals.desc[st->desc_index + st->loop_idx] =
    332		le32_to_cpu(r->intervals[st->loop_idx]);
    333
    334	return 0;
    335}
    336
    337static int scmi_sensor_update_intervals(const struct scmi_protocol_handle *ph,
    338					struct scmi_sensor_info *s)
    339{
    340	void *iter;
    341	struct scmi_iterator_ops ops = {
    342		.prepare_message = iter_intervals_prepare_message,
    343		.update_state = iter_intervals_update_state,
    344		.process_response = iter_intervals_process_response,
    345	};
    346	struct scmi_sens_ipriv upriv = {
    347		.priv = s,
    348		.dev = ph->dev,
    349	};
    350
    351	iter = ph->hops->iter_response_init(ph, &ops, s->intervals.count,
    352					    SENSOR_LIST_UPDATE_INTERVALS,
    353					    sizeof(struct scmi_msg_sensor_list_update_intervals),
    354					    &upriv);
    355	if (IS_ERR(iter))
    356		return PTR_ERR(iter);
    357
    358	return ph->hops->iter_response_run(iter);
    359}
    360
    361struct scmi_apriv {
    362	bool any_axes_support_extended_names;
    363	struct scmi_sensor_info *s;
    364};
    365
    366static void iter_axes_desc_prepare_message(void *message,
    367					   const unsigned int desc_index,
    368					   const void *priv)
    369{
    370	struct scmi_msg_sensor_axis_description_get *msg = message;
    371	const struct scmi_apriv *apriv = priv;
    372
    373	/* Set the number of sensors to be skipped/already read */
    374	msg->id = cpu_to_le32(apriv->s->id);
    375	msg->axis_desc_index = cpu_to_le32(desc_index);
    376}
    377
    378static int
    379iter_axes_desc_update_state(struct scmi_iterator_state *st,
    380			    const void *response, void *priv)
    381{
    382	u32 flags;
    383	const struct scmi_msg_resp_sensor_axis_description *r = response;
    384
    385	flags = le32_to_cpu(r->num_axis_flags);
    386	st->num_returned = NUM_AXIS_RETURNED(flags);
    387	st->num_remaining = NUM_AXIS_REMAINING(flags);
    388	st->priv = (void *)&r->desc[0];
    389
    390	return 0;
    391}
    392
    393static int
    394iter_axes_desc_process_response(const struct scmi_protocol_handle *ph,
    395				const void *response,
    396				struct scmi_iterator_state *st, void *priv)
    397{
    398	u32 attrh, attrl;
    399	struct scmi_sensor_axis_info *a;
    400	size_t dsize = SCMI_MSG_RESP_AXIS_DESCR_BASE_SZ;
    401	struct scmi_apriv *apriv = priv;
    402	const struct scmi_axis_descriptor *adesc = st->priv;
    403
    404	attrl = le32_to_cpu(adesc->attributes_low);
    405	if (SUPPORTS_EXTENDED_AXIS_NAMES(attrl))
    406		apriv->any_axes_support_extended_names = true;
    407
    408	a = &apriv->s->axis[st->desc_index + st->loop_idx];
    409	a->id = le32_to_cpu(adesc->id);
    410	a->extended_attrs = SUPPORTS_EXTEND_ATTRS(attrl);
    411
    412	attrh = le32_to_cpu(adesc->attributes_high);
    413	a->scale = S32_EXT(SENSOR_SCALE(attrh));
    414	a->type = SENSOR_TYPE(attrh);
    415	strscpy(a->name, adesc->name, SCMI_SHORT_NAME_MAX_SIZE);
    416
    417	if (a->extended_attrs) {
    418		unsigned int ares = le32_to_cpu(adesc->resolution);
    419
    420		a->resolution = SENSOR_RES(ares);
    421		a->exponent = S32_EXT(SENSOR_RES_EXP(ares));
    422		dsize += sizeof(adesc->resolution);
    423
    424		scmi_parse_range_attrs(&a->attrs, &adesc->attrs);
    425		dsize += sizeof(adesc->attrs);
    426	}
    427	st->priv = ((u8 *)adesc + dsize);
    428
    429	return 0;
    430}
    431
    432static int
    433iter_axes_extended_name_update_state(struct scmi_iterator_state *st,
    434				     const void *response, void *priv)
    435{
    436	u32 flags;
    437	const struct scmi_msg_resp_sensor_axis_names_description *r = response;
    438
    439	flags = le32_to_cpu(r->num_axis_flags);
    440	st->num_returned = NUM_AXIS_RETURNED(flags);
    441	st->num_remaining = NUM_AXIS_REMAINING(flags);
    442	st->priv = (void *)&r->desc[0];
    443
    444	return 0;
    445}
    446
    447static int
    448iter_axes_extended_name_process_response(const struct scmi_protocol_handle *ph,
    449					 const void *response,
    450					 struct scmi_iterator_state *st,
    451					 void *priv)
    452{
    453	struct scmi_sensor_axis_info *a;
    454	const struct scmi_apriv *apriv = priv;
    455	struct scmi_sensor_axis_name_descriptor *adesc = st->priv;
    456	u32 axis_id = le32_to_cpu(adesc->axis_id);
    457
    458	if (axis_id >= st->max_resources)
    459		return -EPROTO;
    460
    461	/*
    462	 * Pick the corresponding descriptor based on the axis_id embedded
    463	 * in the reply since the list of axes supporting extended names
    464	 * can be a subset of all the axes.
    465	 */
    466	a = &apriv->s->axis[axis_id];
    467	strscpy(a->name, adesc->name, SCMI_MAX_STR_SIZE);
    468	st->priv = ++adesc;
    469
    470	return 0;
    471}
    472
    473static int
    474scmi_sensor_axis_extended_names_get(const struct scmi_protocol_handle *ph,
    475				    struct scmi_sensor_info *s)
    476{
    477	int ret;
    478	void *iter;
    479	struct scmi_iterator_ops ops = {
    480		.prepare_message = iter_axes_desc_prepare_message,
    481		.update_state = iter_axes_extended_name_update_state,
    482		.process_response = iter_axes_extended_name_process_response,
    483	};
    484	struct scmi_apriv apriv = {
    485		.any_axes_support_extended_names = false,
    486		.s = s,
    487	};
    488
    489	iter = ph->hops->iter_response_init(ph, &ops, s->num_axis,
    490					    SENSOR_AXIS_NAME_GET,
    491					    sizeof(struct scmi_msg_sensor_axis_description_get),
    492					    &apriv);
    493	if (IS_ERR(iter))
    494		return PTR_ERR(iter);
    495
    496	/*
    497	 * Do not cause whole protocol initialization failure when failing to
    498	 * get extended names for axes.
    499	 */
    500	ret = ph->hops->iter_response_run(iter);
    501	if (ret)
    502		dev_warn(ph->dev,
    503			 "Failed to get axes extended names for %s (ret:%d).\n",
    504			 s->name, ret);
    505
    506	return 0;
    507}
    508
    509static int scmi_sensor_axis_description(const struct scmi_protocol_handle *ph,
    510					struct scmi_sensor_info *s,
    511					u32 version)
    512{
    513	int ret;
    514	void *iter;
    515	struct scmi_iterator_ops ops = {
    516		.prepare_message = iter_axes_desc_prepare_message,
    517		.update_state = iter_axes_desc_update_state,
    518		.process_response = iter_axes_desc_process_response,
    519	};
    520	struct scmi_apriv apriv = {
    521		.any_axes_support_extended_names = false,
    522		.s = s,
    523	};
    524
    525	s->axis = devm_kcalloc(ph->dev, s->num_axis,
    526			       sizeof(*s->axis), GFP_KERNEL);
    527	if (!s->axis)
    528		return -ENOMEM;
    529
    530	iter = ph->hops->iter_response_init(ph, &ops, s->num_axis,
    531					    SENSOR_AXIS_DESCRIPTION_GET,
    532					    sizeof(struct scmi_msg_sensor_axis_description_get),
    533					    &apriv);
    534	if (IS_ERR(iter))
    535		return PTR_ERR(iter);
    536
    537	ret = ph->hops->iter_response_run(iter);
    538	if (ret)
    539		return ret;
    540
    541	if (PROTOCOL_REV_MAJOR(version) >= 0x3 &&
    542	    apriv.any_axes_support_extended_names)
    543		ret = scmi_sensor_axis_extended_names_get(ph, s);
    544
    545	return ret;
    546}
    547
    548static void iter_sens_descr_prepare_message(void *message,
    549					    unsigned int desc_index,
    550					    const void *priv)
    551{
    552	struct scmi_msg_sensor_description *msg = message;
    553
    554	msg->desc_index = cpu_to_le32(desc_index);
    555}
    556
    557static int iter_sens_descr_update_state(struct scmi_iterator_state *st,
    558					const void *response, void *priv)
    559{
    560	const struct scmi_msg_resp_sensor_description *r = response;
    561
    562	st->num_returned = le16_to_cpu(r->num_returned);
    563	st->num_remaining = le16_to_cpu(r->num_remaining);
    564	st->priv = (void *)&r->desc[0];
    565
    566	return 0;
    567}
    568
    569static int
    570iter_sens_descr_process_response(const struct scmi_protocol_handle *ph,
    571				 const void *response,
    572				 struct scmi_iterator_state *st, void *priv)
    573
    574{
    575	int ret = 0;
    576	u32 attrh, attrl;
    577	size_t dsize = SCMI_MSG_RESP_SENS_DESCR_BASE_SZ;
    578	struct scmi_sensor_info *s;
    579	struct sensors_info *si = priv;
    580	const struct scmi_sensor_descriptor *sdesc = st->priv;
    581
    582	s = &si->sensors[st->desc_index + st->loop_idx];
    583	s->id = le32_to_cpu(sdesc->id);
    584
    585	attrl = le32_to_cpu(sdesc->attributes_low);
    586	/* common bitfields parsing */
    587	s->async = SUPPORTS_ASYNC_READ(attrl);
    588	s->num_trip_points = NUM_TRIP_POINTS(attrl);
    589	/**
    590	 * only SCMIv3.0 specific bitfield below.
    591	 * Such bitfields are assumed to be zeroed on non
    592	 * relevant fw versions...assuming fw not buggy !
    593	 */
    594	s->update = SUPPORTS_UPDATE_NOTIFY(attrl);
    595	s->timestamped = SUPPORTS_TIMESTAMP(attrl);
    596	if (s->timestamped)
    597		s->tstamp_scale = S32_EXT(SENSOR_TSTAMP_EXP(attrl));
    598	s->extended_scalar_attrs = SUPPORTS_EXTEND_ATTRS(attrl);
    599
    600	attrh = le32_to_cpu(sdesc->attributes_high);
    601	/* common bitfields parsing */
    602	s->scale = S32_EXT(SENSOR_SCALE(attrh));
    603	s->type = SENSOR_TYPE(attrh);
    604	/* Use pre-allocated pool wherever possible */
    605	s->intervals.desc = s->intervals.prealloc_pool;
    606	if (si->version == SCMIv2_SENSOR_PROTOCOL) {
    607		s->intervals.segmented = false;
    608		s->intervals.count = 1;
    609		/*
    610		 * Convert SCMIv2.0 update interval format to
    611		 * SCMIv3.0 to be used as the common exposed
    612		 * descriptor, accessible via common macros.
    613		 */
    614		s->intervals.desc[0] = (SENSOR_UPDATE_BASE(attrh) << 5) |
    615					SENSOR_UPDATE_SCALE(attrh);
    616	} else {
    617		/*
    618		 * From SCMIv3.0 update intervals are retrieved
    619		 * via a dedicated (optional) command.
    620		 * Since the command is optional, on error carry
    621		 * on without any update interval.
    622		 */
    623		if (scmi_sensor_update_intervals(ph, s))
    624			dev_dbg(ph->dev,
    625				"Update Intervals not available for sensor ID:%d\n",
    626				s->id);
    627	}
    628	/**
    629	 * only > SCMIv2.0 specific bitfield below.
    630	 * Such bitfields are assumed to be zeroed on non
    631	 * relevant fw versions...assuming fw not buggy !
    632	 */
    633	s->num_axis = min_t(unsigned int,
    634			    SUPPORTS_AXIS(attrh) ?
    635			    SENSOR_AXIS_NUMBER(attrh) : 0,
    636			    SCMI_MAX_NUM_SENSOR_AXIS);
    637	strscpy(s->name, sdesc->name, SCMI_SHORT_NAME_MAX_SIZE);
    638
    639	/*
    640	 * If supported overwrite short name with the extended
    641	 * one; on error just carry on and use already provided
    642	 * short name.
    643	 */
    644	if (PROTOCOL_REV_MAJOR(si->version) >= 0x3 &&
    645	    SUPPORTS_EXTENDED_NAMES(attrl))
    646		ph->hops->extended_name_get(ph, SENSOR_NAME_GET, s->id,
    647					    s->name, SCMI_MAX_STR_SIZE);
    648
    649	if (s->extended_scalar_attrs) {
    650		s->sensor_power = le32_to_cpu(sdesc->power);
    651		dsize += sizeof(sdesc->power);
    652
    653		/* Only for sensors reporting scalar values */
    654		if (s->num_axis == 0) {
    655			unsigned int sres = le32_to_cpu(sdesc->resolution);
    656
    657			s->resolution = SENSOR_RES(sres);
    658			s->exponent = S32_EXT(SENSOR_RES_EXP(sres));
    659			dsize += sizeof(sdesc->resolution);
    660
    661			scmi_parse_range_attrs(&s->scalar_attrs,
    662					       &sdesc->scalar_attrs);
    663			dsize += sizeof(sdesc->scalar_attrs);
    664		}
    665	}
    666
    667	if (s->num_axis > 0)
    668		ret = scmi_sensor_axis_description(ph, s, si->version);
    669
    670	st->priv = ((u8 *)sdesc + dsize);
    671
    672	return ret;
    673}
    674
    675static int scmi_sensor_description_get(const struct scmi_protocol_handle *ph,
    676				       struct sensors_info *si)
    677{
    678	void *iter;
    679	struct scmi_iterator_ops ops = {
    680		.prepare_message = iter_sens_descr_prepare_message,
    681		.update_state = iter_sens_descr_update_state,
    682		.process_response = iter_sens_descr_process_response,
    683	};
    684
    685	iter = ph->hops->iter_response_init(ph, &ops, si->num_sensors,
    686					    SENSOR_DESCRIPTION_GET,
    687					    sizeof(__le32), si);
    688	if (IS_ERR(iter))
    689		return PTR_ERR(iter);
    690
    691	return ph->hops->iter_response_run(iter);
    692}
    693
    694static inline int
    695scmi_sensor_request_notify(const struct scmi_protocol_handle *ph, u32 sensor_id,
    696			   u8 message_id, bool enable)
    697{
    698	int ret;
    699	u32 evt_cntl = enable ? SENSOR_NOTIFY_ALL : 0;
    700	struct scmi_xfer *t;
    701	struct scmi_msg_sensor_request_notify *cfg;
    702
    703	ret = ph->xops->xfer_get_init(ph, message_id, sizeof(*cfg), 0, &t);
    704	if (ret)
    705		return ret;
    706
    707	cfg = t->tx.buf;
    708	cfg->id = cpu_to_le32(sensor_id);
    709	cfg->event_control = cpu_to_le32(evt_cntl);
    710
    711	ret = ph->xops->do_xfer(ph, t);
    712
    713	ph->xops->xfer_put(ph, t);
    714	return ret;
    715}
    716
    717static int scmi_sensor_trip_point_notify(const struct scmi_protocol_handle *ph,
    718					 u32 sensor_id, bool enable)
    719{
    720	return scmi_sensor_request_notify(ph, sensor_id,
    721					  SENSOR_TRIP_POINT_NOTIFY,
    722					  enable);
    723}
    724
    725static int
    726scmi_sensor_continuous_update_notify(const struct scmi_protocol_handle *ph,
    727				     u32 sensor_id, bool enable)
    728{
    729	return scmi_sensor_request_notify(ph, sensor_id,
    730					  SENSOR_CONTINUOUS_UPDATE_NOTIFY,
    731					  enable);
    732}
    733
    734static int
    735scmi_sensor_trip_point_config(const struct scmi_protocol_handle *ph,
    736			      u32 sensor_id, u8 trip_id, u64 trip_value)
    737{
    738	int ret;
    739	u32 evt_cntl = SENSOR_TP_BOTH;
    740	struct scmi_xfer *t;
    741	struct scmi_msg_set_sensor_trip_point *trip;
    742
    743	ret = ph->xops->xfer_get_init(ph, SENSOR_TRIP_POINT_CONFIG,
    744				      sizeof(*trip), 0, &t);
    745	if (ret)
    746		return ret;
    747
    748	trip = t->tx.buf;
    749	trip->id = cpu_to_le32(sensor_id);
    750	trip->event_control = cpu_to_le32(evt_cntl | SENSOR_TP_ID(trip_id));
    751	trip->value_low = cpu_to_le32(trip_value & 0xffffffff);
    752	trip->value_high = cpu_to_le32(trip_value >> 32);
    753
    754	ret = ph->xops->do_xfer(ph, t);
    755
    756	ph->xops->xfer_put(ph, t);
    757	return ret;
    758}
    759
    760static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph,
    761				  u32 sensor_id, u32 *sensor_config)
    762{
    763	int ret;
    764	struct scmi_xfer *t;
    765
    766	ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_GET,
    767				      sizeof(__le32), sizeof(__le32), &t);
    768	if (ret)
    769		return ret;
    770
    771	put_unaligned_le32(sensor_id, t->tx.buf);
    772	ret = ph->xops->do_xfer(ph, t);
    773	if (!ret) {
    774		struct sensors_info *si = ph->get_priv(ph);
    775		struct scmi_sensor_info *s = si->sensors + sensor_id;
    776
    777		*sensor_config = get_unaligned_le64(t->rx.buf);
    778		s->sensor_config = *sensor_config;
    779	}
    780
    781	ph->xops->xfer_put(ph, t);
    782	return ret;
    783}
    784
    785static int scmi_sensor_config_set(const struct scmi_protocol_handle *ph,
    786				  u32 sensor_id, u32 sensor_config)
    787{
    788	int ret;
    789	struct scmi_xfer *t;
    790	struct scmi_msg_sensor_config_set *msg;
    791
    792	ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_SET,
    793				      sizeof(*msg), 0, &t);
    794	if (ret)
    795		return ret;
    796
    797	msg = t->tx.buf;
    798	msg->id = cpu_to_le32(sensor_id);
    799	msg->sensor_config = cpu_to_le32(sensor_config);
    800
    801	ret = ph->xops->do_xfer(ph, t);
    802	if (!ret) {
    803		struct sensors_info *si = ph->get_priv(ph);
    804		struct scmi_sensor_info *s = si->sensors + sensor_id;
    805
    806		s->sensor_config = sensor_config;
    807	}
    808
    809	ph->xops->xfer_put(ph, t);
    810	return ret;
    811}
    812
    813/**
    814 * scmi_sensor_reading_get  - Read scalar sensor value
    815 * @ph: Protocol handle
    816 * @sensor_id: Sensor ID
    817 * @value: The 64bit value sensor reading
    818 *
    819 * This function returns a single 64 bit reading value representing the sensor
    820 * value; if the platform SCMI Protocol implementation and the sensor support
    821 * multiple axis and timestamped-reads, this just returns the first axis while
    822 * dropping the timestamp value.
    823 * Use instead the @scmi_sensor_reading_get_timestamped to retrieve the array of
    824 * timestamped multi-axis values.
    825 *
    826 * Return: 0 on Success
    827 */
    828static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph,
    829				   u32 sensor_id, u64 *value)
    830{
    831	int ret;
    832	struct scmi_xfer *t;
    833	struct scmi_msg_sensor_reading_get *sensor;
    834	struct sensors_info *si = ph->get_priv(ph);
    835	struct scmi_sensor_info *s = si->sensors + sensor_id;
    836
    837	ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET,
    838				      sizeof(*sensor), 0, &t);
    839	if (ret)
    840		return ret;
    841
    842	sensor = t->tx.buf;
    843	sensor->id = cpu_to_le32(sensor_id);
    844	if (s->async) {
    845		sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
    846		ret = ph->xops->do_xfer_with_response(ph, t);
    847		if (!ret) {
    848			struct scmi_resp_sensor_reading_complete *resp;
    849
    850			resp = t->rx.buf;
    851			if (le32_to_cpu(resp->id) == sensor_id)
    852				*value =
    853					get_unaligned_le64(&resp->readings_low);
    854			else
    855				ret = -EPROTO;
    856		}
    857	} else {
    858		sensor->flags = cpu_to_le32(0);
    859		ret = ph->xops->do_xfer(ph, t);
    860		if (!ret)
    861			*value = get_unaligned_le64(t->rx.buf);
    862	}
    863
    864	ph->xops->xfer_put(ph, t);
    865	return ret;
    866}
    867
    868static inline void
    869scmi_parse_sensor_readings(struct scmi_sensor_reading *out,
    870			   const struct scmi_sensor_reading_resp *in)
    871{
    872	out->value = get_unaligned_le64((void *)&in->sensor_value_low);
    873	out->timestamp = get_unaligned_le64((void *)&in->timestamp_low);
    874}
    875
    876/**
    877 * scmi_sensor_reading_get_timestamped  - Read multiple-axis timestamped values
    878 * @ph: Protocol handle
    879 * @sensor_id: Sensor ID
    880 * @count: The length of the provided @readings array
    881 * @readings: An array of elements each representing a timestamped per-axis
    882 *	      reading of type @struct scmi_sensor_reading.
    883 *	      Returned readings are ordered as the @axis descriptors array
    884 *	      included in @struct scmi_sensor_info and the max number of
    885 *	      returned elements is min(@count, @num_axis); ideally the provided
    886 *	      array should be of length @count equal to @num_axis.
    887 *
    888 * Return: 0 on Success
    889 */
    890static int
    891scmi_sensor_reading_get_timestamped(const struct scmi_protocol_handle *ph,
    892				    u32 sensor_id, u8 count,
    893				    struct scmi_sensor_reading *readings)
    894{
    895	int ret;
    896	struct scmi_xfer *t;
    897	struct scmi_msg_sensor_reading_get *sensor;
    898	struct sensors_info *si = ph->get_priv(ph);
    899	struct scmi_sensor_info *s = si->sensors + sensor_id;
    900
    901	if (!count || !readings ||
    902	    (!s->num_axis && count > 1) || (s->num_axis && count > s->num_axis))
    903		return -EINVAL;
    904
    905	ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET,
    906				      sizeof(*sensor), 0, &t);
    907	if (ret)
    908		return ret;
    909
    910	sensor = t->tx.buf;
    911	sensor->id = cpu_to_le32(sensor_id);
    912	if (s->async) {
    913		sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
    914		ret = ph->xops->do_xfer_with_response(ph, t);
    915		if (!ret) {
    916			int i;
    917			struct scmi_resp_sensor_reading_complete_v3 *resp;
    918
    919			resp = t->rx.buf;
    920			/* Retrieve only the number of requested axis anyway */
    921			if (le32_to_cpu(resp->id) == sensor_id)
    922				for (i = 0; i < count; i++)
    923					scmi_parse_sensor_readings(&readings[i],
    924								   &resp->readings[i]);
    925			else
    926				ret = -EPROTO;
    927		}
    928	} else {
    929		sensor->flags = cpu_to_le32(0);
    930		ret = ph->xops->do_xfer(ph, t);
    931		if (!ret) {
    932			int i;
    933			struct scmi_sensor_reading_resp *resp_readings;
    934
    935			resp_readings = t->rx.buf;
    936			for (i = 0; i < count; i++)
    937				scmi_parse_sensor_readings(&readings[i],
    938							   &resp_readings[i]);
    939		}
    940	}
    941
    942	ph->xops->xfer_put(ph, t);
    943	return ret;
    944}
    945
    946static const struct scmi_sensor_info *
    947scmi_sensor_info_get(const struct scmi_protocol_handle *ph, u32 sensor_id)
    948{
    949	struct sensors_info *si = ph->get_priv(ph);
    950
    951	return si->sensors + sensor_id;
    952}
    953
    954static int scmi_sensor_count_get(const struct scmi_protocol_handle *ph)
    955{
    956	struct sensors_info *si = ph->get_priv(ph);
    957
    958	return si->num_sensors;
    959}
    960
    961static const struct scmi_sensor_proto_ops sensor_proto_ops = {
    962	.count_get = scmi_sensor_count_get,
    963	.info_get = scmi_sensor_info_get,
    964	.trip_point_config = scmi_sensor_trip_point_config,
    965	.reading_get = scmi_sensor_reading_get,
    966	.reading_get_timestamped = scmi_sensor_reading_get_timestamped,
    967	.config_get = scmi_sensor_config_get,
    968	.config_set = scmi_sensor_config_set,
    969};
    970
    971static int scmi_sensor_set_notify_enabled(const struct scmi_protocol_handle *ph,
    972					  u8 evt_id, u32 src_id, bool enable)
    973{
    974	int ret;
    975
    976	switch (evt_id) {
    977	case SCMI_EVENT_SENSOR_TRIP_POINT_EVENT:
    978		ret = scmi_sensor_trip_point_notify(ph, src_id, enable);
    979		break;
    980	case SCMI_EVENT_SENSOR_UPDATE:
    981		ret = scmi_sensor_continuous_update_notify(ph, src_id, enable);
    982		break;
    983	default:
    984		ret = -EINVAL;
    985		break;
    986	}
    987
    988	if (ret)
    989		pr_debug("FAIL_ENABLED - evt[%X] dom[%d] - ret:%d\n",
    990			 evt_id, src_id, ret);
    991
    992	return ret;
    993}
    994
    995static void *
    996scmi_sensor_fill_custom_report(const struct scmi_protocol_handle *ph,
    997			       u8 evt_id, ktime_t timestamp,
    998			       const void *payld, size_t payld_sz,
    999			       void *report, u32 *src_id)
   1000{
   1001	void *rep = NULL;
   1002
   1003	switch (evt_id) {
   1004	case SCMI_EVENT_SENSOR_TRIP_POINT_EVENT:
   1005	{
   1006		const struct scmi_sensor_trip_notify_payld *p = payld;
   1007		struct scmi_sensor_trip_point_report *r = report;
   1008
   1009		if (sizeof(*p) != payld_sz)
   1010			break;
   1011
   1012		r->timestamp = timestamp;
   1013		r->agent_id = le32_to_cpu(p->agent_id);
   1014		r->sensor_id = le32_to_cpu(p->sensor_id);
   1015		r->trip_point_desc = le32_to_cpu(p->trip_point_desc);
   1016		*src_id = r->sensor_id;
   1017		rep = r;
   1018		break;
   1019	}
   1020	case SCMI_EVENT_SENSOR_UPDATE:
   1021	{
   1022		int i;
   1023		struct scmi_sensor_info *s;
   1024		const struct scmi_sensor_update_notify_payld *p = payld;
   1025		struct scmi_sensor_update_report *r = report;
   1026		struct sensors_info *sinfo = ph->get_priv(ph);
   1027
   1028		/* payld_sz is variable for this event */
   1029		r->sensor_id = le32_to_cpu(p->sensor_id);
   1030		if (r->sensor_id >= sinfo->num_sensors)
   1031			break;
   1032		r->timestamp = timestamp;
   1033		r->agent_id = le32_to_cpu(p->agent_id);
   1034		s = &sinfo->sensors[r->sensor_id];
   1035		/*
   1036		 * The generated report r (@struct scmi_sensor_update_report)
   1037		 * was pre-allocated to contain up to SCMI_MAX_NUM_SENSOR_AXIS
   1038		 * readings: here it is filled with the effective @num_axis
   1039		 * readings defined for this sensor or 1 for scalar sensors.
   1040		 */
   1041		r->readings_count = s->num_axis ?: 1;
   1042		for (i = 0; i < r->readings_count; i++)
   1043			scmi_parse_sensor_readings(&r->readings[i],
   1044						   &p->readings[i]);
   1045		*src_id = r->sensor_id;
   1046		rep = r;
   1047		break;
   1048	}
   1049	default:
   1050		break;
   1051	}
   1052
   1053	return rep;
   1054}
   1055
   1056static int scmi_sensor_get_num_sources(const struct scmi_protocol_handle *ph)
   1057{
   1058	struct sensors_info *si = ph->get_priv(ph);
   1059
   1060	return si->num_sensors;
   1061}
   1062
   1063static const struct scmi_event sensor_events[] = {
   1064	{
   1065		.id = SCMI_EVENT_SENSOR_TRIP_POINT_EVENT,
   1066		.max_payld_sz = sizeof(struct scmi_sensor_trip_notify_payld),
   1067		.max_report_sz = sizeof(struct scmi_sensor_trip_point_report),
   1068	},
   1069	{
   1070		.id = SCMI_EVENT_SENSOR_UPDATE,
   1071		.max_payld_sz =
   1072			sizeof(struct scmi_sensor_update_notify_payld) +
   1073			 SCMI_MAX_NUM_SENSOR_AXIS *
   1074			 sizeof(struct scmi_sensor_reading_resp),
   1075		.max_report_sz = sizeof(struct scmi_sensor_update_report) +
   1076				  SCMI_MAX_NUM_SENSOR_AXIS *
   1077				  sizeof(struct scmi_sensor_reading),
   1078	},
   1079};
   1080
   1081static const struct scmi_event_ops sensor_event_ops = {
   1082	.get_num_sources = scmi_sensor_get_num_sources,
   1083	.set_notify_enabled = scmi_sensor_set_notify_enabled,
   1084	.fill_custom_report = scmi_sensor_fill_custom_report,
   1085};
   1086
   1087static const struct scmi_protocol_events sensor_protocol_events = {
   1088	.queue_sz = SCMI_PROTO_QUEUE_SZ,
   1089	.ops = &sensor_event_ops,
   1090	.evts = sensor_events,
   1091	.num_events = ARRAY_SIZE(sensor_events),
   1092};
   1093
   1094static int scmi_sensors_protocol_init(const struct scmi_protocol_handle *ph)
   1095{
   1096	u32 version;
   1097	int ret;
   1098	struct sensors_info *sinfo;
   1099
   1100	ret = ph->xops->version_get(ph, &version);
   1101	if (ret)
   1102		return ret;
   1103
   1104	dev_dbg(ph->dev, "Sensor Version %d.%d\n",
   1105		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
   1106
   1107	sinfo = devm_kzalloc(ph->dev, sizeof(*sinfo), GFP_KERNEL);
   1108	if (!sinfo)
   1109		return -ENOMEM;
   1110	sinfo->version = version;
   1111
   1112	ret = scmi_sensor_attributes_get(ph, sinfo);
   1113	if (ret)
   1114		return ret;
   1115	sinfo->sensors = devm_kcalloc(ph->dev, sinfo->num_sensors,
   1116				      sizeof(*sinfo->sensors), GFP_KERNEL);
   1117	if (!sinfo->sensors)
   1118		return -ENOMEM;
   1119
   1120	ret = scmi_sensor_description_get(ph, sinfo);
   1121	if (ret)
   1122		return ret;
   1123
   1124	return ph->set_priv(ph, sinfo);
   1125}
   1126
   1127static const struct scmi_protocol scmi_sensors = {
   1128	.id = SCMI_PROTOCOL_SENSOR,
   1129	.owner = THIS_MODULE,
   1130	.instance_init = &scmi_sensors_protocol_init,
   1131	.ops = &sensor_proto_ops,
   1132	.events = &sensor_protocol_events,
   1133};
   1134
   1135DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(sensors, scmi_sensors)