Deleted Added
full compact
vchiq_arm.c (278430) vchiq_arm.c (290245)
1/**
1/**
2 * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
2 * Copyright (c) 2010-2012 Broadcom. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions, and the following disclaimer,
9 * without modification.

--- 87 unchanged lines hidden (view full) ---

97static void vchiq_proc_remove_instance(VCHIQ_INSTANCE_T instance);
98#endif
99
100
101typedef struct user_service_struct {
102 VCHIQ_SERVICE_T *service;
103 void *userdata;
104 VCHIQ_INSTANCE_T instance;
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.

--- 87 unchanged lines hidden (view full) ---

98static void vchiq_proc_remove_instance(VCHIQ_INSTANCE_T instance);
99#endif
100
101
102typedef struct user_service_struct {
103 VCHIQ_SERVICE_T *service;
104 void *userdata;
105 VCHIQ_INSTANCE_T instance;
105 int is_vchi;
106 int dequeue_pending;
106 char is_vchi;
107 char dequeue_pending;
108 char close_pending;
107 int message_available_pos;
108 int msg_insert;
109 int msg_remove;
110 struct semaphore insert_event;
111 struct semaphore remove_event;
109 int message_available_pos;
110 int msg_insert;
111 int msg_remove;
112 struct semaphore insert_event;
113 struct semaphore remove_event;
114 struct semaphore close_event;
112 VCHIQ_HEADER_T * msg_queue[MSG_QUEUE_SIZE];
113} USER_SERVICE_T;
114
115struct bulk_waiter_node {
116 struct bulk_waiter bulk_waiter;
117 int pid;
118 struct list_head list;
119};

--- 6 unchanged lines hidden (view full) ---

126 struct semaphore insert_event;
127 struct semaphore remove_event;
128 struct mutex completion_mutex;
129
130 int connected;
131 int closing;
132 int pid;
133 int mark;
115 VCHIQ_HEADER_T * msg_queue[MSG_QUEUE_SIZE];
116} USER_SERVICE_T;
117
118struct bulk_waiter_node {
119 struct bulk_waiter bulk_waiter;
120 int pid;
121 struct list_head list;
122};

--- 6 unchanged lines hidden (view full) ---

129 struct semaphore insert_event;
130 struct semaphore remove_event;
131 struct mutex completion_mutex;
132
133 int connected;
134 int closing;
135 int pid;
136 int mark;
137 int use_close_delivered;
138 int trace;
134
135 struct list_head bulk_waiter_list;
136 struct mutex bulk_waiter_list_mutex;
137
139
140 struct list_head bulk_waiter_list;
141 struct mutex bulk_waiter_list_mutex;
142
138 struct proc_dir_entry *proc_entry;
143#ifdef notyet
144 VCHIQ_DEBUGFS_NODE_T proc_entry;
145#endif
139};
140
141typedef struct dump_context_struct {
142 char __user *buf;
143 size_t actual;
144 size_t space;
145 loff_t offset;
146} DUMP_CONTEXT_T;

--- 13 unchanged lines hidden (view full) ---

160 "AWAIT_COMPLETION",
161 "DEQUEUE_MESSAGE",
162 "GET_CLIENT_ID",
163 "GET_CONFIG",
164 "CLOSE_SERVICE",
165 "USE_SERVICE",
166 "RELEASE_SERVICE",
167 "SET_SERVICE_OPTION",
146};
147
148typedef struct dump_context_struct {
149 char __user *buf;
150 size_t actual;
151 size_t space;
152 loff_t offset;
153} DUMP_CONTEXT_T;

--- 13 unchanged lines hidden (view full) ---

167 "AWAIT_COMPLETION",
168 "DEQUEUE_MESSAGE",
169 "GET_CLIENT_ID",
170 "GET_CONFIG",
171 "CLOSE_SERVICE",
172 "USE_SERVICE",
173 "RELEASE_SERVICE",
174 "SET_SERVICE_OPTION",
168 "DUMP_PHYS_MEM"
175 "DUMP_PHYS_MEM",
176 "LIB_VERSION",
177 "CLOSE_DELIVERED"
169};
170
171vchiq_static_assert((sizeof(ioctl_names)/sizeof(ioctl_names[0])) ==
172 (VCHIQ_IOC_MAX + 1));
173
174static eventhandler_tag vchiq_ehtag = NULL;
175static d_open_t vchiq_open;
176static d_close_t vchiq_close;

--- 50 unchanged lines hidden (view full) ---

227 (MAX_COMPLETIONS - 1)];
228
229 completion->header = header;
230 completion->reason = reason;
231 /* N.B. service_userdata is updated while processing AWAIT_COMPLETION */
232 completion->service_userdata = user_service->service;
233 completion->bulk_userdata = bulk_userdata;
234
178};
179
180vchiq_static_assert((sizeof(ioctl_names)/sizeof(ioctl_names[0])) ==
181 (VCHIQ_IOC_MAX + 1));
182
183static eventhandler_tag vchiq_ehtag = NULL;
184static d_open_t vchiq_open;
185static d_close_t vchiq_close;

--- 50 unchanged lines hidden (view full) ---

236 (MAX_COMPLETIONS - 1)];
237
238 completion->header = header;
239 completion->reason = reason;
240 /* N.B. service_userdata is updated while processing AWAIT_COMPLETION */
241 completion->service_userdata = user_service->service;
242 completion->bulk_userdata = bulk_userdata;
243
235 if (reason == VCHIQ_SERVICE_CLOSED)
244 if (reason == VCHIQ_SERVICE_CLOSED) {
236 /* Take an extra reference, to be held until
237 this CLOSED notification is delivered. */
238 lock_service(user_service->service);
245 /* Take an extra reference, to be held until
246 this CLOSED notification is delivered. */
247 lock_service(user_service->service);
248 if (instance->use_close_delivered)
249 user_service->close_pending = 1;
250 }
239
240 /* A write barrier is needed here to ensure that the entire completion
241 record is written out before the insert point. */
242 wmb();
243
244 if (reason == VCHIQ_MESSAGE_AVAILABLE)
245 user_service->message_available_pos =
246 instance->completion_insert;

--- 30 unchanged lines hidden (view full) ---

277 BUG_ON(!service);
278 user_service = (USER_SERVICE_T *)service->base.userdata;
279 instance = user_service->instance;
280
281 if (!instance || instance->closing)
282 return VCHIQ_SUCCESS;
283
284 vchiq_log_trace(vchiq_arm_log_level,
251
252 /* A write barrier is needed here to ensure that the entire completion
253 record is written out before the insert point. */
254 wmb();
255
256 if (reason == VCHIQ_MESSAGE_AVAILABLE)
257 user_service->message_available_pos =
258 instance->completion_insert;

--- 30 unchanged lines hidden (view full) ---

289 BUG_ON(!service);
290 user_service = (USER_SERVICE_T *)service->base.userdata;
291 instance = user_service->instance;
292
293 if (!instance || instance->closing)
294 return VCHIQ_SUCCESS;
295
296 vchiq_log_trace(vchiq_arm_log_level,
285 "service_callback - service %lx(%d), handle %x, reason %d, header %lx, "
297 "service_callback - service %lx(%d,%p), reason %d, header %lx, "
286 "instance %lx, bulk_userdata %lx",
287 (unsigned long)user_service,
298 "instance %lx, bulk_userdata %lx",
299 (unsigned long)user_service,
288 service->localport, service->handle,
300 service->localport, user_service->userdata,
289 reason, (unsigned long)header,
290 (unsigned long)instance, (unsigned long)bulk_userdata);
291
292 if (header && user_service->is_vchi) {
293 spin_lock(&msg_queue_spinlock);
294 while (user_service->msg_insert ==
295 (user_service->msg_remove + MSG_QUEUE_SIZE)) {
296 spin_unlock(&msg_queue_spinlock);

--- 75 unchanged lines hidden (view full) ---

372 _sema_destroy(&user_service->insert_event);
373 _sema_destroy(&user_service->remove_event);
374
375 kfree(user_service);
376}
377
378/****************************************************************************
379*
301 reason, (unsigned long)header,
302 (unsigned long)instance, (unsigned long)bulk_userdata);
303
304 if (header && user_service->is_vchi) {
305 spin_lock(&msg_queue_spinlock);
306 while (user_service->msg_insert ==
307 (user_service->msg_remove + MSG_QUEUE_SIZE)) {
308 spin_unlock(&msg_queue_spinlock);

--- 75 unchanged lines hidden (view full) ---

384 _sema_destroy(&user_service->insert_event);
385 _sema_destroy(&user_service->remove_event);
386
387 kfree(user_service);
388}
389
390/****************************************************************************
391*
392* close_delivered
393*
394***************************************************************************/
395static void close_delivered(USER_SERVICE_T *user_service)
396{
397 vchiq_log_info(vchiq_arm_log_level,
398 "close_delivered(handle=%x)",
399 user_service->service->handle);
400
401 if (user_service->close_pending) {
402 /* Allow the underlying service to be culled */
403 unlock_service(user_service->service);
404
405 /* Wake the user-thread blocked in close_ or remove_service */
406 up(&user_service->close_event);
407
408 user_service->close_pending = 0;
409 }
410}
411
412/****************************************************************************
413*
380* vchiq_ioctl
381*
382***************************************************************************/
383
384static int
385vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag,
386 struct thread *td)
387{

--- 103 unchanged lines hidden (view full) ---

491 instance->state,
492 &args.params, srvstate,
493 instance, user_service_free);
494
495 if (service != NULL) {
496 user_service->service = service;
497 user_service->userdata = userdata;
498 user_service->instance = instance;
414* vchiq_ioctl
415*
416***************************************************************************/
417
418static int
419vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag,
420 struct thread *td)
421{

--- 103 unchanged lines hidden (view full) ---

525 instance->state,
526 &args.params, srvstate,
527 instance, user_service_free);
528
529 if (service != NULL) {
530 user_service->service = service;
531 user_service->userdata = userdata;
532 user_service->instance = instance;
499 user_service->is_vchi = args.is_vchi;
533 user_service->is_vchi = (args.is_vchi != 0);
500 user_service->dequeue_pending = 0;
534 user_service->dequeue_pending = 0;
535 user_service->close_pending = 0;
501 user_service->message_available_pos =
502 instance->completion_remove - 1;
503 user_service->msg_insert = 0;
504 user_service->msg_remove = 0;
505 _sema_init(&user_service->insert_event, 0);
506 _sema_init(&user_service->remove_event, 0);
536 user_service->message_available_pos =
537 instance->completion_remove - 1;
538 user_service->msg_insert = 0;
539 user_service->msg_remove = 0;
540 _sema_init(&user_service->insert_event, 0);
541 _sema_init(&user_service->remove_event, 0);
542 _sema_init(&user_service->close_event, 0);
507
508 if (args.is_open) {
509 status = vchiq_open_service_internal
510 (service, instance->pid);
511 if (status != VCHIQ_SUCCESS) {
512 vchiq_remove_service(service->handle);
513 service = NULL;
514 ret = (status == VCHIQ_RETRY) ?

--- 23 unchanged lines hidden (view full) ---

538
539 memcpy(&handle, (const void*)arg, sizeof(handle));
540
541#ifdef VCHIQ_IOCTL_DEBUG
542 printf("%s: [CLOSE SERVICE] handle = %08x\n", __func__, handle);
543#endif
544
545 service = find_service_for_instance(instance, handle);
543
544 if (args.is_open) {
545 status = vchiq_open_service_internal
546 (service, instance->pid);
547 if (status != VCHIQ_SUCCESS) {
548 vchiq_remove_service(service->handle);
549 service = NULL;
550 ret = (status == VCHIQ_RETRY) ?

--- 23 unchanged lines hidden (view full) ---

574
575 memcpy(&handle, (const void*)arg, sizeof(handle));
576
577#ifdef VCHIQ_IOCTL_DEBUG
578 printf("%s: [CLOSE SERVICE] handle = %08x\n", __func__, handle);
579#endif
580
581 service = find_service_for_instance(instance, handle);
546 if (service != NULL)
547 status = vchiq_close_service(service->handle);
582 if (service != NULL) {
583 USER_SERVICE_T *user_service =
584 (USER_SERVICE_T *)service->base.userdata;
585 /* close_pending is false on first entry, and when the
586 wait in vchiq_close_service has been interrupted. */
587 if (!user_service->close_pending) {
588 status = vchiq_close_service(service->handle);
589 if (status != VCHIQ_SUCCESS)
590 break;
591 }
592
593 /* close_pending is true once the underlying service
594 has been closed until the client library calls the
595 CLOSE_DELIVERED ioctl, signalling close_event. */
596 if (user_service->close_pending &&
597 down_interruptible(&user_service->close_event))
598 status = VCHIQ_RETRY;
599 }
548 else
549 ret = -EINVAL;
550 } break;
551
552 case VCHIQ_IOC_REMOVE_SERVICE: {
553 VCHIQ_SERVICE_HANDLE_T handle;
554
555 memcpy(&handle, (const void*)arg, sizeof(handle));
556
557#ifdef VCHIQ_IOCTL_DEBUG
558 printf("%s: [REMOVE SERVICE] handle = %08x\n", __func__, handle);
559#endif
560
561 service = find_service_for_instance(instance, handle);
600 else
601 ret = -EINVAL;
602 } break;
603
604 case VCHIQ_IOC_REMOVE_SERVICE: {
605 VCHIQ_SERVICE_HANDLE_T handle;
606
607 memcpy(&handle, (const void*)arg, sizeof(handle));
608
609#ifdef VCHIQ_IOCTL_DEBUG
610 printf("%s: [REMOVE SERVICE] handle = %08x\n", __func__, handle);
611#endif
612
613 service = find_service_for_instance(instance, handle);
562 if (service != NULL)
563 status = vchiq_remove_service(service->handle);
614 if (service != NULL) {
615 USER_SERVICE_T *user_service =
616 (USER_SERVICE_T *)service->base.userdata;
617 /* close_pending is false on first entry, and when the
618 wait in vchiq_close_service has been interrupted. */
619 if (!user_service->close_pending) {
620 status = vchiq_remove_service(service->handle);
621 if (status != VCHIQ_SUCCESS)
622 break;
623 }
624
625 /* close_pending is true once the underlying service
626 has been closed until the client library calls the
627 CLOSE_DELIVERED ioctl, signalling close_event. */
628 if (user_service->close_pending &&
629 down_interruptible(&user_service->close_event))
630 status = VCHIQ_RETRY;
631 }
564 else
565 ret = -EINVAL;
566 } break;
567
568 case VCHIQ_IOC_USE_SERVICE:
569 case VCHIQ_IOC_RELEASE_SERVICE: {
570 VCHIQ_SERVICE_HANDLE_T handle;
571

--- 247 unchanged lines hidden (view full) ---

819 vchiq_release_message(service1->handle,
820 header);
821
822 /* The completion must point to the
823 ** msgbuf. */
824 completion->header = msgbuf;
825 }
826
632 else
633 ret = -EINVAL;
634 } break;
635
636 case VCHIQ_IOC_USE_SERVICE:
637 case VCHIQ_IOC_RELEASE_SERVICE: {
638 VCHIQ_SERVICE_HANDLE_T handle;
639

--- 247 unchanged lines hidden (view full) ---

887 vchiq_release_message(service1->handle,
888 header);
889
890 /* The completion must point to the
891 ** msgbuf. */
892 completion->header = msgbuf;
893 }
894
827 if (completion->reason ==
828 VCHIQ_SERVICE_CLOSED)
895 if ((completion->reason ==
896 VCHIQ_SERVICE_CLOSED) &&
897 !instance->use_close_delivered)
829 unlock_service(service1);
830
831 if (copy_to_user((void __user *)(
832 (size_t)args.buf +
833 count * sizeof(VCHIQ_COMPLETION_DATA_T)),
834 completion,
835 sizeof(VCHIQ_COMPLETION_DATA_T)) != 0) {
836 if (ret == 0)

--- 165 unchanged lines hidden (view full) ---

1002
1003 memcpy(&args, (const void*)arg, sizeof(args));
1004 printf("IMPLEMENT ME: %s:%d\n", __FILE__, __LINE__);
1005#if 0
1006 dump_phys_mem(args.virt_addr, args.num_bytes);
1007#endif
1008 } break;
1009
898 unlock_service(service1);
899
900 if (copy_to_user((void __user *)(
901 (size_t)args.buf +
902 count * sizeof(VCHIQ_COMPLETION_DATA_T)),
903 completion,
904 sizeof(VCHIQ_COMPLETION_DATA_T)) != 0) {
905 if (ret == 0)

--- 165 unchanged lines hidden (view full) ---

1071
1072 memcpy(&args, (const void*)arg, sizeof(args));
1073 printf("IMPLEMENT ME: %s:%d\n", __FILE__, __LINE__);
1074#if 0
1075 dump_phys_mem(args.virt_addr, args.num_bytes);
1076#endif
1077 } break;
1078
1079 case VCHIQ_IOC_LIB_VERSION: {
1080 unsigned int lib_version = (unsigned int)arg;
1081
1082 if (lib_version < VCHIQ_VERSION_MIN)
1083 ret = -EINVAL;
1084 else if (lib_version >= VCHIQ_VERSION_CLOSE_DELIVERED)
1085 instance->use_close_delivered = 1;
1086 } break;
1087
1088 case VCHIQ_IOC_CLOSE_DELIVERED: {
1089 VCHIQ_SERVICE_HANDLE_T handle;
1090 memcpy(&handle, (const void*)arg, sizeof(handle));
1091
1092 service = find_closed_service_for_instance(instance, handle);
1093 if (service != NULL) {
1094 USER_SERVICE_T *user_service =
1095 (USER_SERVICE_T *)service->base.userdata;
1096 close_delivered(user_service);
1097 }
1098 else
1099 ret = -EINVAL;
1100 } break;
1101
1010 default:
1011 ret = -ENOTTY;
1012 break;
1013 }
1014
1015 if (service)
1016 unlock_service(service);
1017

--- 186 unchanged lines hidden (view full) ---

1204 instance->completion_insert) {
1205 VCHIQ_COMPLETION_DATA_T *completion;
1206 VCHIQ_SERVICE_T *service1;
1207 completion = &instance->completions[
1208 instance->completion_remove &
1209 (MAX_COMPLETIONS - 1)];
1210 service1 = completion->service_userdata;
1211 if (completion->reason == VCHIQ_SERVICE_CLOSED)
1102 default:
1103 ret = -ENOTTY;
1104 break;
1105 }
1106
1107 if (service)
1108 unlock_service(service);
1109

--- 186 unchanged lines hidden (view full) ---

1296 instance->completion_insert) {
1297 VCHIQ_COMPLETION_DATA_T *completion;
1298 VCHIQ_SERVICE_T *service1;
1299 completion = &instance->completions[
1300 instance->completion_remove &
1301 (MAX_COMPLETIONS - 1)];
1302 service1 = completion->service_userdata;
1303 if (completion->reason == VCHIQ_SERVICE_CLOSED)
1304 {
1305 USER_SERVICE_T *user_service =
1306 service->base.userdata;
1307
1308 /* Wake any blocked user-thread */
1309 if (instance->use_close_delivered)
1310 up(&user_service->close_event);
1212 unlock_service(service1);
1311 unlock_service(service1);
1312 }
1213 instance->completion_remove++;
1214 }
1215
1216 /* Release the PEER service count. */
1217 vchiq_release_internal(instance->state, NULL);
1218
1219 {
1220 struct list_head *pos, *next;

--- 478 unchanged lines hidden (view full) ---

1699** VC_RESUME_RESUMED - Resume has completed successfully. Videocore is running.
1700** Call complete_all on the resume completion to unblock
1701** any threads waiting for resume. Also reset the suspend
1702** state machine to it's idle state.
1703**
1704** VC_RESUME_FAILED - Currently unused - no mechanism to fail resume exists.
1705*/
1706
1313 instance->completion_remove++;
1314 }
1315
1316 /* Release the PEER service count. */
1317 vchiq_release_internal(instance->state, NULL);
1318
1319 {
1320 struct list_head *pos, *next;

--- 478 unchanged lines hidden (view full) ---

1799** VC_RESUME_RESUMED - Resume has completed successfully. Videocore is running.
1800** Call complete_all on the resume completion to unblock
1801** any threads waiting for resume. Also reset the suspend
1802** state machine to it's idle state.
1803**
1804** VC_RESUME_FAILED - Currently unused - no mechanism to fail resume exists.
1805*/
1806
1707inline void
1807void
1708set_suspend_state(VCHIQ_ARM_STATE_T *arm_state,
1709 enum vc_suspend_status new_state)
1710{
1711 /* set the state in all cases */
1712 arm_state->vc_suspend_state = new_state;
1713
1714 /* state specific additional actions */
1715 switch (new_state) {

--- 4 unchanged lines hidden (view full) ---

1720 complete_all(&arm_state->vc_suspend_complete);
1721 break;
1722 case VC_SUSPEND_FAILED:
1723 complete_all(&arm_state->vc_suspend_complete);
1724 arm_state->vc_resume_state = VC_RESUME_RESUMED;
1725 complete_all(&arm_state->vc_resume_complete);
1726 break;
1727 case VC_SUSPEND_IDLE:
1808set_suspend_state(VCHIQ_ARM_STATE_T *arm_state,
1809 enum vc_suspend_status new_state)
1810{
1811 /* set the state in all cases */
1812 arm_state->vc_suspend_state = new_state;
1813
1814 /* state specific additional actions */
1815 switch (new_state) {

--- 4 unchanged lines hidden (view full) ---

1820 complete_all(&arm_state->vc_suspend_complete);
1821 break;
1822 case VC_SUSPEND_FAILED:
1823 complete_all(&arm_state->vc_suspend_complete);
1824 arm_state->vc_resume_state = VC_RESUME_RESUMED;
1825 complete_all(&arm_state->vc_resume_complete);
1826 break;
1827 case VC_SUSPEND_IDLE:
1828 /* TODO: reinit_completion */
1728 INIT_COMPLETION(arm_state->vc_suspend_complete);
1729 break;
1730 case VC_SUSPEND_REQUESTED:
1731 break;
1732 case VC_SUSPEND_IN_PROGRESS:
1733 set_resume_state(arm_state, VC_RESUME_IDLE);
1734 break;
1735 case VC_SUSPEND_SUSPENDED:
1736 complete_all(&arm_state->vc_suspend_complete);
1737 break;
1738 default:
1739 BUG();
1740 break;
1741 }
1742}
1743
1829 INIT_COMPLETION(arm_state->vc_suspend_complete);
1830 break;
1831 case VC_SUSPEND_REQUESTED:
1832 break;
1833 case VC_SUSPEND_IN_PROGRESS:
1834 set_resume_state(arm_state, VC_RESUME_IDLE);
1835 break;
1836 case VC_SUSPEND_SUSPENDED:
1837 complete_all(&arm_state->vc_suspend_complete);
1838 break;
1839 default:
1840 BUG();
1841 break;
1842 }
1843}
1844
1744inline void
1845void
1745set_resume_state(VCHIQ_ARM_STATE_T *arm_state,
1746 enum vc_resume_status new_state)
1747{
1748 /* set the state in all cases */
1749 arm_state->vc_resume_state = new_state;
1750
1751 /* state specific additional actions */
1752 switch (new_state) {
1753 case VC_RESUME_FAILED:
1754 break;
1755 case VC_RESUME_IDLE:
1846set_resume_state(VCHIQ_ARM_STATE_T *arm_state,
1847 enum vc_resume_status new_state)
1848{
1849 /* set the state in all cases */
1850 arm_state->vc_resume_state = new_state;
1851
1852 /* state specific additional actions */
1853 switch (new_state) {
1854 case VC_RESUME_FAILED:
1855 break;
1856 case VC_RESUME_IDLE:
1857 /* TODO: reinit_completion */
1756 INIT_COMPLETION(arm_state->vc_resume_complete);
1757 break;
1758 case VC_RESUME_REQUESTED:
1759 break;
1760 case VC_RESUME_IN_PROGRESS:
1761 break;
1762 case VC_RESUME_RESUMED:
1763 complete_all(&arm_state->vc_resume_complete);

--- 46 unchanged lines hidden (view full) ---

1810 int resume_count = 0;
1811
1812 /* Allow any threads which were blocked by the last force suspend to
1813 * complete if they haven't already. Only give this one shot; if
1814 * blocked_count is incremented after blocked_blocker is completed
1815 * (which only happens when blocked_count hits 0) then those threads
1816 * will have to wait until next time around */
1817 if (arm_state->blocked_count) {
1858 INIT_COMPLETION(arm_state->vc_resume_complete);
1859 break;
1860 case VC_RESUME_REQUESTED:
1861 break;
1862 case VC_RESUME_IN_PROGRESS:
1863 break;
1864 case VC_RESUME_RESUMED:
1865 complete_all(&arm_state->vc_resume_complete);

--- 46 unchanged lines hidden (view full) ---

1912 int resume_count = 0;
1913
1914 /* Allow any threads which were blocked by the last force suspend to
1915 * complete if they haven't already. Only give this one shot; if
1916 * blocked_count is incremented after blocked_blocker is completed
1917 * (which only happens when blocked_count hits 0) then those threads
1918 * will have to wait until next time around */
1919 if (arm_state->blocked_count) {
1920 /* TODO: reinit_completion */
1818 INIT_COMPLETION(arm_state->blocked_blocker);
1819 write_unlock_bh(&arm_state->susp_res_lock);
1820 vchiq_log_info(vchiq_susp_log_level, "%s wait for previously "
1821 "blocked clients", __func__);
1822 if (wait_for_completion_interruptible_timeout(
1823 &arm_state->blocked_blocker, timeout_val)
1824 <= 0) {
1825 vchiq_log_error(vchiq_susp_log_level, "%s wait for "

--- 29 unchanged lines hidden (view full) ---

1855 status = VCHIQ_ERROR;
1856 write_lock_bh(&arm_state->susp_res_lock);
1857 goto out;
1858 }
1859 vchiq_log_info(vchiq_susp_log_level, "%s resumed", __func__);
1860 write_lock_bh(&arm_state->susp_res_lock);
1861 resume_count++;
1862 }
1921 INIT_COMPLETION(arm_state->blocked_blocker);
1922 write_unlock_bh(&arm_state->susp_res_lock);
1923 vchiq_log_info(vchiq_susp_log_level, "%s wait for previously "
1924 "blocked clients", __func__);
1925 if (wait_for_completion_interruptible_timeout(
1926 &arm_state->blocked_blocker, timeout_val)
1927 <= 0) {
1928 vchiq_log_error(vchiq_susp_log_level, "%s wait for "

--- 29 unchanged lines hidden (view full) ---

1958 status = VCHIQ_ERROR;
1959 write_lock_bh(&arm_state->susp_res_lock);
1960 goto out;
1961 }
1962 vchiq_log_info(vchiq_susp_log_level, "%s resumed", __func__);
1963 write_lock_bh(&arm_state->susp_res_lock);
1964 resume_count++;
1965 }
1966 /* TODO: reinit_completion */
1863 INIT_COMPLETION(arm_state->resume_blocker);
1864 arm_state->resume_blocked = 1;
1865
1866out:
1867 return status;
1868}
1869
1870static inline void

--- 939 unchanged lines hidden ---
1967 INIT_COMPLETION(arm_state->resume_blocker);
1968 arm_state->resume_blocked = 1;
1969
1970out:
1971 return status;
1972}
1973
1974static inline void

--- 939 unchanged lines hidden ---