| /* Copyright (c) 2015 Google Inc | 
 |  * Davide Libenzi <dlibenzi@google.com> | 
 |  * See LICENSE for details. | 
 |  */ | 
 |  | 
 | #include <kthread.h> | 
 | #include <completion.h> | 
 |  | 
 | void completion_init(struct completion *comp, int count) | 
 | { | 
 | 	cv_init_irqsave(&comp->cv); | 
 | 	comp->count = count; | 
 | } | 
 |  | 
 | void completion_complete(struct completion *comp, int how_much) | 
 | { | 
 | 	int8_t state = 0; | 
 |  | 
 | 	cv_lock_irqsave(&comp->cv, &state); | 
 | 	comp->count -= how_much; | 
 | 	if (comp->count <= 0) | 
 | 		__cv_broadcast(&comp->cv); | 
 | 	cv_unlock_irqsave(&comp->cv, &state); | 
 | } | 
 |  | 
 | void completion_wait(struct completion *comp) | 
 | { | 
 | 	int8_t state = 0; | 
 |  | 
 | 	cv_lock_irqsave(&comp->cv, &state); | 
 | 	if (comp->count > 0) { | 
 | 		cv_wait_and_unlock(&comp->cv); | 
 | 		enable_irqsave(&state); | 
 | 	} else { | 
 | 		cv_unlock_irqsave(&comp->cv, &state); | 
 | 	} | 
 | } |