From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753632AbcHVD5y (ORCPT ); Sun, 21 Aug 2016 23:57:54 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:53221 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753029AbcHVD5w (ORCPT ); Sun, 21 Aug 2016 23:57:52 -0400 Subject: Re: [PATCH 3/5] firmware: ti_sci: Add support for Device control To: Nishanth Menon , Russell King , Sudeep Holla , Santosh Shilimkar References: <20160819225159.10758-1-nm@ti.com> <20160819225159.10758-4-nm@ti.com> CC: Russ Dill , Dave Gerlach , Peter Ujfalusi , "Andrew F . Davis" , Suman Anna , Tero Kristo , , , , From: Lokesh Vutla Message-ID: <9a6a8663-a3f7-7875-253f-98232d56b860@ti.com> Date: Mon, 22 Aug 2016 09:26:49 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: <20160819225159.10758-4-nm@ti.com> Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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-gerlach@ti.com: Contributed device reset handling] > Signed-off-by: Dave Gerlach > Signed-off-by: Nishanth Menon > --- > 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) >