1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 /*
3  * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
4  * Copyright (c) 2010-2012 Broadcom. All rights reserved.
5  */
6 
7 #ifndef VCHIQ_ARM_H
8 #define VCHIQ_ARM_H
9 
10 #include <linux/mutex.h>
11 #include <linux/platform_device.h>
12 #include <linux/semaphore.h>
13 #include <linux/atomic.h>
14 #include "vchiq_core.h"
15 #include "vchiq_debugfs.h"
16 
17 enum vc_suspend_status {
18 	VC_SUSPEND_FORCE_CANCELED = -3, /* Force suspend canceled, too busy */
19 	VC_SUSPEND_REJECTED = -2,  /* Videocore rejected suspend request */
20 	VC_SUSPEND_FAILED = -1,    /* Videocore suspend failed */
21 	VC_SUSPEND_IDLE = 0,       /* VC active, no suspend actions */
22 	VC_SUSPEND_REQUESTED,      /* User has requested suspend */
23 	VC_SUSPEND_IN_PROGRESS,    /* Slot handler has recvd suspend request */
24 	VC_SUSPEND_SUSPENDED       /* Videocore suspend succeeded */
25 };
26 
27 enum vc_resume_status {
28 	VC_RESUME_FAILED = -1, /* Videocore resume failed */
29 	VC_RESUME_IDLE = 0,    /* VC suspended, no resume actions */
30 	VC_RESUME_REQUESTED,   /* User has requested resume */
31 	VC_RESUME_IN_PROGRESS, /* Slot handler has received resume request */
32 	VC_RESUME_RESUMED      /* Videocore resumed successfully (active) */
33 };
34 
35 enum USE_TYPE_E {
36 	USE_TYPE_SERVICE,
37 	USE_TYPE_SERVICE_NO_RESUME,
38 	USE_TYPE_VCHIQ
39 };
40 
41 struct vchiq_arm_state {
42 	/* Keepalive-related data */
43 	struct task_struct *ka_thread;
44 	struct completion ka_evt;
45 	atomic_t ka_use_count;
46 	atomic_t ka_use_ack_count;
47 	atomic_t ka_release_count;
48 
49 	struct completion vc_suspend_complete;
50 	struct completion vc_resume_complete;
51 
52 	rwlock_t susp_res_lock;
53 	enum vc_suspend_status vc_suspend_state;
54 	enum vc_resume_status vc_resume_state;
55 
56 	struct vchiq_state *state;
57 	struct timer_list suspend_timer;
58 	int suspend_timer_timeout;
59 	int suspend_timer_running;
60 
61 	/* Global use count for videocore.
62 	** This is equal to the sum of the use counts for all services.  When
63 	** this hits zero the videocore suspend procedure will be initiated.
64 	*/
65 	int videocore_use_count;
66 
67 	/* Use count to track requests from videocore peer.
68 	** This use count is not associated with a service, so needs to be
69 	** tracked separately with the state.
70 	*/
71 	int peer_use_count;
72 
73 	int blocked_count;
74 
75 	/* Flag to indicate that the first vchiq connect has made it through.
76 	** This means that both sides should be fully ready, and we should
77 	** be able to suspend after this point.
78 	*/
79 	int first_connect;
80 };
81 
82 struct vchiq_drvdata {
83 	const unsigned int cache_line_size;
84 	struct rpi_firmware *fw;
85 };
86 
87 extern int vchiq_arm_log_level;
88 extern int vchiq_susp_log_level;
89 
90 int vchiq_platform_init(struct platform_device *pdev,
91 			struct vchiq_state *state);
92 
93 extern struct vchiq_state *
94 vchiq_get_state(void);
95 
96 extern enum vchiq_status
97 vchiq_arm_vcsuspend(struct vchiq_state *state);
98 
99 extern enum vchiq_status
100 vchiq_arm_vcresume(struct vchiq_state *state);
101 
102 extern enum vchiq_status
103 vchiq_arm_init_state(struct vchiq_state *state,
104 		     struct vchiq_arm_state *arm_state);
105 
106 extern int
107 vchiq_check_resume(struct vchiq_state *state);
108 
109 extern void
110 vchiq_check_suspend(struct vchiq_state *state);
111 enum vchiq_status
112 vchiq_use_service(unsigned int handle);
113 
114 extern enum vchiq_status
115 vchiq_release_service(unsigned int handle);
116 
117 extern enum vchiq_status
118 vchiq_check_service(struct vchiq_service *service);
119 
120 extern enum vchiq_status
121 vchiq_platform_suspend(struct vchiq_state *state);
122 
123 extern int
124 vchiq_platform_videocore_wanted(struct vchiq_state *state);
125 
126 extern int
127 vchiq_platform_use_suspend_timer(void);
128 
129 extern void
130 vchiq_dump_platform_use_state(struct vchiq_state *state);
131 
132 extern void
133 vchiq_dump_service_use_state(struct vchiq_state *state);
134 
135 extern struct vchiq_arm_state*
136 vchiq_platform_get_arm_state(struct vchiq_state *state);
137 
138 extern int
139 vchiq_videocore_wanted(struct vchiq_state *state);
140 
141 extern enum vchiq_status
142 vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
143 		   enum USE_TYPE_E use_type);
144 extern enum vchiq_status
145 vchiq_release_internal(struct vchiq_state *state,
146 		       struct vchiq_service *service);
147 
148 extern struct vchiq_debugfs_node *
149 vchiq_instance_get_debugfs_node(struct vchiq_instance *instance);
150 
151 extern int
152 vchiq_instance_get_use_count(struct vchiq_instance *instance);
153 
154 extern int
155 vchiq_instance_get_pid(struct vchiq_instance *instance);
156 
157 extern int
158 vchiq_instance_get_trace(struct vchiq_instance *instance);
159 
160 extern void
161 vchiq_instance_set_trace(struct vchiq_instance *instance, int trace);
162 
163 extern void
164 set_suspend_state(struct vchiq_arm_state *arm_state,
165 		  enum vc_suspend_status new_state);
166 
167 extern void
168 set_resume_state(struct vchiq_arm_state *arm_state,
169 		 enum vc_resume_status new_state);
170 
171 extern void
172 start_suspend_timer(struct vchiq_arm_state *arm_state);
173 
174 #endif /* VCHIQ_ARM_H */
175