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 unsigned int wake_address; 57 58 struct vchiq_state *state; 59 struct timer_list suspend_timer; 60 int suspend_timer_timeout; 61 int suspend_timer_running; 62 63 /* Global use count for videocore. 64 ** This is equal to the sum of the use counts for all services. When 65 ** this hits zero the videocore suspend procedure will be initiated. 66 */ 67 int videocore_use_count; 68 69 /* Use count to track requests from videocore peer. 70 ** This use count is not associated with a service, so needs to be 71 ** tracked separately with the state. 72 */ 73 int peer_use_count; 74 75 /* Flag to indicate whether resume is blocked. This happens when the 76 ** ARM is suspending 77 */ 78 struct completion resume_blocker; 79 int resume_blocked; 80 struct completion blocked_blocker; 81 int blocked_count; 82 83 int autosuspend_override; 84 85 /* Flag to indicate that the first vchiq connect has made it through. 86 ** This means that both sides should be fully ready, and we should 87 ** be able to suspend after this point. 88 */ 89 int first_connect; 90 91 unsigned long long suspend_start_time; 92 unsigned long long sleep_start_time; 93 unsigned long long resume_start_time; 94 unsigned long long last_wake_time; 95 96 }; 97 98 struct vchiq_drvdata { 99 const unsigned int cache_line_size; 100 struct rpi_firmware *fw; 101 }; 102 103 extern int vchiq_arm_log_level; 104 extern int vchiq_susp_log_level; 105 106 int vchiq_platform_init(struct platform_device *pdev, 107 struct vchiq_state *state); 108 109 extern struct vchiq_state * 110 vchiq_get_state(void); 111 112 extern VCHIQ_STATUS_T 113 vchiq_arm_vcsuspend(struct vchiq_state *state); 114 115 extern VCHIQ_STATUS_T 116 vchiq_arm_force_suspend(struct vchiq_state *state); 117 118 extern int 119 vchiq_arm_allow_resume(struct vchiq_state *state); 120 121 extern VCHIQ_STATUS_T 122 vchiq_arm_vcresume(struct vchiq_state *state); 123 124 extern VCHIQ_STATUS_T 125 vchiq_arm_init_state(struct vchiq_state *state, 126 struct vchiq_arm_state *arm_state); 127 128 extern int 129 vchiq_check_resume(struct vchiq_state *state); 130 131 extern void 132 vchiq_check_suspend(struct vchiq_state *state); 133 VCHIQ_STATUS_T 134 vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle); 135 136 extern VCHIQ_STATUS_T 137 vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle); 138 139 extern VCHIQ_STATUS_T 140 vchiq_check_service(struct vchiq_service *service); 141 142 extern VCHIQ_STATUS_T 143 vchiq_platform_suspend(struct vchiq_state *state); 144 145 extern int 146 vchiq_platform_videocore_wanted(struct vchiq_state *state); 147 148 extern int 149 vchiq_platform_use_suspend_timer(void); 150 151 extern void 152 vchiq_dump_platform_use_state(struct vchiq_state *state); 153 154 extern void 155 vchiq_dump_service_use_state(struct vchiq_state *state); 156 157 extern struct vchiq_arm_state* 158 vchiq_platform_get_arm_state(struct vchiq_state *state); 159 160 extern int 161 vchiq_videocore_wanted(struct vchiq_state *state); 162 163 extern VCHIQ_STATUS_T 164 vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, 165 enum USE_TYPE_E use_type); 166 extern VCHIQ_STATUS_T 167 vchiq_release_internal(struct vchiq_state *state, 168 struct vchiq_service *service); 169 170 extern struct vchiq_debugfs_node * 171 vchiq_instance_get_debugfs_node(VCHIQ_INSTANCE_T instance); 172 173 extern int 174 vchiq_instance_get_use_count(VCHIQ_INSTANCE_T instance); 175 176 extern int 177 vchiq_instance_get_pid(VCHIQ_INSTANCE_T instance); 178 179 extern int 180 vchiq_instance_get_trace(VCHIQ_INSTANCE_T instance); 181 182 extern void 183 vchiq_instance_set_trace(VCHIQ_INSTANCE_T instance, int trace); 184 185 extern void 186 set_suspend_state(struct vchiq_arm_state *arm_state, 187 enum vc_suspend_status new_state); 188 189 extern void 190 set_resume_state(struct vchiq_arm_state *arm_state, 191 enum vc_resume_status new_state); 192 193 extern void 194 start_suspend_timer(struct vchiq_arm_state *arm_state); 195 196 #endif /* VCHIQ_ARM_H */ 197