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_resume_complete;
50 
51 	rwlock_t susp_res_lock;
52 	enum vc_suspend_status vc_suspend_state;
53 	enum vc_resume_status vc_resume_state;
54 
55 	struct vchiq_state *state;
56 
57 	/* Global use count for videocore.
58 	** This is equal to the sum of the use counts for all services.  When
59 	** this hits zero the videocore suspend procedure will be initiated.
60 	*/
61 	int videocore_use_count;
62 
63 	/* Use count to track requests from videocore peer.
64 	** This use count is not associated with a service, so needs to be
65 	** tracked separately with the state.
66 	*/
67 	int peer_use_count;
68 
69 	/* Flag to indicate that the first vchiq connect has made it through.
70 	** This means that both sides should be fully ready, and we should
71 	** be able to suspend after this point.
72 	*/
73 	int first_connect;
74 };
75 
76 struct vchiq_drvdata {
77 	const unsigned int cache_line_size;
78 	struct rpi_firmware *fw;
79 };
80 
81 extern int vchiq_arm_log_level;
82 extern int vchiq_susp_log_level;
83 
84 int vchiq_platform_init(struct platform_device *pdev,
85 			struct vchiq_state *state);
86 
87 extern struct vchiq_state *
88 vchiq_get_state(void);
89 
90 extern enum vchiq_status
91 vchiq_arm_vcresume(struct vchiq_state *state);
92 
93 extern enum vchiq_status
94 vchiq_arm_init_state(struct vchiq_state *state,
95 		     struct vchiq_arm_state *arm_state);
96 
97 extern void
98 vchiq_check_suspend(struct vchiq_state *state);
99 enum vchiq_status
100 vchiq_use_service(unsigned int handle);
101 
102 extern enum vchiq_status
103 vchiq_release_service(unsigned int handle);
104 
105 extern enum vchiq_status
106 vchiq_check_service(struct vchiq_service *service);
107 
108 extern void
109 vchiq_dump_platform_use_state(struct vchiq_state *state);
110 
111 extern void
112 vchiq_dump_service_use_state(struct vchiq_state *state);
113 
114 extern struct vchiq_arm_state*
115 vchiq_platform_get_arm_state(struct vchiq_state *state);
116 
117 
118 extern enum vchiq_status
119 vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
120 		   enum USE_TYPE_E use_type);
121 extern enum vchiq_status
122 vchiq_release_internal(struct vchiq_state *state,
123 		       struct vchiq_service *service);
124 
125 extern struct vchiq_debugfs_node *
126 vchiq_instance_get_debugfs_node(struct vchiq_instance *instance);
127 
128 extern int
129 vchiq_instance_get_use_count(struct vchiq_instance *instance);
130 
131 extern int
132 vchiq_instance_get_pid(struct vchiq_instance *instance);
133 
134 extern int
135 vchiq_instance_get_trace(struct vchiq_instance *instance);
136 
137 extern void
138 vchiq_instance_set_trace(struct vchiq_instance *instance, int trace);
139 
140 extern void
141 set_suspend_state(struct vchiq_arm_state *arm_state,
142 		  enum vc_suspend_status new_state);
143 
144 extern void
145 set_resume_state(struct vchiq_arm_state *arm_state,
146 		 enum vc_resume_status new_state);
147 
148 #endif /* VCHIQ_ARM_H */
149