Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * System Control and Management Interface (SCMI) Sensor Protocol
0004  *
0005  * Copyright (C) 2018-2022 ARM Ltd.
0006  */
0007 
0008 #define pr_fmt(fmt) "SCMI Notifications SENSOR - " fmt
0009 
0010 #include <linux/bitfield.h>
0011 #include <linux/module.h>
0012 #include <linux/scmi_protocol.h>
0013 
0014 #include "protocols.h"
0015 #include "notify.h"
0016 
0017 #define SCMI_MAX_NUM_SENSOR_AXIS    63
0018 #define SCMIv2_SENSOR_PROTOCOL      0x10000
0019 
0020 enum scmi_sensor_protocol_cmd {
0021     SENSOR_DESCRIPTION_GET = 0x3,
0022     SENSOR_TRIP_POINT_NOTIFY = 0x4,
0023     SENSOR_TRIP_POINT_CONFIG = 0x5,
0024     SENSOR_READING_GET = 0x6,
0025     SENSOR_AXIS_DESCRIPTION_GET = 0x7,
0026     SENSOR_LIST_UPDATE_INTERVALS = 0x8,
0027     SENSOR_CONFIG_GET = 0x9,
0028     SENSOR_CONFIG_SET = 0xA,
0029     SENSOR_CONTINUOUS_UPDATE_NOTIFY = 0xB,
0030     SENSOR_NAME_GET = 0xC,
0031     SENSOR_AXIS_NAME_GET = 0xD,
0032 };
0033 
0034 struct scmi_msg_resp_sensor_attributes {
0035     __le16 num_sensors;
0036     u8 max_requests;
0037     u8 reserved;
0038     __le32 reg_addr_low;
0039     __le32 reg_addr_high;
0040     __le32 reg_size;
0041 };
0042 
0043 /* v3 attributes_low macros */
0044 #define SUPPORTS_UPDATE_NOTIFY(x)   FIELD_GET(BIT(30), (x))
0045 #define SENSOR_TSTAMP_EXP(x)        FIELD_GET(GENMASK(14, 10), (x))
0046 #define SUPPORTS_TIMESTAMP(x)       FIELD_GET(BIT(9), (x))
0047 #define SUPPORTS_EXTEND_ATTRS(x)    FIELD_GET(BIT(8), (x))
0048 
0049 /* v2 attributes_high macros */
0050 #define SENSOR_UPDATE_BASE(x)       FIELD_GET(GENMASK(31, 27), (x))
0051 #define SENSOR_UPDATE_SCALE(x)      FIELD_GET(GENMASK(26, 22), (x))
0052 
0053 /* v3 attributes_high macros */
0054 #define SENSOR_AXIS_NUMBER(x)       FIELD_GET(GENMASK(21, 16), (x))
0055 #define SUPPORTS_AXIS(x)        FIELD_GET(BIT(8), (x))
0056 
0057 /* v3 resolution macros */
0058 #define SENSOR_RES(x)           FIELD_GET(GENMASK(26, 0), (x))
0059 #define SENSOR_RES_EXP(x)       FIELD_GET(GENMASK(31, 27), (x))
0060 
0061 struct scmi_msg_resp_attrs {
0062     __le32 min_range_low;
0063     __le32 min_range_high;
0064     __le32 max_range_low;
0065     __le32 max_range_high;
0066 };
0067 
0068 struct scmi_msg_sensor_description {
0069     __le32 desc_index;
0070 };
0071 
0072 struct scmi_msg_resp_sensor_description {
0073     __le16 num_returned;
0074     __le16 num_remaining;
0075     struct scmi_sensor_descriptor {
0076         __le32 id;
0077         __le32 attributes_low;
0078 /* Common attributes_low macros */
0079 #define SUPPORTS_ASYNC_READ(x)      FIELD_GET(BIT(31), (x))
0080 #define SUPPORTS_EXTENDED_NAMES(x)  FIELD_GET(BIT(29), (x))
0081 #define NUM_TRIP_POINTS(x)      FIELD_GET(GENMASK(7, 0), (x))
0082         __le32 attributes_high;
0083 /* Common attributes_high macros */
0084 #define SENSOR_SCALE(x)         FIELD_GET(GENMASK(15, 11), (x))
0085 #define SENSOR_SCALE_SIGN       BIT(4)
0086 #define SENSOR_SCALE_EXTEND     GENMASK(31, 5)
0087 #define SENSOR_TYPE(x)          FIELD_GET(GENMASK(7, 0), (x))
0088         u8 name[SCMI_SHORT_NAME_MAX_SIZE];
0089         /* only for version > 2.0 */
0090         __le32 power;
0091         __le32 resolution;
0092         struct scmi_msg_resp_attrs scalar_attrs;
0093     } desc[];
0094 };
0095 
0096 /* Base scmi_sensor_descriptor size excluding extended attrs after name */
0097 #define SCMI_MSG_RESP_SENS_DESCR_BASE_SZ    28
0098 
0099 /* Sign extend to a full s32 */
0100 #define S32_EXT(v)                          \
0101     ({                              \
0102         int __v = (v);                      \
0103                                     \
0104         if (__v & SENSOR_SCALE_SIGN)                \
0105             __v |= SENSOR_SCALE_EXTEND;         \
0106         __v;                            \
0107     })
0108 
0109 struct scmi_msg_sensor_axis_description_get {
0110     __le32 id;
0111     __le32 axis_desc_index;
0112 };
0113 
0114 struct scmi_msg_resp_sensor_axis_description {
0115     __le32 num_axis_flags;
0116 #define NUM_AXIS_RETURNED(x)        FIELD_GET(GENMASK(5, 0), (x))
0117 #define NUM_AXIS_REMAINING(x)       FIELD_GET(GENMASK(31, 26), (x))
0118     struct scmi_axis_descriptor {
0119         __le32 id;
0120         __le32 attributes_low;
0121 #define SUPPORTS_EXTENDED_AXIS_NAMES(x) FIELD_GET(BIT(9), (x))
0122         __le32 attributes_high;
0123         u8 name[SCMI_SHORT_NAME_MAX_SIZE];
0124         __le32 resolution;
0125         struct scmi_msg_resp_attrs attrs;
0126     } desc[];
0127 };
0128 
0129 struct scmi_msg_resp_sensor_axis_names_description {
0130     __le32 num_axis_flags;
0131     struct scmi_sensor_axis_name_descriptor {
0132         __le32 axis_id;
0133         u8 name[SCMI_MAX_STR_SIZE];
0134     } desc[];
0135 };
0136 
0137 /* Base scmi_axis_descriptor size excluding extended attrs after name */
0138 #define SCMI_MSG_RESP_AXIS_DESCR_BASE_SZ    28
0139 
0140 struct scmi_msg_sensor_list_update_intervals {
0141     __le32 id;
0142     __le32 index;
0143 };
0144 
0145 struct scmi_msg_resp_sensor_list_update_intervals {
0146     __le32 num_intervals_flags;
0147 #define NUM_INTERVALS_RETURNED(x)   FIELD_GET(GENMASK(11, 0), (x))
0148 #define SEGMENTED_INTVL_FORMAT(x)   FIELD_GET(BIT(12), (x))
0149 #define NUM_INTERVALS_REMAINING(x)  FIELD_GET(GENMASK(31, 16), (x))
0150     __le32 intervals[];
0151 };
0152 
0153 struct scmi_msg_sensor_request_notify {
0154     __le32 id;
0155     __le32 event_control;
0156 #define SENSOR_NOTIFY_ALL   BIT(0)
0157 };
0158 
0159 struct scmi_msg_set_sensor_trip_point {
0160     __le32 id;
0161     __le32 event_control;
0162 #define SENSOR_TP_EVENT_MASK    (0x3)
0163 #define SENSOR_TP_DISABLED  0x0
0164 #define SENSOR_TP_POSITIVE  0x1
0165 #define SENSOR_TP_NEGATIVE  0x2
0166 #define SENSOR_TP_BOTH      0x3
0167 #define SENSOR_TP_ID(x)     (((x) & 0xff) << 4)
0168     __le32 value_low;
0169     __le32 value_high;
0170 };
0171 
0172 struct scmi_msg_sensor_config_set {
0173     __le32 id;
0174     __le32 sensor_config;
0175 };
0176 
0177 struct scmi_msg_sensor_reading_get {
0178     __le32 id;
0179     __le32 flags;
0180 #define SENSOR_READ_ASYNC   BIT(0)
0181 };
0182 
0183 struct scmi_resp_sensor_reading_complete {
0184     __le32 id;
0185     __le32 readings_low;
0186     __le32 readings_high;
0187 };
0188 
0189 struct scmi_sensor_reading_resp {
0190     __le32 sensor_value_low;
0191     __le32 sensor_value_high;
0192     __le32 timestamp_low;
0193     __le32 timestamp_high;
0194 };
0195 
0196 struct scmi_resp_sensor_reading_complete_v3 {
0197     __le32 id;
0198     struct scmi_sensor_reading_resp readings[];
0199 };
0200 
0201 struct scmi_sensor_trip_notify_payld {
0202     __le32 agent_id;
0203     __le32 sensor_id;
0204     __le32 trip_point_desc;
0205 };
0206 
0207 struct scmi_sensor_update_notify_payld {
0208     __le32 agent_id;
0209     __le32 sensor_id;
0210     struct scmi_sensor_reading_resp readings[];
0211 };
0212 
0213 struct sensors_info {
0214     u32 version;
0215     int num_sensors;
0216     int max_requests;
0217     u64 reg_addr;
0218     u32 reg_size;
0219     struct scmi_sensor_info *sensors;
0220 };
0221 
0222 static int scmi_sensor_attributes_get(const struct scmi_protocol_handle *ph,
0223                       struct sensors_info *si)
0224 {
0225     int ret;
0226     struct scmi_xfer *t;
0227     struct scmi_msg_resp_sensor_attributes *attr;
0228 
0229     ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES,
0230                       0, sizeof(*attr), &t);
0231     if (ret)
0232         return ret;
0233 
0234     attr = t->rx.buf;
0235 
0236     ret = ph->xops->do_xfer(ph, t);
0237     if (!ret) {
0238         si->num_sensors = le16_to_cpu(attr->num_sensors);
0239         si->max_requests = attr->max_requests;
0240         si->reg_addr = le32_to_cpu(attr->reg_addr_low) |
0241                 (u64)le32_to_cpu(attr->reg_addr_high) << 32;
0242         si->reg_size = le32_to_cpu(attr->reg_size);
0243     }
0244 
0245     ph->xops->xfer_put(ph, t);
0246     return ret;
0247 }
0248 
0249 static inline void scmi_parse_range_attrs(struct scmi_range_attrs *out,
0250                       const struct scmi_msg_resp_attrs *in)
0251 {
0252     out->min_range = get_unaligned_le64((void *)&in->min_range_low);
0253     out->max_range = get_unaligned_le64((void *)&in->max_range_low);
0254 }
0255 
0256 struct scmi_sens_ipriv {
0257     void *priv;
0258     struct device *dev;
0259 };
0260 
0261 static void iter_intervals_prepare_message(void *message,
0262                        unsigned int desc_index,
0263                        const void *p)
0264 {
0265     struct scmi_msg_sensor_list_update_intervals *msg = message;
0266     const struct scmi_sensor_info *s;
0267 
0268     s = ((const struct scmi_sens_ipriv *)p)->priv;
0269     /* Set the number of sensors to be skipped/already read */
0270     msg->id = cpu_to_le32(s->id);
0271     msg->index = cpu_to_le32(desc_index);
0272 }
0273 
0274 static int iter_intervals_update_state(struct scmi_iterator_state *st,
0275                        const void *response, void *p)
0276 {
0277     u32 flags;
0278     struct scmi_sensor_info *s = ((struct scmi_sens_ipriv *)p)->priv;
0279     struct device *dev = ((struct scmi_sens_ipriv *)p)->dev;
0280     const struct scmi_msg_resp_sensor_list_update_intervals *r = response;
0281 
0282     flags = le32_to_cpu(r->num_intervals_flags);
0283     st->num_returned = NUM_INTERVALS_RETURNED(flags);
0284     st->num_remaining = NUM_INTERVALS_REMAINING(flags);
0285 
0286     /*
0287      * Max intervals is not declared previously anywhere so we
0288      * assume it's returned+remaining on first call.
0289      */
0290     if (!st->max_resources) {
0291         s->intervals.segmented = SEGMENTED_INTVL_FORMAT(flags);
0292         s->intervals.count = st->num_returned + st->num_remaining;
0293         /* segmented intervals are reported in one triplet */
0294         if (s->intervals.segmented &&
0295             (st->num_remaining || st->num_returned != 3)) {
0296             dev_err(dev,
0297                 "Sensor ID:%d advertises an invalid segmented interval (%d)\n",
0298                 s->id, s->intervals.count);
0299             s->intervals.segmented = false;
0300             s->intervals.count = 0;
0301             return -EINVAL;
0302         }
0303         /* Direct allocation when exceeding pre-allocated */
0304         if (s->intervals.count >= SCMI_MAX_PREALLOC_POOL) {
0305             s->intervals.desc =
0306                 devm_kcalloc(dev,
0307                          s->intervals.count,
0308                          sizeof(*s->intervals.desc),
0309                          GFP_KERNEL);
0310             if (!s->intervals.desc) {
0311                 s->intervals.segmented = false;
0312                 s->intervals.count = 0;
0313                 return -ENOMEM;
0314             }
0315         }
0316 
0317         st->max_resources = s->intervals.count;
0318     }
0319 
0320     return 0;
0321 }
0322 
0323 static int
0324 iter_intervals_process_response(const struct scmi_protocol_handle *ph,
0325                 const void *response,
0326                 struct scmi_iterator_state *st, void *p)
0327 {
0328     const struct scmi_msg_resp_sensor_list_update_intervals *r = response;
0329     struct scmi_sensor_info *s = ((struct scmi_sens_ipriv *)p)->priv;
0330 
0331     s->intervals.desc[st->desc_index + st->loop_idx] =
0332         le32_to_cpu(r->intervals[st->loop_idx]);
0333 
0334     return 0;
0335 }
0336 
0337 static int scmi_sensor_update_intervals(const struct scmi_protocol_handle *ph,
0338                     struct scmi_sensor_info *s)
0339 {
0340     void *iter;
0341     struct scmi_iterator_ops ops = {
0342         .prepare_message = iter_intervals_prepare_message,
0343         .update_state = iter_intervals_update_state,
0344         .process_response = iter_intervals_process_response,
0345     };
0346     struct scmi_sens_ipriv upriv = {
0347         .priv = s,
0348         .dev = ph->dev,
0349     };
0350 
0351     iter = ph->hops->iter_response_init(ph, &ops, s->intervals.count,
0352                         SENSOR_LIST_UPDATE_INTERVALS,
0353                         sizeof(struct scmi_msg_sensor_list_update_intervals),
0354                         &upriv);
0355     if (IS_ERR(iter))
0356         return PTR_ERR(iter);
0357 
0358     return ph->hops->iter_response_run(iter);
0359 }
0360 
0361 struct scmi_apriv {
0362     bool any_axes_support_extended_names;
0363     struct scmi_sensor_info *s;
0364 };
0365 
0366 static void iter_axes_desc_prepare_message(void *message,
0367                        const unsigned int desc_index,
0368                        const void *priv)
0369 {
0370     struct scmi_msg_sensor_axis_description_get *msg = message;
0371     const struct scmi_apriv *apriv = priv;
0372 
0373     /* Set the number of sensors to be skipped/already read */
0374     msg->id = cpu_to_le32(apriv->s->id);
0375     msg->axis_desc_index = cpu_to_le32(desc_index);
0376 }
0377 
0378 static int
0379 iter_axes_desc_update_state(struct scmi_iterator_state *st,
0380                 const void *response, void *priv)
0381 {
0382     u32 flags;
0383     const struct scmi_msg_resp_sensor_axis_description *r = response;
0384 
0385     flags = le32_to_cpu(r->num_axis_flags);
0386     st->num_returned = NUM_AXIS_RETURNED(flags);
0387     st->num_remaining = NUM_AXIS_REMAINING(flags);
0388     st->priv = (void *)&r->desc[0];
0389 
0390     return 0;
0391 }
0392 
0393 static int
0394 iter_axes_desc_process_response(const struct scmi_protocol_handle *ph,
0395                 const void *response,
0396                 struct scmi_iterator_state *st, void *priv)
0397 {
0398     u32 attrh, attrl;
0399     struct scmi_sensor_axis_info *a;
0400     size_t dsize = SCMI_MSG_RESP_AXIS_DESCR_BASE_SZ;
0401     struct scmi_apriv *apriv = priv;
0402     const struct scmi_axis_descriptor *adesc = st->priv;
0403 
0404     attrl = le32_to_cpu(adesc->attributes_low);
0405     if (SUPPORTS_EXTENDED_AXIS_NAMES(attrl))
0406         apriv->any_axes_support_extended_names = true;
0407 
0408     a = &apriv->s->axis[st->desc_index + st->loop_idx];
0409     a->id = le32_to_cpu(adesc->id);
0410     a->extended_attrs = SUPPORTS_EXTEND_ATTRS(attrl);
0411 
0412     attrh = le32_to_cpu(adesc->attributes_high);
0413     a->scale = S32_EXT(SENSOR_SCALE(attrh));
0414     a->type = SENSOR_TYPE(attrh);
0415     strscpy(a->name, adesc->name, SCMI_SHORT_NAME_MAX_SIZE);
0416 
0417     if (a->extended_attrs) {
0418         unsigned int ares = le32_to_cpu(adesc->resolution);
0419 
0420         a->resolution = SENSOR_RES(ares);
0421         a->exponent = S32_EXT(SENSOR_RES_EXP(ares));
0422         dsize += sizeof(adesc->resolution);
0423 
0424         scmi_parse_range_attrs(&a->attrs, &adesc->attrs);
0425         dsize += sizeof(adesc->attrs);
0426     }
0427     st->priv = ((u8 *)adesc + dsize);
0428 
0429     return 0;
0430 }
0431 
0432 static int
0433 iter_axes_extended_name_update_state(struct scmi_iterator_state *st,
0434                      const void *response, void *priv)
0435 {
0436     u32 flags;
0437     const struct scmi_msg_resp_sensor_axis_names_description *r = response;
0438 
0439     flags = le32_to_cpu(r->num_axis_flags);
0440     st->num_returned = NUM_AXIS_RETURNED(flags);
0441     st->num_remaining = NUM_AXIS_REMAINING(flags);
0442     st->priv = (void *)&r->desc[0];
0443 
0444     return 0;
0445 }
0446 
0447 static int
0448 iter_axes_extended_name_process_response(const struct scmi_protocol_handle *ph,
0449                      const void *response,
0450                      struct scmi_iterator_state *st,
0451                      void *priv)
0452 {
0453     struct scmi_sensor_axis_info *a;
0454     const struct scmi_apriv *apriv = priv;
0455     struct scmi_sensor_axis_name_descriptor *adesc = st->priv;
0456     u32 axis_id = le32_to_cpu(adesc->axis_id);
0457 
0458     if (axis_id >= st->max_resources)
0459         return -EPROTO;
0460 
0461     /*
0462      * Pick the corresponding descriptor based on the axis_id embedded
0463      * in the reply since the list of axes supporting extended names
0464      * can be a subset of all the axes.
0465      */
0466     a = &apriv->s->axis[axis_id];
0467     strscpy(a->name, adesc->name, SCMI_MAX_STR_SIZE);
0468     st->priv = ++adesc;
0469 
0470     return 0;
0471 }
0472 
0473 static int
0474 scmi_sensor_axis_extended_names_get(const struct scmi_protocol_handle *ph,
0475                     struct scmi_sensor_info *s)
0476 {
0477     int ret;
0478     void *iter;
0479     struct scmi_iterator_ops ops = {
0480         .prepare_message = iter_axes_desc_prepare_message,
0481         .update_state = iter_axes_extended_name_update_state,
0482         .process_response = iter_axes_extended_name_process_response,
0483     };
0484     struct scmi_apriv apriv = {
0485         .any_axes_support_extended_names = false,
0486         .s = s,
0487     };
0488 
0489     iter = ph->hops->iter_response_init(ph, &ops, s->num_axis,
0490                         SENSOR_AXIS_NAME_GET,
0491                         sizeof(struct scmi_msg_sensor_axis_description_get),
0492                         &apriv);
0493     if (IS_ERR(iter))
0494         return PTR_ERR(iter);
0495 
0496     /*
0497      * Do not cause whole protocol initialization failure when failing to
0498      * get extended names for axes.
0499      */
0500     ret = ph->hops->iter_response_run(iter);
0501     if (ret)
0502         dev_warn(ph->dev,
0503              "Failed to get axes extended names for %s (ret:%d).\n",
0504              s->name, ret);
0505 
0506     return 0;
0507 }
0508 
0509 static int scmi_sensor_axis_description(const struct scmi_protocol_handle *ph,
0510                     struct scmi_sensor_info *s,
0511                     u32 version)
0512 {
0513     int ret;
0514     void *iter;
0515     struct scmi_iterator_ops ops = {
0516         .prepare_message = iter_axes_desc_prepare_message,
0517         .update_state = iter_axes_desc_update_state,
0518         .process_response = iter_axes_desc_process_response,
0519     };
0520     struct scmi_apriv apriv = {
0521         .any_axes_support_extended_names = false,
0522         .s = s,
0523     };
0524 
0525     s->axis = devm_kcalloc(ph->dev, s->num_axis,
0526                    sizeof(*s->axis), GFP_KERNEL);
0527     if (!s->axis)
0528         return -ENOMEM;
0529 
0530     iter = ph->hops->iter_response_init(ph, &ops, s->num_axis,
0531                         SENSOR_AXIS_DESCRIPTION_GET,
0532                         sizeof(struct scmi_msg_sensor_axis_description_get),
0533                         &apriv);
0534     if (IS_ERR(iter))
0535         return PTR_ERR(iter);
0536 
0537     ret = ph->hops->iter_response_run(iter);
0538     if (ret)
0539         return ret;
0540 
0541     if (PROTOCOL_REV_MAJOR(version) >= 0x3 &&
0542         apriv.any_axes_support_extended_names)
0543         ret = scmi_sensor_axis_extended_names_get(ph, s);
0544 
0545     return ret;
0546 }
0547 
0548 static void iter_sens_descr_prepare_message(void *message,
0549                         unsigned int desc_index,
0550                         const void *priv)
0551 {
0552     struct scmi_msg_sensor_description *msg = message;
0553 
0554     msg->desc_index = cpu_to_le32(desc_index);
0555 }
0556 
0557 static int iter_sens_descr_update_state(struct scmi_iterator_state *st,
0558                     const void *response, void *priv)
0559 {
0560     const struct scmi_msg_resp_sensor_description *r = response;
0561 
0562     st->num_returned = le16_to_cpu(r->num_returned);
0563     st->num_remaining = le16_to_cpu(r->num_remaining);
0564     st->priv = (void *)&r->desc[0];
0565 
0566     return 0;
0567 }
0568 
0569 static int
0570 iter_sens_descr_process_response(const struct scmi_protocol_handle *ph,
0571                  const void *response,
0572                  struct scmi_iterator_state *st, void *priv)
0573 
0574 {
0575     int ret = 0;
0576     u32 attrh, attrl;
0577     size_t dsize = SCMI_MSG_RESP_SENS_DESCR_BASE_SZ;
0578     struct scmi_sensor_info *s;
0579     struct sensors_info *si = priv;
0580     const struct scmi_sensor_descriptor *sdesc = st->priv;
0581 
0582     s = &si->sensors[st->desc_index + st->loop_idx];
0583     s->id = le32_to_cpu(sdesc->id);
0584 
0585     attrl = le32_to_cpu(sdesc->attributes_low);
0586     /* common bitfields parsing */
0587     s->async = SUPPORTS_ASYNC_READ(attrl);
0588     s->num_trip_points = NUM_TRIP_POINTS(attrl);
0589     /**
0590      * only SCMIv3.0 specific bitfield below.
0591      * Such bitfields are assumed to be zeroed on non
0592      * relevant fw versions...assuming fw not buggy !
0593      */
0594     s->update = SUPPORTS_UPDATE_NOTIFY(attrl);
0595     s->timestamped = SUPPORTS_TIMESTAMP(attrl);
0596     if (s->timestamped)
0597         s->tstamp_scale = S32_EXT(SENSOR_TSTAMP_EXP(attrl));
0598     s->extended_scalar_attrs = SUPPORTS_EXTEND_ATTRS(attrl);
0599 
0600     attrh = le32_to_cpu(sdesc->attributes_high);
0601     /* common bitfields parsing */
0602     s->scale = S32_EXT(SENSOR_SCALE(attrh));
0603     s->type = SENSOR_TYPE(attrh);
0604     /* Use pre-allocated pool wherever possible */
0605     s->intervals.desc = s->intervals.prealloc_pool;
0606     if (si->version == SCMIv2_SENSOR_PROTOCOL) {
0607         s->intervals.segmented = false;
0608         s->intervals.count = 1;
0609         /*
0610          * Convert SCMIv2.0 update interval format to
0611          * SCMIv3.0 to be used as the common exposed
0612          * descriptor, accessible via common macros.
0613          */
0614         s->intervals.desc[0] = (SENSOR_UPDATE_BASE(attrh) << 5) |
0615                     SENSOR_UPDATE_SCALE(attrh);
0616     } else {
0617         /*
0618          * From SCMIv3.0 update intervals are retrieved
0619          * via a dedicated (optional) command.
0620          * Since the command is optional, on error carry
0621          * on without any update interval.
0622          */
0623         if (scmi_sensor_update_intervals(ph, s))
0624             dev_dbg(ph->dev,
0625                 "Update Intervals not available for sensor ID:%d\n",
0626                 s->id);
0627     }
0628     /**
0629      * only > SCMIv2.0 specific bitfield below.
0630      * Such bitfields are assumed to be zeroed on non
0631      * relevant fw versions...assuming fw not buggy !
0632      */
0633     s->num_axis = min_t(unsigned int,
0634                 SUPPORTS_AXIS(attrh) ?
0635                 SENSOR_AXIS_NUMBER(attrh) : 0,
0636                 SCMI_MAX_NUM_SENSOR_AXIS);
0637     strscpy(s->name, sdesc->name, SCMI_SHORT_NAME_MAX_SIZE);
0638 
0639     /*
0640      * If supported overwrite short name with the extended
0641      * one; on error just carry on and use already provided
0642      * short name.
0643      */
0644     if (PROTOCOL_REV_MAJOR(si->version) >= 0x3 &&
0645         SUPPORTS_EXTENDED_NAMES(attrl))
0646         ph->hops->extended_name_get(ph, SENSOR_NAME_GET, s->id,
0647                         s->name, SCMI_MAX_STR_SIZE);
0648 
0649     if (s->extended_scalar_attrs) {
0650         s->sensor_power = le32_to_cpu(sdesc->power);
0651         dsize += sizeof(sdesc->power);
0652 
0653         /* Only for sensors reporting scalar values */
0654         if (s->num_axis == 0) {
0655             unsigned int sres = le32_to_cpu(sdesc->resolution);
0656 
0657             s->resolution = SENSOR_RES(sres);
0658             s->exponent = S32_EXT(SENSOR_RES_EXP(sres));
0659             dsize += sizeof(sdesc->resolution);
0660 
0661             scmi_parse_range_attrs(&s->scalar_attrs,
0662                            &sdesc->scalar_attrs);
0663             dsize += sizeof(sdesc->scalar_attrs);
0664         }
0665     }
0666 
0667     if (s->num_axis > 0)
0668         ret = scmi_sensor_axis_description(ph, s, si->version);
0669 
0670     st->priv = ((u8 *)sdesc + dsize);
0671 
0672     return ret;
0673 }
0674 
0675 static int scmi_sensor_description_get(const struct scmi_protocol_handle *ph,
0676                        struct sensors_info *si)
0677 {
0678     void *iter;
0679     struct scmi_iterator_ops ops = {
0680         .prepare_message = iter_sens_descr_prepare_message,
0681         .update_state = iter_sens_descr_update_state,
0682         .process_response = iter_sens_descr_process_response,
0683     };
0684 
0685     iter = ph->hops->iter_response_init(ph, &ops, si->num_sensors,
0686                         SENSOR_DESCRIPTION_GET,
0687                         sizeof(__le32), si);
0688     if (IS_ERR(iter))
0689         return PTR_ERR(iter);
0690 
0691     return ph->hops->iter_response_run(iter);
0692 }
0693 
0694 static inline int
0695 scmi_sensor_request_notify(const struct scmi_protocol_handle *ph, u32 sensor_id,
0696                u8 message_id, bool enable)
0697 {
0698     int ret;
0699     u32 evt_cntl = enable ? SENSOR_NOTIFY_ALL : 0;
0700     struct scmi_xfer *t;
0701     struct scmi_msg_sensor_request_notify *cfg;
0702 
0703     ret = ph->xops->xfer_get_init(ph, message_id, sizeof(*cfg), 0, &t);
0704     if (ret)
0705         return ret;
0706 
0707     cfg = t->tx.buf;
0708     cfg->id = cpu_to_le32(sensor_id);
0709     cfg->event_control = cpu_to_le32(evt_cntl);
0710 
0711     ret = ph->xops->do_xfer(ph, t);
0712 
0713     ph->xops->xfer_put(ph, t);
0714     return ret;
0715 }
0716 
0717 static int scmi_sensor_trip_point_notify(const struct scmi_protocol_handle *ph,
0718                      u32 sensor_id, bool enable)
0719 {
0720     return scmi_sensor_request_notify(ph, sensor_id,
0721                       SENSOR_TRIP_POINT_NOTIFY,
0722                       enable);
0723 }
0724 
0725 static int
0726 scmi_sensor_continuous_update_notify(const struct scmi_protocol_handle *ph,
0727                      u32 sensor_id, bool enable)
0728 {
0729     return scmi_sensor_request_notify(ph, sensor_id,
0730                       SENSOR_CONTINUOUS_UPDATE_NOTIFY,
0731                       enable);
0732 }
0733 
0734 static int
0735 scmi_sensor_trip_point_config(const struct scmi_protocol_handle *ph,
0736                   u32 sensor_id, u8 trip_id, u64 trip_value)
0737 {
0738     int ret;
0739     u32 evt_cntl = SENSOR_TP_BOTH;
0740     struct scmi_xfer *t;
0741     struct scmi_msg_set_sensor_trip_point *trip;
0742 
0743     ret = ph->xops->xfer_get_init(ph, SENSOR_TRIP_POINT_CONFIG,
0744                       sizeof(*trip), 0, &t);
0745     if (ret)
0746         return ret;
0747 
0748     trip = t->tx.buf;
0749     trip->id = cpu_to_le32(sensor_id);
0750     trip->event_control = cpu_to_le32(evt_cntl | SENSOR_TP_ID(trip_id));
0751     trip->value_low = cpu_to_le32(trip_value & 0xffffffff);
0752     trip->value_high = cpu_to_le32(trip_value >> 32);
0753 
0754     ret = ph->xops->do_xfer(ph, t);
0755 
0756     ph->xops->xfer_put(ph, t);
0757     return ret;
0758 }
0759 
0760 static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph,
0761                   u32 sensor_id, u32 *sensor_config)
0762 {
0763     int ret;
0764     struct scmi_xfer *t;
0765     struct sensors_info *si = ph->get_priv(ph);
0766 
0767     if (sensor_id >= si->num_sensors)
0768         return -EINVAL;
0769 
0770     ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_GET,
0771                       sizeof(__le32), sizeof(__le32), &t);
0772     if (ret)
0773         return ret;
0774 
0775     put_unaligned_le32(sensor_id, t->tx.buf);
0776     ret = ph->xops->do_xfer(ph, t);
0777     if (!ret) {
0778         struct scmi_sensor_info *s = si->sensors + sensor_id;
0779 
0780         *sensor_config = get_unaligned_le64(t->rx.buf);
0781         s->sensor_config = *sensor_config;
0782     }
0783 
0784     ph->xops->xfer_put(ph, t);
0785     return ret;
0786 }
0787 
0788 static int scmi_sensor_config_set(const struct scmi_protocol_handle *ph,
0789                   u32 sensor_id, u32 sensor_config)
0790 {
0791     int ret;
0792     struct scmi_xfer *t;
0793     struct scmi_msg_sensor_config_set *msg;
0794     struct sensors_info *si = ph->get_priv(ph);
0795 
0796     if (sensor_id >= si->num_sensors)
0797         return -EINVAL;
0798 
0799     ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_SET,
0800                       sizeof(*msg), 0, &t);
0801     if (ret)
0802         return ret;
0803 
0804     msg = t->tx.buf;
0805     msg->id = cpu_to_le32(sensor_id);
0806     msg->sensor_config = cpu_to_le32(sensor_config);
0807 
0808     ret = ph->xops->do_xfer(ph, t);
0809     if (!ret) {
0810         struct scmi_sensor_info *s = si->sensors + sensor_id;
0811 
0812         s->sensor_config = sensor_config;
0813     }
0814 
0815     ph->xops->xfer_put(ph, t);
0816     return ret;
0817 }
0818 
0819 /**
0820  * scmi_sensor_reading_get  - Read scalar sensor value
0821  * @ph: Protocol handle
0822  * @sensor_id: Sensor ID
0823  * @value: The 64bit value sensor reading
0824  *
0825  * This function returns a single 64 bit reading value representing the sensor
0826  * value; if the platform SCMI Protocol implementation and the sensor support
0827  * multiple axis and timestamped-reads, this just returns the first axis while
0828  * dropping the timestamp value.
0829  * Use instead the @scmi_sensor_reading_get_timestamped to retrieve the array of
0830  * timestamped multi-axis values.
0831  *
0832  * Return: 0 on Success
0833  */
0834 static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph,
0835                    u32 sensor_id, u64 *value)
0836 {
0837     int ret;
0838     struct scmi_xfer *t;
0839     struct scmi_msg_sensor_reading_get *sensor;
0840     struct scmi_sensor_info *s;
0841     struct sensors_info *si = ph->get_priv(ph);
0842 
0843     if (sensor_id >= si->num_sensors)
0844         return -EINVAL;
0845 
0846     ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET,
0847                       sizeof(*sensor), 0, &t);
0848     if (ret)
0849         return ret;
0850 
0851     sensor = t->tx.buf;
0852     sensor->id = cpu_to_le32(sensor_id);
0853     s = si->sensors + sensor_id;
0854     if (s->async) {
0855         sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
0856         ret = ph->xops->do_xfer_with_response(ph, t);
0857         if (!ret) {
0858             struct scmi_resp_sensor_reading_complete *resp;
0859 
0860             resp = t->rx.buf;
0861             if (le32_to_cpu(resp->id) == sensor_id)
0862                 *value =
0863                     get_unaligned_le64(&resp->readings_low);
0864             else
0865                 ret = -EPROTO;
0866         }
0867     } else {
0868         sensor->flags = cpu_to_le32(0);
0869         ret = ph->xops->do_xfer(ph, t);
0870         if (!ret)
0871             *value = get_unaligned_le64(t->rx.buf);
0872     }
0873 
0874     ph->xops->xfer_put(ph, t);
0875     return ret;
0876 }
0877 
0878 static inline void
0879 scmi_parse_sensor_readings(struct scmi_sensor_reading *out,
0880                const struct scmi_sensor_reading_resp *in)
0881 {
0882     out->value = get_unaligned_le64((void *)&in->sensor_value_low);
0883     out->timestamp = get_unaligned_le64((void *)&in->timestamp_low);
0884 }
0885 
0886 /**
0887  * scmi_sensor_reading_get_timestamped  - Read multiple-axis timestamped values
0888  * @ph: Protocol handle
0889  * @sensor_id: Sensor ID
0890  * @count: The length of the provided @readings array
0891  * @readings: An array of elements each representing a timestamped per-axis
0892  *        reading of type @struct scmi_sensor_reading.
0893  *        Returned readings are ordered as the @axis descriptors array
0894  *        included in @struct scmi_sensor_info and the max number of
0895  *        returned elements is min(@count, @num_axis); ideally the provided
0896  *        array should be of length @count equal to @num_axis.
0897  *
0898  * Return: 0 on Success
0899  */
0900 static int
0901 scmi_sensor_reading_get_timestamped(const struct scmi_protocol_handle *ph,
0902                     u32 sensor_id, u8 count,
0903                     struct scmi_sensor_reading *readings)
0904 {
0905     int ret;
0906     struct scmi_xfer *t;
0907     struct scmi_msg_sensor_reading_get *sensor;
0908     struct scmi_sensor_info *s;
0909     struct sensors_info *si = ph->get_priv(ph);
0910 
0911     if (sensor_id >= si->num_sensors)
0912         return -EINVAL;
0913 
0914     s = si->sensors + sensor_id;
0915     if (!count || !readings ||
0916         (!s->num_axis && count > 1) || (s->num_axis && count > s->num_axis))
0917         return -EINVAL;
0918 
0919     ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET,
0920                       sizeof(*sensor), 0, &t);
0921     if (ret)
0922         return ret;
0923 
0924     sensor = t->tx.buf;
0925     sensor->id = cpu_to_le32(sensor_id);
0926     if (s->async) {
0927         sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
0928         ret = ph->xops->do_xfer_with_response(ph, t);
0929         if (!ret) {
0930             int i;
0931             struct scmi_resp_sensor_reading_complete_v3 *resp;
0932 
0933             resp = t->rx.buf;
0934             /* Retrieve only the number of requested axis anyway */
0935             if (le32_to_cpu(resp->id) == sensor_id)
0936                 for (i = 0; i < count; i++)
0937                     scmi_parse_sensor_readings(&readings[i],
0938                                    &resp->readings[i]);
0939             else
0940                 ret = -EPROTO;
0941         }
0942     } else {
0943         sensor->flags = cpu_to_le32(0);
0944         ret = ph->xops->do_xfer(ph, t);
0945         if (!ret) {
0946             int i;
0947             struct scmi_sensor_reading_resp *resp_readings;
0948 
0949             resp_readings = t->rx.buf;
0950             for (i = 0; i < count; i++)
0951                 scmi_parse_sensor_readings(&readings[i],
0952                                &resp_readings[i]);
0953         }
0954     }
0955 
0956     ph->xops->xfer_put(ph, t);
0957     return ret;
0958 }
0959 
0960 static const struct scmi_sensor_info *
0961 scmi_sensor_info_get(const struct scmi_protocol_handle *ph, u32 sensor_id)
0962 {
0963     struct sensors_info *si = ph->get_priv(ph);
0964 
0965     if (sensor_id >= si->num_sensors)
0966         return NULL;
0967 
0968     return si->sensors + sensor_id;
0969 }
0970 
0971 static int scmi_sensor_count_get(const struct scmi_protocol_handle *ph)
0972 {
0973     struct sensors_info *si = ph->get_priv(ph);
0974 
0975     return si->num_sensors;
0976 }
0977 
0978 static const struct scmi_sensor_proto_ops sensor_proto_ops = {
0979     .count_get = scmi_sensor_count_get,
0980     .info_get = scmi_sensor_info_get,
0981     .trip_point_config = scmi_sensor_trip_point_config,
0982     .reading_get = scmi_sensor_reading_get,
0983     .reading_get_timestamped = scmi_sensor_reading_get_timestamped,
0984     .config_get = scmi_sensor_config_get,
0985     .config_set = scmi_sensor_config_set,
0986 };
0987 
0988 static int scmi_sensor_set_notify_enabled(const struct scmi_protocol_handle *ph,
0989                       u8 evt_id, u32 src_id, bool enable)
0990 {
0991     int ret;
0992 
0993     switch (evt_id) {
0994     case SCMI_EVENT_SENSOR_TRIP_POINT_EVENT:
0995         ret = scmi_sensor_trip_point_notify(ph, src_id, enable);
0996         break;
0997     case SCMI_EVENT_SENSOR_UPDATE:
0998         ret = scmi_sensor_continuous_update_notify(ph, src_id, enable);
0999         break;
1000     default:
1001         ret = -EINVAL;
1002         break;
1003     }
1004 
1005     if (ret)
1006         pr_debug("FAIL_ENABLED - evt[%X] dom[%d] - ret:%d\n",
1007              evt_id, src_id, ret);
1008 
1009     return ret;
1010 }
1011 
1012 static void *
1013 scmi_sensor_fill_custom_report(const struct scmi_protocol_handle *ph,
1014                    u8 evt_id, ktime_t timestamp,
1015                    const void *payld, size_t payld_sz,
1016                    void *report, u32 *src_id)
1017 {
1018     void *rep = NULL;
1019 
1020     switch (evt_id) {
1021     case SCMI_EVENT_SENSOR_TRIP_POINT_EVENT:
1022     {
1023         const struct scmi_sensor_trip_notify_payld *p = payld;
1024         struct scmi_sensor_trip_point_report *r = report;
1025 
1026         if (sizeof(*p) != payld_sz)
1027             break;
1028 
1029         r->timestamp = timestamp;
1030         r->agent_id = le32_to_cpu(p->agent_id);
1031         r->sensor_id = le32_to_cpu(p->sensor_id);
1032         r->trip_point_desc = le32_to_cpu(p->trip_point_desc);
1033         *src_id = r->sensor_id;
1034         rep = r;
1035         break;
1036     }
1037     case SCMI_EVENT_SENSOR_UPDATE:
1038     {
1039         int i;
1040         struct scmi_sensor_info *s;
1041         const struct scmi_sensor_update_notify_payld *p = payld;
1042         struct scmi_sensor_update_report *r = report;
1043         struct sensors_info *sinfo = ph->get_priv(ph);
1044 
1045         /* payld_sz is variable for this event */
1046         r->sensor_id = le32_to_cpu(p->sensor_id);
1047         if (r->sensor_id >= sinfo->num_sensors)
1048             break;
1049         r->timestamp = timestamp;
1050         r->agent_id = le32_to_cpu(p->agent_id);
1051         s = &sinfo->sensors[r->sensor_id];
1052         /*
1053          * The generated report r (@struct scmi_sensor_update_report)
1054          * was pre-allocated to contain up to SCMI_MAX_NUM_SENSOR_AXIS
1055          * readings: here it is filled with the effective @num_axis
1056          * readings defined for this sensor or 1 for scalar sensors.
1057          */
1058         r->readings_count = s->num_axis ?: 1;
1059         for (i = 0; i < r->readings_count; i++)
1060             scmi_parse_sensor_readings(&r->readings[i],
1061                            &p->readings[i]);
1062         *src_id = r->sensor_id;
1063         rep = r;
1064         break;
1065     }
1066     default:
1067         break;
1068     }
1069 
1070     return rep;
1071 }
1072 
1073 static int scmi_sensor_get_num_sources(const struct scmi_protocol_handle *ph)
1074 {
1075     struct sensors_info *si = ph->get_priv(ph);
1076 
1077     return si->num_sensors;
1078 }
1079 
1080 static const struct scmi_event sensor_events[] = {
1081     {
1082         .id = SCMI_EVENT_SENSOR_TRIP_POINT_EVENT,
1083         .max_payld_sz = sizeof(struct scmi_sensor_trip_notify_payld),
1084         .max_report_sz = sizeof(struct scmi_sensor_trip_point_report),
1085     },
1086     {
1087         .id = SCMI_EVENT_SENSOR_UPDATE,
1088         .max_payld_sz =
1089             sizeof(struct scmi_sensor_update_notify_payld) +
1090              SCMI_MAX_NUM_SENSOR_AXIS *
1091              sizeof(struct scmi_sensor_reading_resp),
1092         .max_report_sz = sizeof(struct scmi_sensor_update_report) +
1093                   SCMI_MAX_NUM_SENSOR_AXIS *
1094                   sizeof(struct scmi_sensor_reading),
1095     },
1096 };
1097 
1098 static const struct scmi_event_ops sensor_event_ops = {
1099     .get_num_sources = scmi_sensor_get_num_sources,
1100     .set_notify_enabled = scmi_sensor_set_notify_enabled,
1101     .fill_custom_report = scmi_sensor_fill_custom_report,
1102 };
1103 
1104 static const struct scmi_protocol_events sensor_protocol_events = {
1105     .queue_sz = SCMI_PROTO_QUEUE_SZ,
1106     .ops = &sensor_event_ops,
1107     .evts = sensor_events,
1108     .num_events = ARRAY_SIZE(sensor_events),
1109 };
1110 
1111 static int scmi_sensors_protocol_init(const struct scmi_protocol_handle *ph)
1112 {
1113     u32 version;
1114     int ret;
1115     struct sensors_info *sinfo;
1116 
1117     ret = ph->xops->version_get(ph, &version);
1118     if (ret)
1119         return ret;
1120 
1121     dev_dbg(ph->dev, "Sensor Version %d.%d\n",
1122         PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
1123 
1124     sinfo = devm_kzalloc(ph->dev, sizeof(*sinfo), GFP_KERNEL);
1125     if (!sinfo)
1126         return -ENOMEM;
1127     sinfo->version = version;
1128 
1129     ret = scmi_sensor_attributes_get(ph, sinfo);
1130     if (ret)
1131         return ret;
1132     sinfo->sensors = devm_kcalloc(ph->dev, sinfo->num_sensors,
1133                       sizeof(*sinfo->sensors), GFP_KERNEL);
1134     if (!sinfo->sensors)
1135         return -ENOMEM;
1136 
1137     ret = scmi_sensor_description_get(ph, sinfo);
1138     if (ret)
1139         return ret;
1140 
1141     return ph->set_priv(ph, sinfo);
1142 }
1143 
1144 static const struct scmi_protocol scmi_sensors = {
1145     .id = SCMI_PROTOCOL_SENSOR,
1146     .owner = THIS_MODULE,
1147     .instance_init = &scmi_sensors_protocol_init,
1148     .ops = &sensor_proto_ops,
1149     .events = &sensor_protocol_events,
1150 };
1151 
1152 DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(sensors, scmi_sensors)