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 	/* Flag to indicate that the first vchiq connect has made it through.
74 	** This means that both sides should be fully ready, and we should
75 	** be able to suspend after this point.
76 	*/
77 	int first_connect;
78 };
79 
80 struct vchiq_drvdata {
81 	const unsigned int cache_line_size;
82 	struct rpi_firmware *fw;
83 };
84 
85 extern int vchiq_arm_log_level;
86 extern int vchiq_susp_log_level;
87 
88 int vchiq_platform_init(struct platform_device *pdev,
89 			struct vchiq_state *state);
90 
91 extern struct vchiq_state *
92 vchiq_get_state(void);
93 
94 extern enum vchiq_status
95 vchiq_arm_vcsuspend(struct vchiq_state *state);
96 
97 extern enum vchiq_status
98 vchiq_arm_vcresume(struct vchiq_state *state);
99 
100 extern enum vchiq_status
101 vchiq_arm_init_state(struct vchiq_state *state,
102 		     struct vchiq_arm_state *arm_state);
103 
104 extern int
105 vchiq_check_resume(struct vchiq_state *state);
106 
107 extern void
108 vchiq_check_suspend(struct vchiq_state *state);
109 enum vchiq_status
110 vchiq_use_service(unsigned int handle);
111 
112 extern enum vchiq_status
113 vchiq_release_service(unsigned int handle);
114 
115 extern enum vchiq_status
116 vchiq_check_service(struct vchiq_service *service);
117 
118 extern enum vchiq_status
119 vchiq_platform_suspend(struct vchiq_state *state);
120 
121 extern int
122 vchiq_platform_videocore_wanted(struct vchiq_state *state);
123 
124 extern int
125 vchiq_platform_use_suspend_timer(void);
126 
127 extern void
128 vchiq_dump_platform_use_state(struct vchiq_state *state);
129 
130 extern void
131 vchiq_dump_service_use_state(struct vchiq_state *state);
132 
133 extern struct vchiq_arm_state*
134 vchiq_platform_get_arm_state(struct vchiq_state *state);
135 
136 extern int
137 vchiq_videocore_wanted(struct vchiq_state *state);
138 
139 extern enum vchiq_status
140 vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
141 		   enum USE_TYPE_E use_type);
142 extern enum vchiq_status
143 vchiq_release_internal(struct vchiq_state *state,
144 		       struct vchiq_service *service);
145 
146 extern struct vchiq_debugfs_node *
147 vchiq_instance_get_debugfs_node(struct vchiq_instance *instance);
148 
149 extern int
150 vchiq_instance_get_use_count(struct vchiq_instance *instance);
151 
152 extern int
153 vchiq_instance_get_pid(struct vchiq_instance *instance);
154 
155 extern int
156 vchiq_instance_get_trace(struct vchiq_instance *instance);
157 
158 extern void
159 vchiq_instance_set_trace(struct vchiq_instance *instance, int trace);
160 
161 extern void
162 set_suspend_state(struct vchiq_arm_state *arm_state,
163 		  enum vc_suspend_status new_state);
164 
165 extern void
166 set_resume_state(struct vchiq_arm_state *arm_state,
167 		 enum vc_resume_status new_state);
168 
169 extern void
170 start_suspend_timer(struct vchiq_arm_state *arm_state);
171 
172 #endif /* VCHIQ_ARM_H */
173