Lines Matching +full:protocol +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0
3 * System Control and Management Interface (SCMI) Message Protocol driver
5 * SCMI Message Protocol is used between the System Control Processor(SCP)
7 * provides a mechanism for inter-processor communication between SCP's
14 * Copyright (C) 2018-2021 ARM Ltd.
41 SCMI_ERR_SUPPORT = -1, /* Not supported */
42 SCMI_ERR_PARAMS = -2, /* Invalid Parameters */
43 SCMI_ERR_ACCESS = -3, /* Invalid access/permission denied */
44 SCMI_ERR_ENTRY = -4, /* Not found */
45 SCMI_ERR_RANGE = -5, /* Value out of range */
46 SCMI_ERR_BUSY = -6, /* Device busy */
47 SCMI_ERR_COMMS = -7, /* Communication Error */
48 SCMI_ERR_GENERIC = -8, /* Generic Error */
49 SCMI_ERR_HARDWARE = -9, /* Hardware Error */
50 SCMI_ERR_PROTOCOL = -10,/* Protocol Error */
57 /* Track the unique id for the transfers for debug & profiling purpose */
69 * struct scmi_xfers_info - Structure to manage transfer information
77 * a number of xfers equal to the maximum allowed in-flight
80 * currently in-flight messages.
91 * struct scmi_protocol_instance - Describe an initialized protocol instance.
92 * @handle: Reference to the SCMI handle associated to this protocol instance.
93 * @proto: A reference to the protocol descriptor.
94 * @gid: A reference for per-protocol devres management.
95 * @users: A refcount to track effective users of this protocol.
96 * @priv: Reference for optional protocol private data.
97 * @ph: An embedded protocol handle that will be passed down to protocol
100 * Each protocol is initialized independently once for each SCMI platform in
115 * struct scmi_info - Structure representing a SCMI instance
119 * @version: SCMI revision information containing protocol version,
120 * implementation version and (sub-)vendor identification.
124 * @tx_idr: IDR object to map protocol id to Tx channel info pointer
125 * @rx_idr: IDR object to map protocol id to Rx channel info pointer
127 * this SCMI instance: populated on protocol's first attempted
131 * MAX_PROTOCOLS_IMP elements allocated by the base protocol
162 -EOPNOTSUPP, /* SCMI_ERR_SUPPORT */
163 -EINVAL, /* SCMI_ERR_PARAM */
164 -EACCES, /* SCMI_ERR_ACCESS */
165 -ENOENT, /* SCMI_ERR_ENTRY */
166 -ERANGE, /* SCMI_ERR_RANGE */
167 -EBUSY, /* SCMI_ERR_BUSY */
168 -ECOMM, /* SCMI_ERR_COMMS */
169 -EIO, /* SCMI_ERR_GENERIC */
170 -EREMOTEIO, /* SCMI_ERR_HARDWARE */
171 -EPROTO, /* SCMI_ERR_PROTOCOL */
176 int err_idx = -errno; in scmi_to_linux_errno()
180 return -EIO; in scmi_to_linux_errno()
188 info->notify_priv = priv; in scmi_notification_instance_data_set()
189 /* Ensure updated protocol private date are visible */ in scmi_notification_instance_data_set()
199 return info->notify_priv; in scmi_notification_instance_data_get()
203 * scmi_xfer_token_set - Reserve and set new token for the xfer at hand
209 * xfer->hdr.seq: picking a monotonically increasing value avoids immediate
210 * reuse of freshly completed or timed-out xfers, thus mitigating the risk
211 * of incorrect association of a late and expired xfer with a live in-flight
212 * transaction, both happening to re-use the same token identifier.
214 * Since platform is NOT required to answer our request in-order we should
217 * - exactly 'next_token' may be NOT available so pick xfer_id >= next_token
220 * - all tokens ahead upto (MSG_TOKEN_ID_MASK - 1) are used in-flight but we
224 * X = used in-flight
227 * ------
229 * |- xfer_id picked
230 * -----------+----------------------------------------------------------
232 * ----------------------------------------------------------------------
234 * |- next_token
236 * Out-of-order pending at start
237 * -----------------------------
239 * |- xfer_id picked, last_token fixed
240 * -----+----------------------------------------------------------------
242 * ----------------------------------------------------------------------
244 * |- next_token
247 * Out-of-order pending at end
248 * ---------------------------
250 * |- xfer_id picked, last_token fixed
251 * -----+----------------------------------------------------------------
253 * ----------------------------------------------------------------------
255 * |- next_token
267 * Pick a candidate monotonic token in range [0, MSG_TOKEN_MAX - 1] in scmi_xfer_token_set()
268 * using the pre-allocated transfer_id as a base. in scmi_xfer_token_set()
274 next_token = (xfer->transfer_id & (MSG_TOKEN_MAX - 1)); in scmi_xfer_token_set()
277 xfer_id = find_next_zero_bit(minfo->xfer_alloc_table, in scmi_xfer_token_set()
281 * After heavily out-of-order responses, there are no free in scmi_xfer_token_set()
285 xfer_id = find_next_zero_bit(minfo->xfer_alloc_table, in scmi_xfer_token_set()
289 * maximum number of (MSG_TOKEN_MAX - 1) in-flight messages in scmi_xfer_token_set()
290 * but we have not found any free token [0, MSG_TOKEN_MAX - 1]. in scmi_xfer_token_set()
293 return -ENOMEM; in scmi_xfer_token_set()
296 /* Update +/- last_token accordingly if we skipped some hole */ in scmi_xfer_token_set()
298 atomic_add((int)(xfer_id - next_token), &transfer_last_id); in scmi_xfer_token_set()
300 /* Set in-flight */ in scmi_xfer_token_set()
301 set_bit(xfer_id, minfo->xfer_alloc_table); in scmi_xfer_token_set()
302 xfer->hdr.seq = (u16)xfer_id; in scmi_xfer_token_set()
308 * scmi_xfer_token_clear - Release the token
316 clear_bit(xfer->hdr.seq, minfo->xfer_alloc_table); in scmi_xfer_token_clear()
320 * scmi_xfer_get() - Allocate one message
349 spin_lock_irqsave(&minfo->xfer_lock, flags); in scmi_xfer_get()
350 if (hlist_empty(&minfo->free_xfers)) { in scmi_xfer_get()
351 spin_unlock_irqrestore(&minfo->xfer_lock, flags); in scmi_xfer_get()
352 return ERR_PTR(-ENOMEM); in scmi_xfer_get()
356 xfer = hlist_entry(minfo->free_xfers.first, struct scmi_xfer, node); in scmi_xfer_get()
357 hlist_del_init(&xfer->node); in scmi_xfer_get()
363 xfer->transfer_id = atomic_inc_return(&transfer_last_id); in scmi_xfer_get()
369 hash_add(minfo->pending_xfers, &xfer->node, in scmi_xfer_get()
370 xfer->hdr.seq); in scmi_xfer_get()
371 xfer->pending = true; in scmi_xfer_get()
373 dev_err(handle->dev, in scmi_xfer_get()
375 hlist_add_head(&xfer->node, &minfo->free_xfers); in scmi_xfer_get()
381 refcount_set(&xfer->users, 1); in scmi_xfer_get()
382 atomic_set(&xfer->busy, SCMI_XFER_FREE); in scmi_xfer_get()
384 spin_unlock_irqrestore(&minfo->xfer_lock, flags); in scmi_xfer_get()
390 * __scmi_xfer_put() - Release a message
405 spin_lock_irqsave(&minfo->xfer_lock, flags); in __scmi_xfer_put()
406 if (refcount_dec_and_test(&xfer->users)) { in __scmi_xfer_put()
407 if (xfer->pending) { in __scmi_xfer_put()
409 hash_del(&xfer->node); in __scmi_xfer_put()
410 xfer->pending = false; in __scmi_xfer_put()
412 hlist_add_head(&xfer->node, &minfo->free_xfers); in __scmi_xfer_put()
414 spin_unlock_irqrestore(&minfo->xfer_lock, flags); in __scmi_xfer_put()
418 * scmi_xfer_lookup_unlocked - Helper to lookup an xfer_id
421 * @xfer_id: Token ID to lookup in @pending_xfers
434 if (test_bit(xfer_id, minfo->xfer_alloc_table)) in scmi_xfer_lookup_unlocked()
435 xfer = XFER_FIND(minfo->pending_xfers, xfer_id); in scmi_xfer_lookup_unlocked()
437 return xfer ?: ERR_PTR(-EINVAL); in scmi_xfer_lookup_unlocked()
441 * scmi_msg_response_validate - Validate message type against state of related
450 * related synchronous response (Out-of-Order Delayed Response) the missing
453 * SCMI transport can deliver such out-of-order responses.
455 * Context: Assumes to be called with xfer->lock already acquired.
466 * delayed response we're not prepared to handle: bail-out safely in scmi_msg_response_validate()
469 if (msg_type == MSG_TYPE_DELAYED_RESP && !xfer->async_done) { in scmi_msg_response_validate()
470 dev_err(cinfo->dev, in scmi_msg_response_validate()
472 xfer->hdr.seq); in scmi_msg_response_validate()
473 return -EINVAL; in scmi_msg_response_validate()
476 switch (xfer->state) { in scmi_msg_response_validate()
483 xfer->hdr.status = SCMI_SUCCESS; in scmi_msg_response_validate()
484 xfer->state = SCMI_XFER_RESP_OK; in scmi_msg_response_validate()
485 complete(&xfer->done); in scmi_msg_response_validate()
486 dev_warn(cinfo->dev, in scmi_msg_response_validate()
488 xfer->hdr.seq); in scmi_msg_response_validate()
493 return -EINVAL; in scmi_msg_response_validate()
497 return -EINVAL; in scmi_msg_response_validate()
504 * scmi_xfer_state_update - Update xfer state
517 xfer->hdr.type = msg_type; in scmi_xfer_state_update()
520 if (xfer->hdr.type == MSG_TYPE_COMMAND) in scmi_xfer_state_update()
521 xfer->state = SCMI_XFER_RESP_OK; in scmi_xfer_state_update()
523 xfer->state = SCMI_XFER_DRESP_OK; in scmi_xfer_state_update()
530 ret = atomic_cmpxchg(&xfer->busy, SCMI_XFER_FREE, SCMI_XFER_BUSY); in scmi_xfer_acquired()
536 * scmi_xfer_command_acquire - Helper to lookup and acquire a command xfer
553 struct scmi_info *info = handle_to_scmi_info(cinfo->handle); in scmi_xfer_command_acquire()
554 struct scmi_xfers_info *minfo = &info->tx_minfo; in scmi_xfer_command_acquire()
559 spin_lock_irqsave(&minfo->xfer_lock, flags); in scmi_xfer_command_acquire()
562 dev_err(cinfo->dev, in scmi_xfer_command_acquire()
565 spin_unlock_irqrestore(&minfo->xfer_lock, flags); in scmi_xfer_command_acquire()
568 refcount_inc(&xfer->users); in scmi_xfer_command_acquire()
569 spin_unlock_irqrestore(&minfo->xfer_lock, flags); in scmi_xfer_command_acquire()
571 spin_lock_irqsave(&xfer->lock, flags); in scmi_xfer_command_acquire()
584 spin_unlock_irqrestore(&xfer->lock, flags); in scmi_xfer_command_acquire()
587 dev_err(cinfo->dev, in scmi_xfer_command_acquire()
588 "Invalid message type:%d for %d - HDR:0x%X state:%d\n", in scmi_xfer_command_acquire()
589 msg_type, xfer_id, msg_hdr, xfer->state); in scmi_xfer_command_acquire()
592 xfer = ERR_PTR(-EINVAL); in scmi_xfer_command_acquire()
601 atomic_set(&xfer->busy, SCMI_XFER_FREE); in scmi_xfer_command_release()
602 __scmi_xfer_put(&info->tx_minfo, xfer); in scmi_xfer_command_release()
608 if (info->desc->ops->clear_channel) in scmi_clear_channel()
609 info->desc->ops->clear_channel(cinfo); in scmi_clear_channel()
616 struct device *dev = cinfo->dev; in scmi_handle_notification()
617 struct scmi_info *info = handle_to_scmi_info(cinfo->handle); in scmi_handle_notification()
618 struct scmi_xfers_info *minfo = &info->rx_minfo; in scmi_handle_notification()
622 xfer = scmi_xfer_get(cinfo->handle, minfo, false); in scmi_handle_notification()
630 unpack_scmi_header(msg_hdr, &xfer->hdr); in scmi_handle_notification()
632 xfer->priv = priv; in scmi_handle_notification()
633 info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size, in scmi_handle_notification()
635 scmi_notify(cinfo->handle, xfer->hdr.protocol_id, in scmi_handle_notification()
636 xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts); in scmi_handle_notification()
638 trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id, in scmi_handle_notification()
639 xfer->hdr.protocol_id, xfer->hdr.seq, in scmi_handle_notification()
651 struct scmi_info *info = handle_to_scmi_info(cinfo->handle); in scmi_handle_response()
660 if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) in scmi_handle_response()
661 xfer->rx.len = info->desc->max_msg_size; in scmi_handle_response()
664 xfer->priv = priv; in scmi_handle_response()
665 info->desc->ops->fetch_response(cinfo, xfer); in scmi_handle_response()
667 trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id, in scmi_handle_response()
668 xfer->hdr.protocol_id, xfer->hdr.seq, in scmi_handle_response()
669 xfer->hdr.type); in scmi_handle_response()
671 if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) { in scmi_handle_response()
673 complete(xfer->async_done); in scmi_handle_response()
675 complete(&xfer->done); in scmi_handle_response()
682 * scmi_rx_callback() - callback for receiving messages
713 * xfer_put() - Release a transmit message
715 * @ph: Pointer to SCMI protocol handle
722 struct scmi_info *info = handle_to_scmi_info(pi->handle); in xfer_put()
724 __scmi_xfer_put(&info->tx_minfo, xfer); in xfer_put()
732 struct scmi_info *info = handle_to_scmi_info(cinfo->handle); in scmi_xfer_done_no_timeout()
735 * Poll also on xfer->done so that polling can be forcibly terminated in scmi_xfer_done_no_timeout()
736 * in case of out-of-order receptions of delayed responses in scmi_xfer_done_no_timeout()
738 return info->desc->ops->poll_done(cinfo, xfer) || in scmi_xfer_done_no_timeout()
739 try_wait_for_completion(&xfer->done) || in scmi_xfer_done_no_timeout()
744 * do_xfer() - Do one transfer
746 * @ph: Pointer to SCMI protocol handle
749 * Return: -ETIMEDOUT in case of no response, if transmit error,
759 struct scmi_info *info = handle_to_scmi_info(pi->handle); in do_xfer()
760 struct device *dev = info->dev; in do_xfer()
763 if (xfer->hdr.poll_completion && !info->desc->ops->poll_done) { in do_xfer()
766 return -EINVAL; in do_xfer()
770 * Initialise protocol id now from protocol handle to avoid it being in do_xfer()
771 * overridden by mistake (or malice) by the protocol code mangling with in do_xfer()
774 xfer->hdr.protocol_id = pi->proto->id; in do_xfer()
775 reinit_completion(&xfer->done); in do_xfer()
777 cinfo = idr_find(&info->tx_idr, xfer->hdr.protocol_id); in do_xfer()
779 return -EINVAL; in do_xfer()
781 trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id, in do_xfer()
782 xfer->hdr.protocol_id, xfer->hdr.seq, in do_xfer()
783 xfer->hdr.poll_completion); in do_xfer()
785 xfer->state = SCMI_XFER_SENT_OK; in do_xfer()
788 * on xfer->state due to the monotonically increasing tokens allocation, in do_xfer()
789 * we must anyway ensure xfer->state initialization is not re-ordered in do_xfer()
791 * ISR calling scmi_rx_callback() cannot see an old stale xfer->state. in do_xfer()
795 ret = info->desc->ops->send_message(cinfo, xfer); in do_xfer()
801 if (xfer->hdr.poll_completion) { in do_xfer()
809 * Do not fetch_response if an out-of-order delayed in do_xfer()
812 spin_lock_irqsave(&xfer->lock, flags); in do_xfer()
813 if (xfer->state == SCMI_XFER_SENT_OK) { in do_xfer()
814 info->desc->ops->fetch_response(cinfo, xfer); in do_xfer()
815 xfer->state = SCMI_XFER_RESP_OK; in do_xfer()
817 spin_unlock_irqrestore(&xfer->lock, flags); in do_xfer()
819 ret = -ETIMEDOUT; in do_xfer()
823 timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms); in do_xfer()
824 if (!wait_for_completion_timeout(&xfer->done, timeout)) { in do_xfer()
827 ret = -ETIMEDOUT; in do_xfer()
831 if (!ret && xfer->hdr.status) in do_xfer()
832 ret = scmi_to_linux_errno(xfer->hdr.status); in do_xfer()
834 if (info->desc->ops->mark_txdone) in do_xfer()
835 info->desc->ops->mark_txdone(cinfo, ret); in do_xfer()
837 trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id, in do_xfer()
838 xfer->hdr.protocol_id, xfer->hdr.seq, ret); in do_xfer()
847 struct scmi_info *info = handle_to_scmi_info(pi->handle); in reset_rx_to_maxsz()
849 xfer->rx.len = info->desc->max_msg_size; in reset_rx_to_maxsz()
855 * do_xfer_with_response() - Do one transfer and wait until the delayed
858 * @ph: Pointer to SCMI protocol handle
861 * Return: -ETIMEDOUT in case of no delayed response, if transmit error,
870 xfer->async_done = &async_response; in do_xfer_with_response()
874 if (!wait_for_completion_timeout(xfer->async_done, timeout)) in do_xfer_with_response()
875 ret = -ETIMEDOUT; in do_xfer_with_response()
876 else if (xfer->hdr.status) in do_xfer_with_response()
877 ret = scmi_to_linux_errno(xfer->hdr.status); in do_xfer_with_response()
880 xfer->async_done = NULL; in do_xfer_with_response()
885 * xfer_get_init() - Allocate and initialise one message for transmit
887 * @ph: Pointer to SCMI protocol handle
906 struct scmi_info *info = handle_to_scmi_info(pi->handle); in xfer_get_init()
907 struct scmi_xfers_info *minfo = &info->tx_minfo; in xfer_get_init()
908 struct device *dev = info->dev; in xfer_get_init()
911 if (rx_size > info->desc->max_msg_size || in xfer_get_init()
912 tx_size > info->desc->max_msg_size) in xfer_get_init()
913 return -ERANGE; in xfer_get_init()
915 xfer = scmi_xfer_get(pi->handle, minfo, true); in xfer_get_init()
922 xfer->tx.len = tx_size; in xfer_get_init()
923 xfer->rx.len = rx_size ? : info->desc->max_msg_size; in xfer_get_init()
924 xfer->hdr.type = MSG_TYPE_COMMAND; in xfer_get_init()
925 xfer->hdr.id = msg_id; in xfer_get_init()
926 xfer->hdr.poll_completion = false; in xfer_get_init()
934 * version_get() - command to get the revision of the SCMI entity
936 * @ph: Pointer to SCMI protocol handle
937 * @version: Holds returned version of protocol.
955 rev_info = t->rx.buf; in version_get()
964 * scmi_set_protocol_priv - Set protocol specific data at init time
966 * @ph: A reference to the protocol handle.
976 pi->priv = priv; in scmi_set_protocol_priv()
982 * scmi_get_protocol_priv - Set protocol specific data at init time
984 * @ph: A reference to the protocol handle.
986 * Return: Protocol private data if any was set.
992 return pi->priv; in scmi_get_protocol_priv()
1005 * scmi_revision_area_get - Retrieve version memory area.
1007 * @ph: A reference to the protocol handle.
1009 * A helper to grab the version memory area reference during SCMI Base protocol
1013 * instance underlying this protocol handle.
1020 return pi->handle->version; in scmi_revision_area_get()
1024 * scmi_alloc_init_protocol_instance - Allocate and initialize a protocol
1027 * @proto: The protocol descriptor.
1029 * Allocate a new protocol instance descriptor, using the provided @proto
1031 * all resources management is handled via a dedicated per-protocol devres
1035 * Return: A reference to a freshly allocated and initialized protocol instance
1043 int ret = -ENOMEM; in scmi_alloc_init_protocol_instance()
1046 const struct scmi_handle *handle = &info->handle; in scmi_alloc_init_protocol_instance()
1048 /* Protocol specific devres group */ in scmi_alloc_init_protocol_instance()
1049 gid = devres_open_group(handle->dev, NULL, GFP_KERNEL); in scmi_alloc_init_protocol_instance()
1051 scmi_protocol_put(proto->id); in scmi_alloc_init_protocol_instance()
1055 pi = devm_kzalloc(handle->dev, sizeof(*pi), GFP_KERNEL); in scmi_alloc_init_protocol_instance()
1059 pi->gid = gid; in scmi_alloc_init_protocol_instance()
1060 pi->proto = proto; in scmi_alloc_init_protocol_instance()
1061 pi->handle = handle; in scmi_alloc_init_protocol_instance()
1062 pi->ph.dev = handle->dev; in scmi_alloc_init_protocol_instance()
1063 pi->ph.xops = &xfer_ops; in scmi_alloc_init_protocol_instance()
1064 pi->ph.set_priv = scmi_set_protocol_priv; in scmi_alloc_init_protocol_instance()
1065 pi->ph.get_priv = scmi_get_protocol_priv; in scmi_alloc_init_protocol_instance()
1066 refcount_set(&pi->users, 1); in scmi_alloc_init_protocol_instance()
1067 /* proto->init is assured NON NULL by scmi_protocol_register */ in scmi_alloc_init_protocol_instance()
1068 ret = pi->proto->instance_init(&pi->ph); in scmi_alloc_init_protocol_instance()
1072 ret = idr_alloc(&info->protocols, pi, proto->id, proto->id + 1, in scmi_alloc_init_protocol_instance()
1074 if (ret != proto->id) in scmi_alloc_init_protocol_instance()
1081 if (pi->proto->events) { in scmi_alloc_init_protocol_instance()
1082 ret = scmi_register_protocol_events(handle, pi->proto->id, in scmi_alloc_init_protocol_instance()
1083 &pi->ph, in scmi_alloc_init_protocol_instance()
1084 pi->proto->events); in scmi_alloc_init_protocol_instance()
1086 dev_warn(handle->dev, in scmi_alloc_init_protocol_instance()
1087 "Protocol:%X - Events Registration Failed - err:%d\n", in scmi_alloc_init_protocol_instance()
1088 pi->proto->id, ret); in scmi_alloc_init_protocol_instance()
1091 devres_close_group(handle->dev, pi->gid); in scmi_alloc_init_protocol_instance()
1092 dev_dbg(handle->dev, "Initialized protocol: 0x%X\n", pi->proto->id); in scmi_alloc_init_protocol_instance()
1097 /* Take care to put the protocol module's owner before releasing all */ in scmi_alloc_init_protocol_instance()
1098 scmi_protocol_put(proto->id); in scmi_alloc_init_protocol_instance()
1099 devres_release_group(handle->dev, gid); in scmi_alloc_init_protocol_instance()
1105 * scmi_get_protocol_instance - Protocol initialization helper.
1107 * @protocol_id: The protocol being requested.
1109 * In case the required protocol has never been requested before for this
1111 * resource allocation with a dedicated per-protocol devres subgroup.
1113 * Return: A reference to an initialized protocol instance or error on failure:
1114 * in particular returns -EPROBE_DEFER when the desired protocol could
1123 mutex_lock(&info->protocols_mtx); in scmi_get_protocol_instance()
1124 pi = idr_find(&info->protocols, protocol_id); in scmi_get_protocol_instance()
1127 refcount_inc(&pi->users); in scmi_get_protocol_instance()
1131 /* Fails if protocol not registered on bus */ in scmi_get_protocol_instance()
1136 pi = ERR_PTR(-EPROBE_DEFER); in scmi_get_protocol_instance()
1138 mutex_unlock(&info->protocols_mtx); in scmi_get_protocol_instance()
1144 * scmi_protocol_acquire - Protocol acquire
1146 * @protocol_id: The protocol being requested.
1148 * Register a new user for the requested protocol on the specified SCMI
1151 * Return: 0 if protocol was acquired successfully.
1159 * scmi_protocol_release - Protocol de-initialization helper.
1161 * @protocol_id: The protocol being requested.
1163 * Remove one user for the specified protocol and triggers de-initialization
1164 * and resources de-allocation once the last user has gone.
1171 mutex_lock(&info->protocols_mtx); in scmi_protocol_release()
1172 pi = idr_find(&info->protocols, protocol_id); in scmi_protocol_release()
1176 if (refcount_dec_and_test(&pi->users)) { in scmi_protocol_release()
1177 void *gid = pi->gid; in scmi_protocol_release()
1179 if (pi->proto->events) in scmi_protocol_release()
1182 if (pi->proto->instance_deinit) in scmi_protocol_release()
1183 pi->proto->instance_deinit(&pi->ph); in scmi_protocol_release()
1185 idr_remove(&info->protocols, protocol_id); in scmi_protocol_release()
1189 devres_release_group(handle->dev, gid); in scmi_protocol_release()
1190 dev_dbg(handle->dev, "De-Initialized protocol: 0x%X\n", in scmi_protocol_release()
1195 mutex_unlock(&info->protocols_mtx); in scmi_protocol_release()
1202 struct scmi_info *info = handle_to_scmi_info(pi->handle); in scmi_setup_protocol_implemented()
1204 info->protocols_imp = prot_imp; in scmi_setup_protocol_implemented()
1213 if (!info->protocols_imp) in scmi_is_protocol_implemented()
1217 if (info->protocols_imp[i] == prot_id) in scmi_is_protocol_implemented()
1231 scmi_protocol_release(dres->handle, dres->protocol_id); in scmi_devm_release_protocol()
1235 * scmi_devm_protocol_get - Devres managed get protocol operations and handle
1238 * @protocol_id: The protocol being requested.
1239 * @ph: A pointer reference used to pass back the associated protocol handle.
1241 * Get hold of a protocol accounting for its usage, eventually triggering its
1242 * initialization, and returning the protocol specific operations and related
1243 * protocol handle which will be used as first argument in most of the
1245 * Being a devres based managed method, protocol hold will be automatically
1246 * released, and possibly de-initialized on last user, once the SCMI driver
1249 * Return: A reference to the requested protocol operations or error.
1258 struct scmi_handle *handle = sdev->handle; in scmi_devm_protocol_get()
1261 return ERR_PTR(-EINVAL); in scmi_devm_protocol_get()
1266 return ERR_PTR(-ENOMEM); in scmi_devm_protocol_get()
1274 dres->handle = handle; in scmi_devm_protocol_get()
1275 dres->protocol_id = protocol_id; in scmi_devm_protocol_get()
1276 devres_add(&sdev->dev, dres); in scmi_devm_protocol_get()
1278 *ph = &pi->ph; in scmi_devm_protocol_get()
1280 return pi->proto->ops; in scmi_devm_protocol_get()
1290 return dres->protocol_id == *((u8 *)data); in scmi_devm_protocol_match()
1294 * scmi_devm_protocol_put - Devres managed put protocol operations and handle
1297 * @protocol_id: The protocol being requested.
1299 * Explicitly release a protocol hold previously obtained calling the above
1306 ret = devres_release(&sdev->dev, scmi_devm_release_protocol, in scmi_devm_protocol_put()
1314 info->users++; in scmi_handle_get_from_info_unlocked()
1315 return &info->handle; in scmi_handle_get_from_info_unlocked()
1319 * scmi_handle_get() - Get the SCMI handle for a device
1324 * and is expected to be maintained by caller of SCMI protocol library.
1338 if (dev->parent == info->dev) { in scmi_handle_get()
1349 * scmi_handle_put() - Release the handle acquired by scmi_handle_get
1354 * and is expected to be maintained by caller of SCMI protocol library.
1358 * if null was passed, it returns -EINVAL;
1365 return -EINVAL; in scmi_handle_put()
1369 if (!WARN_ON(!info->users)) in scmi_handle_put()
1370 info->users--; in scmi_handle_put()
1381 struct device *dev = sinfo->dev; in __scmi_xfer_info_init()
1382 const struct scmi_desc *desc = sinfo->desc; in __scmi_xfer_info_init()
1384 /* Pre-allocated messages, no more than what hdr.seq can support */ in __scmi_xfer_info_init()
1385 if (WARN_ON(!info->max_msg || info->max_msg > MSG_TOKEN_MAX)) { in __scmi_xfer_info_init()
1387 "Invalid maximum messages %d, not in range [1 - %lu]\n", in __scmi_xfer_info_init()
1388 info->max_msg, MSG_TOKEN_MAX); in __scmi_xfer_info_init()
1389 return -EINVAL; in __scmi_xfer_info_init()
1392 hash_init(info->pending_xfers); in __scmi_xfer_info_init()
1395 info->xfer_alloc_table = devm_kcalloc(dev, BITS_TO_LONGS(MSG_TOKEN_MAX), in __scmi_xfer_info_init()
1397 if (!info->xfer_alloc_table) in __scmi_xfer_info_init()
1398 return -ENOMEM; in __scmi_xfer_info_init()
1402 * pre-initialize the buffer pointer to pre-allocated buffers and in __scmi_xfer_info_init()
1405 INIT_HLIST_HEAD(&info->free_xfers); in __scmi_xfer_info_init()
1406 for (i = 0; i < info->max_msg; i++) { in __scmi_xfer_info_init()
1409 return -ENOMEM; in __scmi_xfer_info_init()
1411 xfer->rx.buf = devm_kcalloc(dev, sizeof(u8), desc->max_msg_size, in __scmi_xfer_info_init()
1413 if (!xfer->rx.buf) in __scmi_xfer_info_init()
1414 return -ENOMEM; in __scmi_xfer_info_init()
1416 xfer->tx.buf = xfer->rx.buf; in __scmi_xfer_info_init()
1417 init_completion(&xfer->done); in __scmi_xfer_info_init()
1418 spin_lock_init(&xfer->lock); in __scmi_xfer_info_init()
1421 hlist_add_head(&xfer->node, &info->free_xfers); in __scmi_xfer_info_init()
1424 spin_lock_init(&info->xfer_lock); in __scmi_xfer_info_init()
1431 const struct scmi_desc *desc = sinfo->desc; in scmi_channels_max_msg_configure()
1433 if (!desc->ops->get_max_msg) { in scmi_channels_max_msg_configure()
1434 sinfo->tx_minfo.max_msg = desc->max_msg; in scmi_channels_max_msg_configure()
1435 sinfo->rx_minfo.max_msg = desc->max_msg; in scmi_channels_max_msg_configure()
1439 base_cinfo = idr_find(&sinfo->tx_idr, SCMI_PROTOCOL_BASE); in scmi_channels_max_msg_configure()
1441 return -EINVAL; in scmi_channels_max_msg_configure()
1442 sinfo->tx_minfo.max_msg = desc->ops->get_max_msg(base_cinfo); in scmi_channels_max_msg_configure()
1445 base_cinfo = idr_find(&sinfo->rx_idr, SCMI_PROTOCOL_BASE); in scmi_channels_max_msg_configure()
1447 sinfo->rx_minfo.max_msg = in scmi_channels_max_msg_configure()
1448 desc->ops->get_max_msg(base_cinfo); in scmi_channels_max_msg_configure()
1462 ret = __scmi_xfer_info_init(sinfo, &sinfo->tx_minfo); in scmi_xfer_info_init()
1463 if (!ret && idr_find(&sinfo->rx_idr, SCMI_PROTOCOL_BASE)) in scmi_xfer_info_init()
1464 ret = __scmi_xfer_info_init(sinfo, &sinfo->rx_minfo); in scmi_xfer_info_init()
1478 idr = tx ? &info->tx_idr : &info->rx_idr; in scmi_chan_setup()
1480 /* check if already allocated, used for multiple device per protocol */ in scmi_chan_setup()
1485 if (!info->desc->ops->chan_available(dev, idx)) { in scmi_chan_setup()
1488 return -EINVAL; in scmi_chan_setup()
1492 cinfo = devm_kzalloc(info->dev, sizeof(*cinfo), GFP_KERNEL); in scmi_chan_setup()
1494 return -ENOMEM; in scmi_chan_setup()
1496 cinfo->dev = dev; in scmi_chan_setup()
1498 ret = info->desc->ops->chan_setup(cinfo, info->dev, tx); in scmi_chan_setup()
1509 cinfo->handle = &info->handle; in scmi_chan_setup()
1525 * scmi_get_protocol_device - Helper to get/create an SCMI device.
1531 * @prot_id: The protocol ID.
1549 sdev = scmi_child_dev_find(info->dev, prot_id, name); in scmi_get_protocol_device()
1553 pr_debug("Creating SCMI device (%s) for protocol %x\n", name, prot_id); in scmi_get_protocol_device()
1555 sdev = scmi_device_create(np, info->dev, prot_id, name); in scmi_get_protocol_device()
1557 dev_err(info->dev, "failed to create %d protocol device\n", in scmi_get_protocol_device()
1562 if (scmi_txrx_setup(info, &sdev->dev, prot_id)) { in scmi_get_protocol_device()
1563 dev_err(&sdev->dev, "failed to setup transport\n"); in scmi_get_protocol_device()
1586 * scmi_create_protocol_devices - Create devices for all pending requests for
1589 * @np: The device node describing the protocol
1591 * @prot_id: The protocol ID
1608 rdev->id_table->name); in scmi_create_protocol_devices()
1614 * scmi_protocol_device_request - Helper to request a device
1616 * @id_table: A protocol/name pair descriptor for the device to be created.
1621 * The requested device name MUST NOT be already existent for any protocol;
1626 * This way the requested device is created straight-away for all the already
1639 unsigned int id = 0; in scmi_protocol_device_request() local
1644 pr_debug("Requesting SCMI device (%s) for protocol %x\n", in scmi_protocol_device_request()
1645 id_table->name, id_table->protocol_id); in scmi_protocol_device_request()
1648 * Search for the matching protocol rdev list and then search in scmi_protocol_device_request()
1652 idr_for_each_entry(&scmi_requested_devices, head, id) { in scmi_protocol_device_request()
1657 if (rdev->id_table->protocol_id == in scmi_protocol_device_request()
1658 id_table->protocol_id) in scmi_protocol_device_request()
1662 if (!strcmp(rdev->id_table->name, id_table->name)) { in scmi_protocol_device_request()
1664 rdev->id_table->protocol_id, in scmi_protocol_device_request()
1665 rdev->id_table->name); in scmi_protocol_device_request()
1666 ret = -EINVAL; in scmi_protocol_device_request()
1678 ret = -ENOMEM; in scmi_protocol_device_request()
1681 rdev->id_table = id_table; in scmi_protocol_device_request()
1685 * related protocol list, eventually creating such head if not already in scmi_protocol_device_request()
1692 ret = -ENOMEM; in scmi_protocol_device_request()
1698 id_table->protocol_id, in scmi_protocol_device_request()
1699 id_table->protocol_id + 1, GFP_KERNEL); in scmi_protocol_device_request()
1700 if (ret != id_table->protocol_id) { in scmi_protocol_device_request()
1701 pr_err("Failed to save SCMI device - ret:%d\n", ret); in scmi_protocol_device_request()
1704 ret = -EINVAL; in scmi_protocol_device_request()
1709 list_add(&rdev->node, phead); in scmi_protocol_device_request()
1714 * protocol as a valid active one: i.e. defined in DT and supported by in scmi_protocol_device_request()
1721 child = idr_find(&info->active_protocols, in scmi_protocol_device_request()
1722 id_table->protocol_id); in scmi_protocol_device_request()
1727 id_table->protocol_id, in scmi_protocol_device_request()
1728 id_table->name); in scmi_protocol_device_request()
1730 if (sdev && !sdev->handle) in scmi_protocol_device_request()
1731 sdev->handle = in scmi_protocol_device_request()
1734 dev_err(info->dev, in scmi_protocol_device_request()
1735 "Failed. SCMI protocol %d not active.\n", in scmi_protocol_device_request()
1736 id_table->protocol_id); in scmi_protocol_device_request()
1748 * scmi_protocol_device_unrequest - Helper to unrequest a device
1750 * @id_table: A protocol/name pair descriptor for the device to be unrequested.
1765 pr_debug("Unrequesting SCMI device (%s) for protocol %x\n", in scmi_protocol_device_unrequest()
1766 id_table->name, id_table->protocol_id); in scmi_protocol_device_unrequest()
1769 phead = idr_find(&scmi_requested_devices, id_table->protocol_id); in scmi_protocol_device_unrequest()
1774 if (!strcmp(victim->id_table->name, id_table->name)) { in scmi_protocol_device_unrequest()
1775 list_del(&victim->node); in scmi_protocol_device_unrequest()
1783 id_table->protocol_id); in scmi_protocol_device_unrequest()
1793 struct idr *idr = &info->tx_idr; in scmi_cleanup_txrx_channels()
1795 ret = idr_for_each(idr, info->desc->ops->chan_free, idr); in scmi_cleanup_txrx_channels()
1796 idr_destroy(&info->tx_idr); in scmi_cleanup_txrx_channels()
1798 idr = &info->rx_idr; in scmi_cleanup_txrx_channels()
1799 ret = idr_for_each(idr, info->desc->ops->chan_free, idr); in scmi_cleanup_txrx_channels()
1800 idr_destroy(&info->rx_idr); in scmi_cleanup_txrx_channels()
1811 struct device *dev = &pdev->dev; in scmi_probe()
1812 struct device_node *child, *np = dev->of_node; in scmi_probe()
1816 return -EINVAL; in scmi_probe()
1820 return -ENOMEM; in scmi_probe()
1822 info->dev = dev; in scmi_probe()
1823 info->desc = desc; in scmi_probe()
1824 INIT_LIST_HEAD(&info->node); in scmi_probe()
1825 idr_init(&info->protocols); in scmi_probe()
1826 mutex_init(&info->protocols_mtx); in scmi_probe()
1827 idr_init(&info->active_protocols); in scmi_probe()
1830 idr_init(&info->tx_idr); in scmi_probe()
1831 idr_init(&info->rx_idr); in scmi_probe()
1833 handle = &info->handle; in scmi_probe()
1834 handle->dev = info->dev; in scmi_probe()
1835 handle->version = &info->version; in scmi_probe()
1836 handle->devm_protocol_get = scmi_devm_protocol_get; in scmi_probe()
1837 handle->devm_protocol_put = scmi_devm_protocol_put; in scmi_probe()
1839 if (desc->ops->link_supplier) { in scmi_probe()
1840 ret = desc->ops->link_supplier(dev); in scmi_probe()
1857 * Trigger SCMI Base protocol initialization. in scmi_probe()
1868 list_add_tail(&info->node, &scmi_list); in scmi_probe()
1878 dev_err(dev, "Out of range protocol %d\n", prot_id); in scmi_probe()
1881 dev_err(dev, "SCMI protocol %d not implemented\n", in scmi_probe()
1887 * Save this valid DT protocol descriptor amongst in scmi_probe()
1890 ret = idr_alloc(&info->active_protocols, child, in scmi_probe()
1893 dev_err(dev, "SCMI protocol %d already activated. Skip\n", in scmi_probe()
1905 scmi_notification_exit(&info->handle); in scmi_probe()
1911 void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id) in scmi_free_channel() argument
1913 idr_remove(idr, id); in scmi_free_channel()
1918 int ret = 0, id; in scmi_remove() local
1923 if (info->users) in scmi_remove()
1924 ret = -EBUSY; in scmi_remove()
1926 list_del(&info->node); in scmi_remove()
1932 scmi_notification_exit(&info->handle); in scmi_remove()
1934 mutex_lock(&info->protocols_mtx); in scmi_remove()
1935 idr_destroy(&info->protocols); in scmi_remove()
1936 mutex_unlock(&info->protocols_mtx); in scmi_remove()
1938 idr_for_each_entry(&info->active_protocols, child, id) in scmi_remove()
1940 idr_destroy(&info->active_protocols); in scmi_remove()
1951 return sprintf(buf, "%u.%u\n", info->version.major_ver, in protocol_version_show()
1952 info->version.minor_ver); in protocol_version_show()
1961 return sprintf(buf, "0x%x\n", info->version.impl_ver); in firmware_version_show()
1970 return sprintf(buf, "%s\n", info->version.vendor_id); in vendor_id_show()
1979 return sprintf(buf, "%s\n", info->version.sub_vendor_id); in sub_vendor_id_show()
1998 { .compatible = "arm,scmi-smc", .data = &scmi_smc_desc},
2001 { .compatible = "arm,scmi-virtio", .data = &scmi_virtio_desc},
2010 .name = "arm-scmi",
2019 * __scmi_transports_setup - Common helper to call transport-specific
2034 for (trans = scmi_of_match; trans->data; trans++) { in __scmi_transports_setup()
2035 const struct scmi_desc *tdesc = trans->data; in __scmi_transports_setup()
2037 if ((init && !tdesc->transport_init) || in __scmi_transports_setup()
2038 (!init && !tdesc->transport_exit)) in __scmi_transports_setup()
2042 ret = tdesc->transport_init(); in __scmi_transports_setup()
2044 tdesc->transport_exit(); in __scmi_transports_setup()
2048 trans->compatible); in __scmi_transports_setup()
2072 return -EINVAL; in scmi_driver_init()
2076 /* Initialize any compiled-in transport which provided an init/exit */ in scmi_driver_init()
2115 MODULE_ALIAS("platform: arm-scmi");
2117 MODULE_DESCRIPTION("ARM SCMI protocol driver");