popcornmix | 71bad7f | 2013-07-02 23:42:01 +0100 | [diff] [blame] | 1 | /** |
| 2 | * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. |
| 3 | * Copyright (c) 2010-2012 Broadcom. All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 8 | * 1. Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions, and the following disclaimer, |
| 10 | * without modification. |
| 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer in the |
| 13 | * documentation and/or other materials provided with the distribution. |
| 14 | * 3. The names of the above-listed copyright holders may not be used |
| 15 | * to endorse or promote products derived from this software without |
| 16 | * specific prior written permission. |
| 17 | * |
| 18 | * ALTERNATIVELY, this software may be distributed under the terms of the |
| 19 | * GNU General Public License ("GPL") version 2, as published by the Free |
| 20 | * Software Foundation. |
| 21 | * |
| 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
| 23 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 24 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 25 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| 26 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 27 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 28 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 29 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 33 | */ |
| 34 | |
| 35 | #ifndef VCHIQ_ARM_H |
| 36 | #define VCHIQ_ARM_H |
| 37 | |
| 38 | #include <linux/mutex.h> |
| 39 | #include <linux/platform_device.h> |
| 40 | #include <linux/semaphore.h> |
| 41 | #include <linux/atomic.h> |
| 42 | #include "vchiq_core.h" |
| 43 | #include "vchiq_debugfs.h" |
| 44 | |
| 45 | |
| 46 | enum vc_suspend_status { |
| 47 | VC_SUSPEND_FORCE_CANCELED = -3, /* Force suspend canceled, too busy */ |
| 48 | VC_SUSPEND_REJECTED = -2, /* Videocore rejected suspend request */ |
| 49 | VC_SUSPEND_FAILED = -1, /* Videocore suspend failed */ |
| 50 | VC_SUSPEND_IDLE = 0, /* VC active, no suspend actions */ |
| 51 | VC_SUSPEND_REQUESTED, /* User has requested suspend */ |
| 52 | VC_SUSPEND_IN_PROGRESS, /* Slot handler has recvd suspend request */ |
| 53 | VC_SUSPEND_SUSPENDED /* Videocore suspend succeeded */ |
| 54 | }; |
| 55 | |
| 56 | enum vc_resume_status { |
| 57 | VC_RESUME_FAILED = -1, /* Videocore resume failed */ |
| 58 | VC_RESUME_IDLE = 0, /* VC suspended, no resume actions */ |
| 59 | VC_RESUME_REQUESTED, /* User has requested resume */ |
| 60 | VC_RESUME_IN_PROGRESS, /* Slot handler has received resume request */ |
| 61 | VC_RESUME_RESUMED /* Videocore resumed successfully (active) */ |
| 62 | }; |
| 63 | |
| 64 | |
| 65 | enum USE_TYPE_E { |
| 66 | USE_TYPE_SERVICE, |
| 67 | USE_TYPE_SERVICE_NO_RESUME, |
| 68 | USE_TYPE_VCHIQ |
| 69 | }; |
| 70 | |
| 71 | |
| 72 | |
| 73 | typedef struct vchiq_arm_state_struct { |
| 74 | /* Keepalive-related data */ |
| 75 | struct task_struct *ka_thread; |
| 76 | struct completion ka_evt; |
| 77 | atomic_t ka_use_count; |
| 78 | atomic_t ka_use_ack_count; |
| 79 | atomic_t ka_release_count; |
| 80 | |
| 81 | struct completion vc_suspend_complete; |
| 82 | struct completion vc_resume_complete; |
| 83 | |
| 84 | rwlock_t susp_res_lock; |
| 85 | enum vc_suspend_status vc_suspend_state; |
| 86 | enum vc_resume_status vc_resume_state; |
| 87 | |
| 88 | unsigned int wake_address; |
| 89 | |
| 90 | struct timer_list suspend_timer; |
| 91 | int suspend_timer_timeout; |
| 92 | int suspend_timer_running; |
| 93 | |
| 94 | /* Global use count for videocore. |
| 95 | ** This is equal to the sum of the use counts for all services. When |
| 96 | ** this hits zero the videocore suspend procedure will be initiated. |
| 97 | */ |
| 98 | int videocore_use_count; |
| 99 | |
| 100 | /* Use count to track requests from videocore peer. |
| 101 | ** This use count is not associated with a service, so needs to be |
| 102 | ** tracked separately with the state. |
| 103 | */ |
| 104 | int peer_use_count; |
| 105 | |
| 106 | /* Flag to indicate whether resume is blocked. This happens when the |
| 107 | ** ARM is suspending |
| 108 | */ |
| 109 | struct completion resume_blocker; |
| 110 | int resume_blocked; |
| 111 | struct completion blocked_blocker; |
| 112 | int blocked_count; |
| 113 | |
| 114 | int autosuspend_override; |
| 115 | |
| 116 | /* Flag to indicate that the first vchiq connect has made it through. |
| 117 | ** This means that both sides should be fully ready, and we should |
| 118 | ** be able to suspend after this point. |
| 119 | */ |
| 120 | int first_connect; |
| 121 | |
| 122 | unsigned long long suspend_start_time; |
| 123 | unsigned long long sleep_start_time; |
| 124 | unsigned long long resume_start_time; |
| 125 | unsigned long long last_wake_time; |
| 126 | |
| 127 | } VCHIQ_ARM_STATE_T; |
| 128 | |
| 129 | extern int vchiq_arm_log_level; |
| 130 | extern int vchiq_susp_log_level; |
| 131 | |
| 132 | int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state); |
| 133 | |
| 134 | extern VCHIQ_STATE_T * |
| 135 | vchiq_get_state(void); |
| 136 | |
| 137 | extern VCHIQ_STATUS_T |
| 138 | vchiq_arm_vcsuspend(VCHIQ_STATE_T *state); |
| 139 | |
| 140 | extern VCHIQ_STATUS_T |
| 141 | vchiq_arm_force_suspend(VCHIQ_STATE_T *state); |
| 142 | |
| 143 | extern int |
| 144 | vchiq_arm_allow_resume(VCHIQ_STATE_T *state); |
| 145 | |
| 146 | extern VCHIQ_STATUS_T |
| 147 | vchiq_arm_vcresume(VCHIQ_STATE_T *state); |
| 148 | |
| 149 | extern VCHIQ_STATUS_T |
| 150 | vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state); |
| 151 | |
| 152 | extern int |
| 153 | vchiq_check_resume(VCHIQ_STATE_T *state); |
| 154 | |
| 155 | extern void |
| 156 | vchiq_check_suspend(VCHIQ_STATE_T *state); |
| 157 | VCHIQ_STATUS_T |
| 158 | vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle); |
| 159 | |
| 160 | extern VCHIQ_STATUS_T |
| 161 | vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle); |
| 162 | |
| 163 | extern VCHIQ_STATUS_T |
| 164 | vchiq_check_service(VCHIQ_SERVICE_T *service); |
| 165 | |
| 166 | extern VCHIQ_STATUS_T |
| 167 | vchiq_platform_suspend(VCHIQ_STATE_T *state); |
| 168 | |
| 169 | extern int |
| 170 | vchiq_platform_videocore_wanted(VCHIQ_STATE_T *state); |
| 171 | |
| 172 | extern int |
| 173 | vchiq_platform_use_suspend_timer(void); |
| 174 | |
| 175 | extern void |
| 176 | vchiq_dump_platform_use_state(VCHIQ_STATE_T *state); |
| 177 | |
| 178 | extern void |
| 179 | vchiq_dump_service_use_state(VCHIQ_STATE_T *state); |
| 180 | |
| 181 | extern VCHIQ_ARM_STATE_T* |
| 182 | vchiq_platform_get_arm_state(VCHIQ_STATE_T *state); |
| 183 | |
| 184 | extern int |
| 185 | vchiq_videocore_wanted(VCHIQ_STATE_T *state); |
| 186 | |
| 187 | extern VCHIQ_STATUS_T |
| 188 | vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, |
| 189 | enum USE_TYPE_E use_type); |
| 190 | extern VCHIQ_STATUS_T |
| 191 | vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service); |
| 192 | |
| 193 | extern VCHIQ_DEBUGFS_NODE_T * |
| 194 | vchiq_instance_get_debugfs_node(VCHIQ_INSTANCE_T instance); |
| 195 | |
| 196 | extern int |
| 197 | vchiq_instance_get_use_count(VCHIQ_INSTANCE_T instance); |
| 198 | |
| 199 | extern int |
| 200 | vchiq_instance_get_pid(VCHIQ_INSTANCE_T instance); |
| 201 | |
| 202 | extern int |
| 203 | vchiq_instance_get_trace(VCHIQ_INSTANCE_T instance); |
| 204 | |
| 205 | extern void |
| 206 | vchiq_instance_set_trace(VCHIQ_INSTANCE_T instance, int trace); |
| 207 | |
| 208 | extern void |
| 209 | set_suspend_state(VCHIQ_ARM_STATE_T *arm_state, |
| 210 | enum vc_suspend_status new_state); |
| 211 | |
| 212 | extern void |
| 213 | set_resume_state(VCHIQ_ARM_STATE_T *arm_state, |
| 214 | enum vc_resume_status new_state); |
| 215 | |
| 216 | extern void |
| 217 | start_suspend_timer(VCHIQ_ARM_STATE_T *arm_state); |
| 218 | |
| 219 | |
| 220 | #endif /* VCHIQ_ARM_H */ |