@@ -97,6 +97,13 @@ struct vchiq_arm_state {
9797 * tracked separately with the state.
9898 */
9999 int peer_use_count ;
100+
101+ /*
102+ * Flag to indicate that the first vchiq connect has made it through.
103+ * This means that both sides should be fully ready, and we should
104+ * be able to suspend after this point.
105+ */
106+ int first_connect ;
100107};
101108
102109static int
@@ -273,6 +280,29 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state
273280 return 0 ;
274281}
275282
283+ int
284+ vchiq_platform_init_state (struct vchiq_state * state )
285+ {
286+ struct vchiq_arm_state * platform_state ;
287+
288+ platform_state = devm_kzalloc (state -> dev , sizeof (* platform_state ), GFP_KERNEL );
289+ if (!platform_state )
290+ return - ENOMEM ;
291+
292+ rwlock_init (& platform_state -> susp_res_lock );
293+
294+ init_completion (& platform_state -> ka_evt );
295+ atomic_set (& platform_state -> ka_use_count , 0 );
296+ atomic_set (& platform_state -> ka_use_ack_count , 0 );
297+ atomic_set (& platform_state -> ka_release_count , 0 );
298+
299+ platform_state -> state = state ;
300+
301+ state -> platform_state = (struct opaque_platform_state * )platform_state ;
302+
303+ return 0 ;
304+ }
305+
276306static struct vchiq_arm_state * vchiq_platform_get_arm_state (struct vchiq_state * state )
277307{
278308 return (struct vchiq_arm_state * )state -> platform_state ;
@@ -363,8 +393,7 @@ int vchiq_shutdown(struct vchiq_instance *instance)
363393 struct vchiq_state * state = instance -> state ;
364394 int ret = 0 ;
365395
366- if (mutex_lock_killable (& state -> mutex ))
367- return - EAGAIN ;
396+ mutex_lock (& state -> mutex );
368397
369398 /* Remove all services */
370399 vchiq_shutdown_internal (state , instance );
@@ -981,39 +1010,6 @@ vchiq_keepalive_thread_func(void *v)
9811010 return 0 ;
9821011}
9831012
984- int
985- vchiq_platform_init_state (struct vchiq_state * state )
986- {
987- struct vchiq_arm_state * platform_state ;
988- char threadname [16 ];
989-
990- platform_state = devm_kzalloc (state -> dev , sizeof (* platform_state ), GFP_KERNEL );
991- if (!platform_state )
992- return - ENOMEM ;
993-
994- snprintf (threadname , sizeof (threadname ), "vchiq-keep/%d" ,
995- state -> id );
996- platform_state -> ka_thread = kthread_create (& vchiq_keepalive_thread_func ,
997- (void * )state , threadname );
998- if (IS_ERR (platform_state -> ka_thread )) {
999- dev_err (state -> dev , "couldn't create thread %s\n" , threadname );
1000- return PTR_ERR (platform_state -> ka_thread );
1001- }
1002-
1003- rwlock_init (& platform_state -> susp_res_lock );
1004-
1005- init_completion (& platform_state -> ka_evt );
1006- atomic_set (& platform_state -> ka_use_count , 0 );
1007- atomic_set (& platform_state -> ka_use_ack_count , 0 );
1008- atomic_set (& platform_state -> ka_release_count , 0 );
1009-
1010- platform_state -> state = state ;
1011-
1012- state -> platform_state = (struct opaque_platform_state * )platform_state ;
1013-
1014- return 0 ;
1015- }
1016-
10171013int
10181014vchiq_use_internal (struct vchiq_state * state , struct vchiq_service * service ,
10191015 enum USE_TYPE_E use_type )
@@ -1329,19 +1325,37 @@ vchiq_check_service(struct vchiq_service *service)
13291325 return ret ;
13301326}
13311327
1332- void vchiq_platform_connected (struct vchiq_state * state )
1333- {
1334- struct vchiq_arm_state * arm_state = vchiq_platform_get_arm_state (state );
1335-
1336- wake_up_process (arm_state -> ka_thread );
1337- }
1338-
13391328void vchiq_platform_conn_state_changed (struct vchiq_state * state ,
13401329 enum vchiq_connstate oldstate ,
13411330 enum vchiq_connstate newstate )
13421331{
1332+ struct vchiq_arm_state * arm_state = vchiq_platform_get_arm_state (state );
1333+ char threadname [16 ];
1334+
13431335 dev_dbg (state -> dev , "suspend: %d: %s->%s\n" ,
13441336 state -> id , get_conn_state_name (oldstate ), get_conn_state_name (newstate ));
1337+ if (state -> conn_state != VCHIQ_CONNSTATE_CONNECTED )
1338+ return ;
1339+
1340+ write_lock_bh (& arm_state -> susp_res_lock );
1341+ if (arm_state -> first_connect ) {
1342+ write_unlock_bh (& arm_state -> susp_res_lock );
1343+ return ;
1344+ }
1345+
1346+ arm_state -> first_connect = 1 ;
1347+ write_unlock_bh (& arm_state -> susp_res_lock );
1348+ snprintf (threadname , sizeof (threadname ), "vchiq-keep/%d" ,
1349+ state -> id );
1350+ arm_state -> ka_thread = kthread_create (& vchiq_keepalive_thread_func ,
1351+ (void * )state ,
1352+ threadname );
1353+ if (IS_ERR (arm_state -> ka_thread )) {
1354+ dev_err (state -> dev , "suspend: Couldn't create thread %s\n" ,
1355+ threadname );
1356+ } else {
1357+ wake_up_process (arm_state -> ka_thread );
1358+ }
13451359}
13461360
13471361static const struct of_device_id vchiq_of_match [] = {
0 commit comments