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 --- |