1 /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 #ifndef _SOC_QCOM_GLINK_PRIVATE_H_
13 #define _SOC_QCOM_GLINK_PRIVATE_H_
15 #include <linux/bug.h>
16 #include <linux/completion.h>
17 #include <linux/dcache.h>
18 #include <linux/ipc_logging.h>
19 #include <linux/kernel.h>
20 #include <linux/kref.h>
21 #include <linux/ratelimit.h>
22 #include <linux/seq_file.h>
23 #include <linux/spinlock.h>
24 #include <linux/types.h>
25 #include <soc/qcom/glink.h>
27 struct glink_core_xprt_ctx;
29 enum transport_state_e;
30 enum local_channel_state_e;
34 QCOM_GLINK_INFO = 1U << 0,
35 QCOM_GLINK_DEBUG = 1U << 1,
36 QCOM_GLINK_GPIO = 1U << 2,
37 QCOM_GLINK_PERF = 1U << 3,
49 GLINK_DBGFS_MAX_NUM_SUBS
52 enum glink_dbgfs_xprt {
57 GLINK_DBGFS_XMOCK_LOW,
58 GLINK_DBGFS_XMOCK_HIGH,
59 GLINK_DBGFS_MAX_NUM_XPRTS
63 const char *curr_name;
68 struct glink_dbgfs_data {
69 struct list_head flist;
71 void (*o_func)(struct seq_file *s);
76 struct xprt_ctx_iterator {
77 struct list_head *xprt_list;
78 struct glink_core_xprt_ctx *i_curr;
79 unsigned long xprt_list_flags;
82 struct ch_ctx_iterator {
83 struct list_head *ch_list;
84 struct channel_ctx *i_curr;
85 unsigned long ch_list_flags;
88 struct glink_ch_intent_info {
89 spinlock_t *li_lst_lock;
90 struct list_head *li_avail_list;
91 struct list_head *li_used_list;
92 spinlock_t *ri_lst_lock;
93 struct list_head *ri_list;
96 /* Tracer Packet Event IDs for G-Link */
97 enum glink_tracer_pkt_events {
99 GLINK_QUEUE_TO_SCHEDULER = 2,
100 GLINK_SCHEDULER_TX = 3,
107 * glink_get_ss_enum_string() - get the name of the subsystem based on enum value
108 * @enum_id: enum id of a specific subsystem.
110 * Return: name of the subsystem, NULL in case of invalid input
112 const char *glink_get_ss_enum_string(unsigned int enum_id);
115 * glink_get_xprt_enum_string() - get the name of the transport based on enum value
116 * @enum_id: enum id of a specific transport.
118 * Return: name of the transport, NULL in case of invalid input
120 const char *glink_get_xprt_enum_string(unsigned int enum_id);
123 * glink_get_xprt_state_string() - get the name of the transport based on enum value
124 * @enum_id: enum id of the state of the transport.
126 * Return: name of the transport state, NULL in case of invalid input
128 const char *glink_get_xprt_state_string(enum transport_state_e enum_id);
131 * glink_get_ch_state_string() - get the name of the transport based on enum value
132 * @enum_id: enum id of a specific state of the channel.
134 * Return: name of the channel state, NULL in case of invalid input
136 const char *glink_get_ch_state_string(enum local_channel_state_e enum_id);
138 #define GLINK_IPC_LOG_STR(x...) do { \
139 if (glink_get_log_ctx()) \
140 ipc_log_string(glink_get_log_ctx(), x); \
143 #define GLINK_DBG(x...) do { \
144 if (glink_get_debug_mask() & QCOM_GLINK_DEBUG) \
145 GLINK_IPC_LOG_STR(x); \
148 #define GLINK_INFO(x...) do { \
149 if (glink_get_debug_mask() & QCOM_GLINK_INFO) \
150 GLINK_IPC_LOG_STR(x); \
153 #define GLINK_INFO_PERF(x...) do { \
154 if (glink_get_debug_mask() & (QCOM_GLINK_INFO | QCOM_GLINK_PERF)) \
155 GLINK_IPC_LOG_STR(x); \
158 #define GLINK_PERF(x...) do { \
159 if (glink_get_debug_mask() & QCOM_GLINK_PERF) \
160 GLINK_IPC_LOG_STR("<PERF> " x); \
163 #define GLINK_UT_ERR(x...) do { \
164 if (!(glink_get_debug_mask() & QCOM_GLINK_PERF)) \
166 GLINK_IPC_LOG_STR("<UT> " x); \
169 #define GLINK_UT_DBG(x...) do { \
170 if (glink_get_debug_mask() & QCOM_GLINK_DEBUG) \
171 GLINK_IPC_LOG_STR("<UT> " x); \
174 #define GLINK_UT_INFO(x...) do { \
175 if (glink_get_debug_mask() & QCOM_GLINK_INFO) \
176 GLINK_IPC_LOG_STR("<UT> " x); \
179 #define GLINK_UT_INFO_PERF(x...) do { \
180 if (glink_get_debug_mask() & (QCOM_GLINK_INFO | QCOM_GLINK_PERF)) \
181 GLINK_IPC_LOG_STR("<UT> " x); \
184 #define GLINK_UT_PERF(x...) do { \
185 if (glink_get_debug_mask() & QCOM_GLINK_PERF) \
186 GLINK_IPC_LOG_STR("<PERF> " x); \
189 #define GLINK_PERF_XPRT(xprt, fmt, args...) do { \
190 if (glink_get_debug_mask() & QCOM_GLINK_PERF) \
191 GLINK_IPC_LOG_STR("<PERF> %s:%s " fmt, \
192 xprt->name, xprt->edge, args); \
195 #define GLINK_PERF_CH(ctx, fmt, args...) do { \
196 if (glink_get_debug_mask() & QCOM_GLINK_PERF) \
197 GLINK_IPC_LOG_STR("<PERF> %s:%s:%s[%u:%u] " fmt, \
198 ctx->transport_ptr->name, \
199 ctx->transport_ptr->edge, \
205 #define GLINK_PERF_CH_XPRT(ctx, xprt, fmt, args...) do { \
206 if (glink_get_debug_mask() & QCOM_GLINK_PERF) \
207 GLINK_IPC_LOG_STR("<PERF> %s:%s:%s[%u:%u] " fmt, \
215 #define GLINK_INFO_PERF_XPRT(xprt, fmt, args...) do { \
216 if (glink_get_debug_mask() & (QCOM_GLINK_INFO | QCOM_GLINK_PERF)) \
217 GLINK_IPC_LOG_STR("<CORE> %s:%s " fmt, \
218 xprt->name, xprt->edge, args); \
221 #define GLINK_INFO_PERF_CH(ctx, fmt, args...) do { \
222 if (glink_get_debug_mask() & (QCOM_GLINK_INFO | QCOM_GLINK_PERF)) \
223 GLINK_IPC_LOG_STR("<CORE> %s:%s:%s[%u:%u] " fmt, \
224 ctx->transport_ptr->name, \
225 ctx->transport_ptr->edge, \
231 #define GLINK_INFO_PERF_CH_XPRT(ctx, xprt, fmt, args...) do { \
232 if (glink_get_debug_mask() & (QCOM_GLINK_INFO | QCOM_GLINK_PERF)) \
233 GLINK_IPC_LOG_STR("<CORE> %s:%s:%s[%u:%u] " fmt, \
241 #define GLINK_INFO_XPRT(xprt, fmt, args...) do { \
242 if (glink_get_debug_mask() & QCOM_GLINK_INFO) \
243 GLINK_IPC_LOG_STR("<CORE> %s:%s " fmt, \
244 xprt->name, xprt->edge, args); \
247 #define GLINK_INFO_CH(ctx, fmt, args...) do { \
248 if (glink_get_debug_mask() & QCOM_GLINK_INFO) \
249 GLINK_IPC_LOG_STR("<CORE> %s:%s:%s[%u:%u] " fmt, \
250 ctx->transport_ptr->name, \
251 ctx->transport_ptr->edge, \
257 #define GLINK_INFO_CH_XPRT(ctx, xprt, fmt, args...) do { \
258 if (glink_get_debug_mask() & QCOM_GLINK_INFO) \
259 GLINK_IPC_LOG_STR("<CORE> %s:%s:%s[%u:%u] " fmt, \
267 #define GLINK_DBG_XPRT(xprt, fmt, args...) do { \
268 if (glink_get_debug_mask() & QCOM_GLINK_DEBUG) \
269 GLINK_IPC_LOG_STR("<CORE> %s:%s " fmt, \
270 xprt->name, xprt->edge, args); \
273 #define GLINK_DBG_CH(ctx, fmt, args...) do { \
274 if (glink_get_debug_mask() & QCOM_GLINK_DEBUG) \
275 GLINK_IPC_LOG_STR("<CORE> %s:%s:%s[%u:%u] " fmt, \
276 ctx->transport_ptr->name, \
277 ctx->transport_ptr->edge, \
283 #define GLINK_DBG_CH_XPRT(ctx, xprt, fmt, args...) do { \
284 if (glink_get_debug_mask() & QCOM_GLINK_DEBUG) \
285 GLINK_IPC_LOG_STR("<CORE> %s:%s:%s[%u:%u] " fmt, \
293 #define GLINK_ERR(x...) do { \
294 pr_err_ratelimited("<CORE> " x); \
295 GLINK_IPC_LOG_STR("<CORE> " x); \
298 #define GLINK_ERR_XPRT(xprt, fmt, args...) do { \
299 pr_err_ratelimited("<CORE> %s:%s " fmt, \
300 xprt->name, xprt->edge, args); \
301 GLINK_INFO_XPRT(xprt, fmt, args); \
304 #define GLINK_ERR_CH(ctx, fmt, args...) do { \
305 pr_err_ratelimited("<CORE> %s:%s:%s[%u:%u] " fmt, \
306 ctx->transport_ptr->name, \
307 ctx->transport_ptr->edge, \
311 GLINK_INFO_CH(ctx, fmt, args); \
314 #define GLINK_ERR_CH_XPRT(ctx, xprt, fmt, args...) do { \
315 pr_err_ratelimited("<CORE> %s:%s:%s[%u:%u] " fmt, \
321 GLINK_INFO_CH_XPRT(ctx, xprt, fmt, args); \
325 * OVERFLOW_ADD_UNSIGNED() - check for unsigned overflow
327 * type: type to check for overflow
328 * a: left value to use
329 * b: right value to use
330 * returns: true if a + b will result in overflow; false otherwise
332 #define OVERFLOW_ADD_UNSIGNED(type, a, b) \
333 (((type)~0 - (a)) < (b) ? true : false)
336 * glink_get_debug_mask() - Return debug mask attribute
338 * Return: debug mask attribute
340 unsigned glink_get_debug_mask(void);
343 * glink_get_log_ctx() - Return log context for other GLINK modules.
345 * Return: Log context or NULL if none.
347 void *glink_get_log_ctx(void);
350 * glink_get_channel_id_for_handle() - Get logical channel ID
352 * @handle: handle of channel
354 * Used internally by G-Link debugfs.
356 * Return: Logical Channel ID or standard Linux error code
358 int glink_get_channel_id_for_handle(void *handle);
361 * glink_get_channel_name_for_handle() - return channel name
363 * @handle: handle of channel
365 * Used internally by G-Link debugfs.
367 * Return: Channel name or NULL
369 char *glink_get_channel_name_for_handle(void *handle);
372 * glink_debugfs_init() - initialize glink debugfs directory
374 * Return: error code or success.
376 int glink_debugfs_init(void);
379 * glink_debugfs_exit() - removes glink debugfs directory
381 void glink_debugfs_exit(void);
384 * glink_debugfs_create() - create the debugfs file
385 * @name: debugfs file name
386 * @show: pointer to the actual function which will be invoked upon
388 * @dir: pointer to a structure debugfs_dir
389 * @dbgfs_data: pointer to any private data need to be associated with debugfs
390 * @b_free_req: boolean value to decide to free the memory associated with
391 * @dbgfs_data during deletion of the file
393 * Return: pointer to the file/directory created, NULL in case of error
395 * This function checks which directory will be used to create the debugfs file
396 * and calls glink_dfs_create_file. Anybody who intend to allocate some memory
397 * for the dbgfs_data and required to free it in deletion, need to set
398 * b_free_req to true. Otherwise, there will be a memory leak.
400 struct dentry *glink_debugfs_create(const char *name,
401 void (*show)(struct seq_file *),
402 struct glink_dbgfs *dir, void *dbgfs_data, bool b_free_req);
405 * glink_debugfs_remove_recur() - remove the the directory & files recursively
406 * @rm_dfs: pointer to the structure glink_dbgfs
408 * This function removes the files & directories. This also takes care of
409 * freeing any memory associated with the debugfs file.
411 void glink_debugfs_remove_recur(struct glink_dbgfs *dfs);
414 * glink_debugfs_remove_channel() - remove all channel specifc files & folder in
415 * debugfs when channel is fully closed
416 * @ch_ctx: pointer to the channel_contenxt
417 * @xprt_ctx: pointer to the transport_context
419 * This function is invoked when any channel is fully closed. It removes the
420 * folders & other files in debugfs for that channel.
422 void glink_debugfs_remove_channel(struct channel_ctx *ch_ctx,
423 struct glink_core_xprt_ctx *xprt_ctx);
426 * glink_debugfs_add_channel() - create channel specifc files & folder in
427 * debugfs when channel is added
428 * @ch_ctx: pointer to the channel_contenxt
429 * @xprt_ctx: pointer to the transport_context
431 * This function is invoked when a new channel is created. It creates the
432 * folders & other files in debugfs for that channel
434 void glink_debugfs_add_channel(struct channel_ctx *ch_ctx,
435 struct glink_core_xprt_ctx *xprt_ctx);
438 * glink_debugfs_add_xprt() - create transport specifc files & folder in
439 * debugfs when new transport is registerd
440 * @xprt_ctx: pointer to the transport_context
442 * This function is invoked when a new transport is registered. It creates the
443 * folders & other files in debugfs for that transport
445 void glink_debugfs_add_xprt(struct glink_core_xprt_ctx *xprt_ctx);
448 * glink_xprt_ctx_iterator_init() - Initializes the transport context list iterator
449 * @xprt_i: pointer to the transport context iterator.
453 * This function acquires the transport context lock which must then be
454 * released by glink_xprt_ctx_iterator_end()
456 void glink_xprt_ctx_iterator_init(struct xprt_ctx_iterator *xprt_i);
459 * glink_xprt_ctx_iterator_end() - Ends the transport context list iteration
460 * @xprt_i: pointer to the transport context iterator.
464 void glink_xprt_ctx_iterator_end(struct xprt_ctx_iterator *xprt_i);
467 * glink_xprt_ctx_iterator_next() - iterates element by element in transport context list
468 * @xprt_i: pointer to the transport context iterator.
470 * Return: pointer to the transport context structure
472 struct glink_core_xprt_ctx *glink_xprt_ctx_iterator_next(
473 struct xprt_ctx_iterator *xprt_i);
476 * glink_get_xprt_name() - get the transport name
477 * @xprt_ctx: pointer to the transport context.
479 * Return: name of the transport
481 char *glink_get_xprt_name(struct glink_core_xprt_ctx *xprt_ctx);
484 * glink_get_xprt_edge_name() - get the name of the remote processor/edge
486 * @xprt_ctx: pointer to the transport context.
488 * Return: name of the remote processor/edge
490 char *glink_get_xprt_edge_name(struct glink_core_xprt_ctx *xprt_ctx);
493 * glink_get_xprt_state() - get the state of the transport
494 * @xprt_ctx: pointer to the transport context.
496 * Return: name of the transport state, NULL in case of invalid input
498 const char *glink_get_xprt_state(struct glink_core_xprt_ctx *xprt_ctx);
501 * glink_get_xprt_version_features() - get the version and feature set
502 * of local transport in glink
503 * @xprt_ctx: pointer to the transport context.
505 * Return: pointer to the glink_core_version
507 const struct glink_core_version *glink_get_xprt_version_features(
508 struct glink_core_xprt_ctx *xprt_ctx);
511 * glink_ch_ctx_iterator_init() - Initializes the channel context list iterator
512 * @ch_iter: pointer to the channel context iterator.
513 * @xprt: pointer to the transport context that holds the channel list
515 * This function acquires the channel context lock which must then be
516 * released by glink_ch_ctx_iterator_end()
518 void glink_ch_ctx_iterator_init(struct ch_ctx_iterator *ch_iter,
519 struct glink_core_xprt_ctx *xprt);
522 * glink_ch_ctx_iterator_end() - Ends the channel context list iteration
523 * @ch_iter: pointer to the channel context iterator.
526 void glink_ch_ctx_iterator_end(struct ch_ctx_iterator *ch_iter,
527 struct glink_core_xprt_ctx *xprt);
530 * glink_ch_ctx_iterator_next() - iterates element by element in channel context list
531 * @c_i: pointer to the channel context iterator.
533 * Return: pointer to the channel context structure
535 struct channel_ctx *glink_ch_ctx_iterator_next(struct ch_ctx_iterator *ch_iter);
538 * glink_get_ch_name() - get the channel name
539 * @ch_ctx: pointer to the channel context.
541 * Return: name of the channel, NULL in case of invalid input
543 char *glink_get_ch_name(struct channel_ctx *ch_ctx);
546 * glink_get_ch_edge_name() - get the name of the remote processor/edge
548 * @xprt_ctx: pointer to the channel context.
550 * Return: name of the remote processor/edge
552 char *glink_get_ch_edge_name(struct channel_ctx *ch_ctx);
555 * glink_get_ch_rcid() - get the remote channel ID
556 * @ch_ctx: pointer to the channel context.
558 * Return: remote channel id, -EINVAL in case of invalid input
560 int glink_get_ch_lcid(struct channel_ctx *ch_ctx);
563 * glink_get_ch_rcid() - get the remote channel ID
564 * @ch_ctx: pointer to the channel context.
566 * Return: remote channel id, -EINVAL in case of invalid input
568 int glink_get_ch_rcid(struct channel_ctx *ch_ctx);
571 * glink_get_ch_lstate() - get the local channel state
572 * @ch_ctx: pointer to the channel context.
574 * Return: name of the local channel state, NULL in case of invalid input
576 const char *glink_get_ch_lstate(struct channel_ctx *ch_ctx);
579 * glink_get_ch_rstate() - get the remote channel state
580 * @ch_ctx: pointer to the channel context.
582 * Return: true if remote side is opened false otherwise
584 bool glink_get_ch_rstate(struct channel_ctx *ch_ctx);
587 * glink_get_ch_xprt_name() - get the name of the transport to which
588 * the channel belongs
589 * @ch_ctx: pointer to the channel context.
591 * Return: name of the export, NULL in case of invalid input
593 char *glink_get_ch_xprt_name(struct channel_ctx *ch_ctx);
596 * glink_get_tx_pkt_count() - get the total number of packets sent
597 * through this channel
598 * @ch_ctx: pointer to the channel context.
600 * Return: number of packets transmitted, -EINVAL in case of invalid input
602 int glink_get_ch_tx_pkt_count(struct channel_ctx *ch_ctx);
605 * glink_get_ch_rx_pkt_count() - get the total number of packets
606 * recieved at this channel
607 * @ch_ctx: pointer to the channel context.
609 * Return: number of packets recieved, -EINVAL in case of invalid input
611 int glink_get_ch_rx_pkt_count(struct channel_ctx *ch_ctx);
614 * glink_get_ch_lintents_queued() - get the total number of intents queued
616 * @ch_ctx: pointer to the channel context.
618 * Return: number of intents queued, -EINVAL in case of invalid input
620 int glink_get_ch_lintents_queued(struct channel_ctx *ch_ctx);
623 * glink_get_ch_rintents_queued() - get the total number of intents queued
625 * @ch_ctx: pointer to the channel context.
627 * Return: number of intents queued
629 int glink_get_ch_rintents_queued(struct channel_ctx *ch_ctx);
632 * glink_get_ch_intent_info() - get the intent details of a channel
633 * @ch_ctx: pointer to the channel context.
634 * @ch_ctx_i: pointer to a structure that will contain intent details
636 * This funcion is used to get all the channel intent details including locks.
638 void glink_get_ch_intent_info(struct channel_ctx *ch_ctx,
639 struct glink_ch_intent_info *ch_ctx_i);
642 * enum ssr_command - G-Link SSR protocol commands
645 GLINK_SSR_DO_CLEANUP,
646 GLINK_SSR_CLEANUP_DONE,
650 * struct ssr_notify_data - Contains private data used for client notifications
652 * tx_done: Indicates whether or not the tx_done notification has
654 * event: The state notification event received.
655 * responded: Indicates whether or not a cleanup_done response was
657 * edge: The G-Link edge name for the channel associated with
659 * do_cleanup_data: Structure containing the G-Link SSR do_cleanup message.
661 struct ssr_notify_data {
666 struct do_cleanup_msg *do_cleanup_data;
670 * struct subsys_info - Subsystem info structure
671 * ssr_name: name of the subsystem recognized by the SSR framework
672 * edge: name of the G-Link edge
673 * xprt: name of the G-Link transport
674 * handle: glink_ssr channel used for this subsystem
675 * link_state_handle: link state handle for this edge, used to unregister
676 * from receiving link state callbacks
677 * link_info: Transport info used in link state callback registration
678 * cb_data: Private callback data structure for notification
680 * subsystem_list_node: used to chain this structure in a list of subsystem
682 * notify_list: list of subsys_info_leaf structures, containing the
683 * subsystems to notify if this subsystem undergoes SSR
684 * notify_list_len: length of notify_list
685 * link_up: Flag indicating whether transport is up or not
686 * link_up_lock: Lock for protecting the link_up flag
689 const char *ssr_name;
693 void *link_state_handle;
694 struct glink_link_info *link_info;
695 struct ssr_notify_data *cb_data;
696 struct list_head subsystem_list_node;
697 struct list_head notify_list;
700 spinlock_t link_up_lock;
704 * struct subsys_info_leaf - Subsystem info leaf structure (a subsystem on the
705 * notify list of a subsys_info structure)
706 * ssr_name: Name of the subsystem recognized by the SSR framework
707 * edge: Name of the G-Link edge
708 * xprt: Name of the G-Link transport
709 * restarted: Indicates whether a restart has been triggered for this edge
710 * cb_data: Private callback data structure for notification functions
711 * notify_list_node: used to chain this structure in the notify list
713 struct subsys_info_leaf {
714 const char *ssr_name;
718 struct ssr_notify_data *cb_data;
719 struct list_head notify_list_node;
723 * struct do_cleanup_msg - The data structure for an SSR do_cleanup message
724 * version: The G-Link SSR protocol version
725 * command: The G-Link SSR command - do_cleanup
726 * seq_num: Sequence number
727 * name_len: Length of the name of the subsystem being restarted
728 * name: G-Link edge name of the subsystem being restarted
730 struct do_cleanup_msg {
739 * struct cleanup_done_msg - The data structure for an SSR cleanup_done message
740 * version: The G-Link SSR protocol version
741 * response: The G-Link SSR response to a do_cleanup command, cleanup_done
742 * seq_num: Sequence number
744 struct cleanup_done_msg {
751 * get_info_for_subsystem() - Retrieve information about a subsystem from the
752 * global subsystem_info_list
753 * @subsystem: The name of the subsystem recognized by the SSR
756 * Return: subsys_info structure containing info for the requested subsystem;
757 * NULL if no structure can be found for the requested subsystem
759 struct subsys_info *get_info_for_subsystem(const char *subsystem);
762 * get_info_for_edge() - Retrieve information about a subsystem from the
763 * global subsystem_info_list
764 * @edge: The name of the edge recognized by G-Link
766 * Return: subsys_info structure containing info for the requested subsystem;
767 * NULL if no structure can be found for the requested subsystem
769 struct subsys_info *get_info_for_edge(const char *edge);
772 * glink_ssr_get_seq_num() - Get the current SSR sequence number
774 * Return: The current SSR sequence number
776 uint32_t glink_ssr_get_seq_num(void);
779 * glink_ssr() - SSR cleanup function.
781 * Return: Standard error code.
783 int glink_ssr(const char *subsystem);
786 * notify for subsystem() - Notify other subsystems that a subsystem is being
788 * @ss_info: Subsystem info structure for the subsystem being restarted
790 * This function sends notifications to affected subsystems that the subsystem
791 * in ss_info is being restarted, and waits for the cleanup done response from
792 * all of those subsystems. It also initiates any local cleanup that is
795 * Return: 0 on success, standard error codes otherwise
797 int notify_for_subsystem(struct subsys_info *ss_info);
800 * glink_ssr_wait_cleanup_done() - Get the value of the
801 * notifications_successful flag in glink_ssr.
802 * @timeout_multiplier: timeout multiplier for waiting on all processors
805 * Return: True if cleanup_done received from all processors, false otherwise
807 bool glink_ssr_wait_cleanup_done(unsigned ssr_timeout_multiplier);
809 struct channel_lcid {
810 struct list_head list_node;
815 * struct rwref_lock - Read/Write Reference Lock
817 * kref: reference count
818 * read_count: number of readers that own the lock
819 * write_count: number of writers (max 1) that own the lock
820 * count_zero: used for internal signaling for non-atomic locks
822 * A Read/Write Reference Lock is a combination of a read/write spinlock and a
823 * refence count. The main difference is that no locks are held in the
824 * critical section and the lifetime of the object is guaranteed.
827 * Multiple readers may access the lock at any given time and a read lock will
828 * also ensure that the object exists for the life of the lock.
831 * use resource in "critical section" (no locks are held)
835 * A single writer may access the lock at any given time and a write lock will
836 * also ensure that the object exists for the life of the lock.
839 * use resource in "critical section" (no locks are held)
843 * To ensure the lifetime of the lock (and not affect the read or write lock),
844 * a simple reference can be done. By default, rwref_lock_init() will set the
845 * reference count to 1.
847 * rwref_lock_init() Reference count is 1
848 * rwref_get() Reference count is 2
849 * rwref_put() Reference count is 1
850 * rwref_put() Reference count goes to 0 and object is destroyed
855 unsigned write_count;
857 struct completion count_zero;
859 void (*release)(struct rwref_lock *);
863 * rwref_lock_release() - Initialize rwref_lock
864 * lock_ptr: pointer to lock structure
866 static inline void rwref_lock_release(struct kref *kref_ptr)
868 struct rwref_lock *lock_ptr;
870 BUG_ON(kref_ptr == NULL);
872 lock_ptr = container_of(kref_ptr, struct rwref_lock, kref);
873 if (lock_ptr->release)
874 lock_ptr->release(lock_ptr);
878 * rwref_lock_init() - Initialize rwref_lock
879 * lock_ptr: pointer to lock structure
880 * release: release function called when reference count goes to 0
882 static inline void rwref_lock_init(struct rwref_lock *lock_ptr,
883 void (*release)(struct rwref_lock *))
885 BUG_ON(lock_ptr == NULL);
887 kref_init(&lock_ptr->kref);
888 lock_ptr->read_count = 0;
889 lock_ptr->write_count = 0;
890 spin_lock_init(&lock_ptr->lock);
891 init_completion(&lock_ptr->count_zero);
892 lock_ptr->release = release;
896 * rwref_get() - gains a reference count for the object
897 * lock_ptr: pointer to lock structure
899 static inline void rwref_get(struct rwref_lock *lock_ptr)
901 BUG_ON(lock_ptr == NULL);
903 kref_get(&lock_ptr->kref);
907 * rwref_put() - puts a reference count for the object
908 * lock_ptr: pointer to lock structure
910 * If the reference count goes to zero, the release function is called.
912 static inline void rwref_put(struct rwref_lock *lock_ptr)
914 BUG_ON(lock_ptr == NULL);
916 kref_put(&lock_ptr->kref, rwref_lock_release);
920 * rwref_read_get() - gains a reference count for a read operation
921 * lock_ptr: pointer to lock structure
923 * Multiple readers may acquire the lock as long as the write count is zero.
925 static inline void rwref_read_get(struct rwref_lock *lock_ptr)
929 BUG_ON(lock_ptr == NULL);
931 kref_get(&lock_ptr->kref);
933 spin_lock_irqsave(&lock_ptr->lock, flags);
934 if (lock_ptr->write_count == 0) {
935 lock_ptr->read_count++;
936 spin_unlock_irqrestore(&lock_ptr->lock, flags);
939 spin_unlock_irqrestore(&lock_ptr->lock, flags);
940 wait_for_completion(&lock_ptr->count_zero);
945 * rwref_read_put() - returns a reference count for a read operation
946 * lock_ptr: pointer to lock structure
948 * Must be preceded by a call to rwref_read_get().
950 static inline void rwref_read_put(struct rwref_lock *lock_ptr)
954 BUG_ON(lock_ptr == NULL);
956 spin_lock_irqsave(&lock_ptr->lock, flags);
957 BUG_ON(lock_ptr->read_count == 0);
958 if (--lock_ptr->read_count == 0)
959 complete(&lock_ptr->count_zero);
960 spin_unlock_irqrestore(&lock_ptr->lock, flags);
961 kref_put(&lock_ptr->kref, rwref_lock_release);
965 * rwref_write_get() - gains a reference count for a write operation
966 * lock_ptr: pointer to lock structure
968 * Only one writer may acquire the lock as long as the reader count is zero.
970 static inline void rwref_write_get(struct rwref_lock *lock_ptr)
974 BUG_ON(lock_ptr == NULL);
976 kref_get(&lock_ptr->kref);
978 spin_lock_irqsave(&lock_ptr->lock, flags);
979 if (lock_ptr->read_count == 0 && lock_ptr->write_count == 0) {
980 lock_ptr->write_count++;
981 spin_unlock_irqrestore(&lock_ptr->lock, flags);
984 spin_unlock_irqrestore(&lock_ptr->lock, flags);
985 wait_for_completion(&lock_ptr->count_zero);
990 * rwref_write_put() - returns a reference count for a write operation
991 * lock_ptr: pointer to lock structure
993 * Must be preceded by a call to rwref_write_get().
995 static inline void rwref_write_put(struct rwref_lock *lock_ptr)
999 BUG_ON(lock_ptr == NULL);
1001 spin_lock_irqsave(&lock_ptr->lock, flags);
1002 BUG_ON(lock_ptr->write_count != 1);
1003 if (--lock_ptr->write_count == 0)
1004 complete(&lock_ptr->count_zero);
1005 spin_unlock_irqrestore(&lock_ptr->lock, flags);
1006 kref_put(&lock_ptr->kref, rwref_lock_release);
1009 #endif /* _SOC_QCOM_GLINK_PRIVATE_H_ */