On Saturday 20 August 2016 04:21 AM, Nishanth Menon wrote:
> Texas Instrument's System Control Interface (TI-SCI) Message Protocol
> is used in Texas Instrument's System on Chip (SoC) such as those
> in keystone family K2G SoC to communicate between various compute
> processors with a central system controller entity.
> 
> TI-SCI message protocol provides support for management of various
> hardware entitites within the SoC. Add support driver to allow
> communication with system controller entity within the SoC using the
> mailbox client.
> 
> We introduce the fundamental device management capability support to
> the driver protocol as part of this change.
> 
> [d-gerl...@ti.com: Contributed device reset handling]
> Signed-off-by: Dave Gerlach <d-gerl...@ti.com>
> Signed-off-by: Nishanth Menon <n...@ti.com>
> ---
>  drivers/firmware/ti_sci.c              | 433 
> +++++++++++++++++++++++++++++++++
>  drivers/firmware/ti_sci.h              |  98 ++++++++
>  include/linux/soc/ti/ti_sci_protocol.h |  91 +++++++
>  3 files changed, 622 insertions(+)
> 
> diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
> index 4580c29dcb52..e0e286e76095 100644
> --- a/drivers/firmware/ti_sci.c
> +++ b/drivers/firmware/ti_sci.c
> @@ -496,6 +496,437 @@ fail:
>  }
>  
>  /**
> + * tis_sci_is_response_ack() - Generic ACK/NACK message checkup
> + * @r:       pointer to response buffer
> + *
> + * Return: true if the response was an ACK, else returns false.
> + */
> +static inline bool tis_sci_is_response_ack(void *r)

May be just ti_sci_is_response_ack() to be consistent? or you wanted to
keep it tis_sci* ?

> +{
> +     struct ti_sci_msg_hdr *hdr = r;
> +
> +     return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
> +}
> +
> +/**
> + * ti_sci_set_device_state() - Set device state helper
> + * @handle:  pointer to TI SCI handle
> + * @id:              Device identifier
> + * @flags:   flags to setup for the device
> + * @state:   State to move the device to
> + *
> + * Return: 0 if all went well, else returns appropriate error value.
> + */
> +static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
> +                                u32 id, u32 flags, u8 state)
> +{
> +     struct ti_sci_info *info;
> +     struct ti_sci_msg_req_set_device_state *req;
> +     struct ti_sci_msg_hdr *resp;
> +     struct ti_sci_xfer *xfer;
> +     struct device *dev;
> +     int ret = 0;
> +
> +     if (IS_ERR(handle))
> +             return PTR_ERR(handle);
> +     if (!handle)
> +             return -EINVAL;
> +
> +     info = handle_to_ti_sci_info(handle);
> +     dev = info->dev;
> +
> +     xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
> +                                flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
> +                                sizeof(*req), sizeof(*resp));
> +     if (IS_ERR(xfer)) {
> +             ret = PTR_ERR(xfer);
> +             dev_err(dev, "Message alloc failed(%d)\n", ret);
> +             return ret;
> +     }
> +     req = (struct ti_sci_msg_req_set_device_state *)xfer->xfer_buf;
> +     req->id = id;
> +     req->state = state;
> +
> +     ret = ti_sci_do_xfer(info, xfer);
> +     if (ret) {
> +             dev_err(dev, "Mbox send fail %d\n", ret);
> +             goto fail;
> +     }
> +
> +     resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
> +
> +     ret = tis_sci_is_response_ack(resp) ? 0 : -ENODEV;
> +
> +fail:
> +     ti_sci_put_one_xfer(&info->minfo, xfer);
> +
> +     return ret;
> +}
> +
> +/**
> + * ti_sci_get_device_state() - Get device state helper
> + * @handle:  Handle to the device
> + * @id:              Device Identifier
> + * @clcnt:   Pointer to Context Loss Count
> + * @resets:  pointer to resets
> + * @p_state: pointer to p_state
> + * @c_state: pointer to c_state
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
> +                                u32 id,  u32 *clcnt,  u32 *resets,
> +                                 u8 *p_state,  u8 *c_state)
> +{
> +     struct ti_sci_info *info;
> +     struct ti_sci_msg_req_get_device_state *req;
> +     struct ti_sci_msg_resp_get_device_state *resp;
> +     struct ti_sci_xfer *xfer;
> +     struct device *dev;
> +     int ret = 0;
> +
> +     if (IS_ERR(handle))
> +             return PTR_ERR(handle);
> +     if (!handle)
> +             return -EINVAL;
> +
> +     if (!clcnt && !resets && !p_state && !c_state)
> +             return -EINVAL;
> +
> +     info = handle_to_ti_sci_info(handle);
> +     dev = info->dev;
> +
> +     /* Response is expected, so need of any flags */
                                                        ^^ no*

Thanks and regards,
Lokesh

> +     xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE,
> +                                0, sizeof(*req), sizeof(*resp));
> +     if (IS_ERR(xfer)) {
> +             ret = PTR_ERR(xfer);
> +             dev_err(dev, "Message alloc failed(%d)\n", ret);
> +             return ret;
> +     }
> +     req = (struct ti_sci_msg_req_get_device_state *)xfer->xfer_buf;
> +     req->id = id;
> +
> +     ret = ti_sci_do_xfer(info, xfer);
> +     if (ret) {
> +             dev_err(dev, "Mbox send fail %d\n", ret);
> +             goto fail;
> +     }
> +
> +     resp = (struct ti_sci_msg_resp_get_device_state *)xfer->xfer_buf;
> +     if (!tis_sci_is_response_ack(resp)) {
> +             ret = -ENODEV;
> +             goto fail;
> +     }
> +
> +     if (clcnt)
> +             *clcnt = resp->context_loss_count;
> +     if (resets)
> +             *resets = resp->resets;
> +     if (p_state)
> +             *p_state = resp->programmed_state;
> +     if (c_state)
> +             *c_state = resp->current_state;
> +fail:
> +     ti_sci_put_one_xfer(&info->minfo, xfer);
> +
> +     return ret;
> +}
> +
> +/**
> + * ti_sci_cmd_get_device() - command to request for device managed by TISCI
> + * @handle:  Pointer to TISCI handle as retrieved by *ti_sci_get_handle
> + * @id:              Device Identifier
> + *
> + * Request for the device - NOTE: the client MUST maintain integrity of
> + * usage count by balancing get_device with put_device. No refcounting is
> + * managed by driver for that purpose.
> + *
> + * NOTE: The request is for exclusive access for the processor.
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id)
> +{
> +     return ti_sci_set_device_state(handle, id,
> +                                    MSG_FLAG_DEVICE_EXCLUSIVE,
> +                                    MSG_DEVICE_SW_STATE_ON);
> +}
> +
> +/**
> + * ti_sci_cmd_idle_device() - Command to idle a device managed by TISCI
> + * @handle:  Pointer to TISCI handle as retrieved by *ti_sci_get_handle
> + * @id:              Device Identifier
> + *
> + * Request for the device - NOTE: the client MUST maintain integrity of
> + * usage count by balancing get_device with put_device. No refcounting is
> + * managed by driver for that purpose.
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id)
> +{
> +     return ti_sci_set_device_state(handle, id,
> +                                    MSG_FLAG_DEVICE_EXCLUSIVE,
> +                                    MSG_DEVICE_SW_STATE_RETENTION);
> +}
> +
> +/**
> + * ti_sci_cmd_put_device() - command to release a device managed by TISCI
> + * @handle:  Pointer to TISCI handle as retrieved by *ti_sci_get_handle
> + * @id:              Device Identifier
> + *
> + * Request for the device - NOTE: the client MUST maintain integrity of
> + * usage count by balancing get_device with put_device. No refcounting is
> + * managed by driver for that purpose.
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id)
> +{
> +     return ti_sci_set_device_state(handle, id,
> +                                    0, MSG_DEVICE_SW_STATE_AUTO_OFF);
> +}
> +
> +/**
> + * ti_sci_cmd_dev_is_valid() - Is the device valid
> + * @handle:  Pointer to TISCI handle as retrieved by *ti_sci_get_handle
> + * @id:              Device Identifier
> + *
> + * Return: 0 if all went fine and the device ID is valid, else return
> + * appropriate error.
> + */
> +static int ti_sci_cmd_dev_is_valid(const struct ti_sci_handle *handle, u32 
> id)
> +{
> +     u8 unused;
> +
> +     /* check the device state which will also tell us if the ID is valid */
> +     return ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &unused);
> +}
> +
> +/**
> + * ti_sci_cmd_dev_get_clcnt() - Get context loss counter
> + * @handle:  Pointer to TISCI handle
> + * @id:              Device Identifier
> + * @count:   Pointer to Context Loss counter to populate
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle *handle, u32 
> id,
> +                                 u32 *count)
> +{
> +     return ti_sci_get_device_state(handle, id, count, NULL, NULL, NULL);
> +}
> +
> +/**
> + * ti_sci_cmd_dev_is_idle() - Check if the device is requested to be idle
> + * @handle:  Pointer to TISCI handle
> + * @id:              Device Identifier
> + * @r_state: true if requested to be idle
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_cmd_dev_is_idle(const struct ti_sci_handle *handle, u32 id,
> +                               bool *r_state)
> +{
> +     int ret;
> +     u8 state;
> +
> +     if (!r_state)
> +             return -EINVAL;
> +
> +     ret = ti_sci_get_device_state(handle, id, NULL, NULL, &state, NULL);
> +     if (ret)
> +             return ret;
> +
> +     *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION);
> +
> +     return 0;
> +}
> +
> +/**
> + * ti_sci_cmd_dev_is_stop() - Check if the device is requested to be stopped
> + * @handle:  Pointer to TISCI handle
> + * @id:              Device Identifier
> + * @r_state: true if requested to be stopped
> + * @curr_state:      true if currently stopped.
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_cmd_dev_is_stop(const struct ti_sci_handle *handle, u32 id,
> +                               bool *r_state,  bool *curr_state)
> +{
> +     int ret;
> +     u8 p_state, c_state;
> +
> +     if (!r_state && !curr_state)
> +             return -EINVAL;
> +
> +     ret =
> +         ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
> +     if (ret)
> +             return ret;
> +
> +     if (r_state)
> +             *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF);
> +     if (curr_state)
> +             *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF);
> +
> +     return 0;
> +}
> +
> +/**
> + * ti_sci_cmd_dev_is_on() - Check if the device is requested to be ON
> + * @handle:  Pointer to TISCI handle
> + * @id:              Device Identifier
> + * @r_state: true if requested to be ON
> + * @curr_state:      true if currently ON and active
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_cmd_dev_is_on(const struct ti_sci_handle *handle, u32 id,
> +                             bool *r_state,  bool *curr_state)
> +{
> +     int ret;
> +     u8 p_state, c_state;
> +
> +     if (!r_state && !curr_state)
> +             return -EINVAL;
> +
> +     ret =
> +         ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
> +     if (ret)
> +             return ret;
> +
> +     if (r_state)
> +             *r_state = (p_state == MSG_DEVICE_SW_STATE_ON);
> +     if (curr_state)
> +             *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON);
> +
> +     return 0;
> +}
> +
> +/**
> + * ti_sci_cmd_dev_is_trans() - Check if the device is currently transitioning
> + * @handle:  Pointer to TISCI handle
> + * @id:              Device Identifier
> + * @curr_state:      true if currently transitioning.
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_cmd_dev_is_trans(const struct ti_sci_handle *handle, u32 
> id,
> +                                bool *curr_state)
> +{
> +     int ret;
> +     u8 state;
> +
> +     if (!curr_state)
> +             return -EINVAL;
> +
> +     ret = ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &state);
> +     if (ret)
> +             return ret;
> +
> +     *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS);
> +
> +     return 0;
> +}
> +
> +/**
> + * ti_sci_cmd_set_device_resets() - command to set resets for device managed
> + *                               by TISCI
> + * @handle:  Pointer to TISCI handle as retrieved by *ti_sci_get_handle
> + * @id:              Device Identifier
> + * @reset_state: Device specific reset bit field
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle,
> +                                     u32 id, u32 reset_state)
> +{
> +     struct ti_sci_info *info;
> +     struct ti_sci_msg_req_set_device_resets *req;
> +     struct ti_sci_msg_hdr *resp;
> +     struct ti_sci_xfer *xfer;
> +     struct device *dev;
> +     int ret = 0;
> +
> +     if (IS_ERR(handle))
> +             return PTR_ERR(handle);
> +     if (!handle)
> +             return -EINVAL;
> +
> +     info = handle_to_ti_sci_info(handle);
> +     dev = info->dev;
> +
> +     xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_RESETS,
> +                                TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
> +                                sizeof(*req), sizeof(*resp));
> +     if (IS_ERR(xfer)) {
> +             ret = PTR_ERR(xfer);
> +             dev_err(dev, "Message alloc failed(%d)\n", ret);
> +             return ret;
> +     }
> +     req = (struct ti_sci_msg_req_set_device_resets *)xfer->xfer_buf;
> +     req->id = id;
> +     req->resets = reset_state;
> +
> +     ret = ti_sci_do_xfer(info, xfer);
> +     if (ret) {
> +             dev_err(dev, "Mbox send fail %d\n", ret);
> +             goto fail;
> +     }
> +
> +     resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
> +
> +     ret = tis_sci_is_response_ack(resp) ? 0 : -ENODEV;
> +
> +fail:
> +     ti_sci_put_one_xfer(&info->minfo, xfer);
> +
> +     return ret;
> +}
> +
> +/**
> + * ti_sci_cmd_get_device_resets() - Get reset state for device managed
> + *                               by TISCI
> + * @handle:          Pointer to TISCI handle
> + * @id:                      Device Identifier
> + * @reset_state:     Pointer to reset state to populate
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle,
> +                                     u32 id, u32 *reset_state)
> +{
> +     return ti_sci_get_device_state(handle, id, NULL, reset_state, NULL,
> +                                    NULL);
> +}
> +
> +/*
> + * ti_sci_setup_ops() - Setup the operations structures
> + * @info:    pointer to TISCI pointer
> + */
> +static void ti_sci_setup_ops(struct ti_sci_info *info)
> +{
> +     struct ti_sci_ops *ops = &info->handle.ops;
> +     struct ti_sci_dev_ops *dops = &ops->dev_ops;
> +
> +     dops->get_device = ti_sci_cmd_get_device;
> +     dops->idle_device = ti_sci_cmd_idle_device;
> +     dops->put_device = ti_sci_cmd_put_device;
> +
> +     dops->is_valid = ti_sci_cmd_dev_is_valid;
> +     dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt;
> +     dops->is_idle = ti_sci_cmd_dev_is_idle;
> +     dops->is_stop = ti_sci_cmd_dev_is_stop;
> +     dops->is_on = ti_sci_cmd_dev_is_on;
> +     dops->is_transitioning = ti_sci_cmd_dev_is_trans;
> +     dops->set_device_resets = ti_sci_cmd_set_device_resets;
> +     dops->get_device_resets = ti_sci_cmd_get_device_resets;
> +}
> +
> +/**
>   * ti_sci_get_handle() - Get the TI SCI handle for a device
>   * @dev:     Pointer to device for which we want SCI handle
>   *
> @@ -735,6 +1166,8 @@ static int ti_sci_probe(struct platform_device *pdev)
>               goto out;
>       }
>  
> +     ti_sci_setup_ops(info);
> +
>       dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n",
>                info->handle.version.abi_major, info->handle.version.abi_minor,
>                info->handle.version.firmware_revision,
> diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
> index e9dc53f26e0e..29ce0532a7ca 100644
> --- a/drivers/firmware/ti_sci.h
> +++ b/drivers/firmware/ti_sci.h
> @@ -47,6 +47,11 @@
>  #define TI_SCI_MSG_WAKE_REASON       0x0003
>  #define TI_SCI_MSG_GOODBYE   0x0004
>  
> +/* Device requests */
> +#define TI_SCI_MSG_SET_DEVICE_STATE  0x0200
> +#define TI_SCI_MSG_GET_DEVICE_STATE  0x0201
> +#define TI_SCI_MSG_SET_DEVICE_RESETS 0x0202
> +
>  /**
>   * struct ti_sci_msg_hdr - Generic Message Header for All messages and 
> responses
>   * @type:    Type of messages: One of TI_SCI_MSG* values
> @@ -90,4 +95,97 @@ struct ti_sci_msg_resp_version {
>       u8 abi_minor;
>  } __packed;
>  
> +/**
> + * struct ti_sci_msg_req_set_device_state - Set the desired state of the 
> device
> + * @hdr:             Generic header
> + * @id:      Indicates which device to modify
> + * @reserved: Reserved space in message, must be 0 for backward compatibility
> + * @state: The desired state of the device.
> + *
> + * Certain flags can also be set to alter the device state:
> + * + MSG_FLAG_DEVICE_WAKE_ENABLED - Configure the device to be a wake source.
> + * The meaning of this flag will vary slightly from device to device and from
> + * SoC to SoC but it generally allows the device to wake the SoC out of deep
> + * suspend states.
> + * + MSG_FLAG_DEVICE_RESET_ISO - Enable reset isolation for this device.
> + * + MSG_FLAG_DEVICE_EXCLUSIVE - Claim this device exclusively. When passed
> + * with STATE_RETENTION or STATE_ON, it will claim the device exclusively.
> + * If another host already has this device set to STATE_RETENTION or 
> STATE_ON,
> + * the message will fail. Once successful, other hosts attempting to set
> + * STATE_RETENTION or STATE_ON will fail.
> + *
> + * Request type is TI_SCI_MSG_SET_DEVICE_STATE, responded with a generic
> + * ACK/NACK message.
> + */
> +struct ti_sci_msg_req_set_device_state {
> +     /* Additional hdr->flags options */
> +#define MSG_FLAG_DEVICE_WAKE_ENABLED TI_SCI_MSG_FLAG(8)
> +#define MSG_FLAG_DEVICE_RESET_ISO    TI_SCI_MSG_FLAG(9)
> +#define MSG_FLAG_DEVICE_EXCLUSIVE    TI_SCI_MSG_FLAG(10)
> +     struct ti_sci_msg_hdr hdr;
> +     u32 id;
> +     u32 reserved;
> +
> +#define MSG_DEVICE_SW_STATE_AUTO_OFF 0
> +#define MSG_DEVICE_SW_STATE_RETENTION        1
> +#define MSG_DEVICE_SW_STATE_ON               2
> +     u8 state;
> +} __packed;
> +
> +/**
> + * struct ti_sci_msg_req_get_device_state - Request to get device.
> + * @hdr:             Generic header
> + * @id:              Device Identifier
> + *
> + * Request type is TI_SCI_MSG_GET_DEVICE_STATE, responded device state
> + * information
> + */
> +struct ti_sci_msg_req_get_device_state {
> +     struct ti_sci_msg_hdr hdr;
> +     u32 id;
> +} __packed;
> +
> +/**
> + * struct ti_sci_msg_resp_get_device_state - Response to get device request.
> + * @hdr:             Generic header
> + * @context_loss_count: Indicates how many times the device has lost 
> context. A
> + *   driver can use this monotonic counter to determine if the device has
> + *   lost context since the last time this message was exchanged.
> + * @resets: Programmed state of the reset lines.
> + * @programmed_state:        The state as programmed by set_device.
> + *                   - Uses the MSG_DEVICE_SW_* macros
> + * @current_state:   The actual state of the hardware.
> + *
> + * Response to request TI_SCI_MSG_GET_DEVICE_STATE.
> + */
> +struct ti_sci_msg_resp_get_device_state {
> +     struct ti_sci_msg_hdr hdr;
> +     u32 context_loss_count;
> +     u32 resets;
> +     u8 programmed_state;
> +#define MSG_DEVICE_HW_STATE_OFF              0
> +#define MSG_DEVICE_HW_STATE_ON               1
> +#define MSG_DEVICE_HW_STATE_TRANS    2
> +     u8 current_state;
> +} __packed;
> +
> +/**
> + * struct ti_sci_msg_req_set_device_resets - Set the desired resets
> + *                           configuration of the device
> + * @hdr:             Generic header
> + * @id:      Indicates which device to modify
> + * @resets: A bit field of resets for the device. The meaning, behavior,
> + *   and usage of the reset flags are device specific. 0 for a bit
> + *   indicates releasing the reset represented by that bit while 1
> + *   indicates keeping it held.
> + *
> + * Request type is TI_SCI_MSG_SET_DEVICE_RESETS, responded with a generic
> + * ACK/NACK message.
> + */
> +struct ti_sci_msg_req_set_device_resets {
> +     struct ti_sci_msg_hdr hdr;
> +     u32 id;
> +     u32 resets;
> +} __packed;
> +
>  #endif /* __TI_SCI_H */
> diff --git a/include/linux/soc/ti/ti_sci_protocol.h 
> b/include/linux/soc/ti/ti_sci_protocol.h
> index e73483fd5327..87fa73851471 100644
> --- a/include/linux/soc/ti/ti_sci_protocol.h
> +++ b/include/linux/soc/ti/ti_sci_protocol.h
> @@ -33,12 +33,103 @@ struct ti_sci_version_info {
>       char firmware_description[32];
>  };
>  
> +struct ti_sci_handle;
> +
> +/**
> + * struct ti_sci_dev_ops - Device control operations
> + * @get_device: Command to request for device managed by TISCI
> + *           Returns 0 for successful exclusive request, else returns
> + *           corresponding error message.
> + * @idle_device: Command to idle a device managed by TISCI
> + *           Returns 0 for successful exclusive request, else returns
> + *           corresponding error message.
> + * @put_device:      Command to release a device managed by TISCI
> + *           Returns 0 for successful release, else returns corresponding
> + *           error message.
> + * @is_valid:        Check if the device ID is a valid ID.
> + *           Returns 0 if the ID is valid, else returns corresponding error.
> + * @get_context_loss_count: Command to retrieve context loss counter - this
> + *           increments every time the device looses context. Overflow
> + *           is possible.
> + *           - count: pointer to u32 which will retrieve counter
> + *           Returns 0 for successful information request and count has
> + *           proper data, else returns corresponding error message.
> + * @is_idle: Reports back about device idle state
> + *           - req_state: Returns requested idle state
> + *           Returns 0 for successful information request and req_state and
> + *           current_state has proper data, else returns corresponding error
> + *           message.
> + * @is_stop: Reports back about device stop state
> + *           - req_state: Returns requested stop state
> + *           - current_state: Returns current stop state
> + *           Returns 0 for successful information request and req_state and
> + *           current_state has proper data, else returns corresponding error
> + *           message.
> + * @is_on:   Reports back about device ON(or active) state
> + *           - req_state: Returns requested ON state
> + *           - current_state: Returns current ON state
> + *           Returns 0 for successful information request and req_state and
> + *           current_state has proper data, else returns corresponding error
> + *           message.
> + * @is_transitioning: Reports back if the device is in the middle of 
> transition
> + *           of state.
> + *           -current_state: Returns 'true' if currently transitioning.
> + * @set_device_resets: Command to configure resets for device managed by 
> TISCI.
> + *           -reset_state: Device specific reset bit field
> + *           Returns 0 for successful request, else returns
> + *           corresponding error message.
> + * @get_device_resets: Command to read state of resets for device managed
> + *           by TISCI.
> + *           -reset_state: pointer to u32 which will retrieve resets
> + *           Returns 0 for successful request, else returns
> + *           corresponding error message.
> + *
> + * NOTE: for all these functions, the following parameters are generic in
> + * nature:
> + * -handle:  Pointer to TISCI handle as retrieved by *ti_sci_get_handle
> + * -id:              Device Identifier
> + *
> + * Request for the device - NOTE: the client MUST maintain integrity of
> + * usage count by balancing get_device with put_device. No refcounting is
> + * managed by driver for that purpose.
> + */
> +struct ti_sci_dev_ops {
> +     int (*get_device)(const struct ti_sci_handle *handle, u32 id);
> +     int (*idle_device)(const struct ti_sci_handle *handle, u32 id);
> +     int (*put_device)(const struct ti_sci_handle *handle, u32 id);
> +     int (*is_valid)(const struct ti_sci_handle *handle, u32 id);
> +     int (*get_context_loss_count)(const struct ti_sci_handle *handle,
> +                                   u32 id, u32 *count);
> +     int (*is_idle)(const struct ti_sci_handle *handle, u32 id,
> +                    bool *requested_state);
> +     int (*is_stop)(const struct ti_sci_handle *handle, u32 id,
> +                    bool *req_state, bool *current_state);
> +     int (*is_on)(const struct ti_sci_handle *handle, u32 id,
> +                  bool *req_state, bool *current_state);
> +     int (*is_transitioning)(const struct ti_sci_handle *handle, u32 id,
> +                             bool *current_state);
> +     int (*set_device_resets)(const struct ti_sci_handle *handle, u32 id,
> +                              u32 reset_state);
> +     int (*get_device_resets)(const struct ti_sci_handle *handle, u32 id,
> +                              u32 *reset_state);
> +};
> +
> +/**
> + * struct ti_sci_ops - Function support for TI SCI
> + * @dev_ops: Device specific operations
> + */
> +struct ti_sci_ops {
> +     struct ti_sci_dev_ops dev_ops;
> +};
> +
>  /**
>   * struct ti_sci_handle - Handle returned to TI SCI clients for usage.
>   * @version: structure containing version information
> + * @ops:     operations that are made available to TI SCI clients
>   */
>  struct ti_sci_handle {
>       struct ti_sci_version_info version;
> +     struct ti_sci_ops ops;
>  };
>  
>  #if IS_ENABLED(CONFIG_TI_SCI_PROTOCOL)
> 

Reply via email to