aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorPhil Elwell <phil@raspberrypi.org>2019-01-11 11:34:53 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-01-15 16:31:09 +0100
commita50c4c9a65779ca835746b5fd79d3d5278afbdbe (patch)
treecb56ba2d41c78511d7c5b8fd633fd5167c42c073 /drivers/staging
parentStaging: wilc1000: unlock on error in init_chip() (diff)
downloadlinux-dev-a50c4c9a65779ca835746b5fd79d3d5278afbdbe.tar.xz
linux-dev-a50c4c9a65779ca835746b5fd79d3d5278afbdbe.zip
staging: vchiq: Fix local event signalling
Prior to the recent event reworking (see Fixes), thread synchronisation was implemented using completions, the worker thread being woken with a call to complete(). The replacement uses waitqueues, which are more like condition variables in that the waiting thread is only woken if the condition is true. When the VPU signals the ARM, it first sets the event's fired flag to indicate which event is being signalled, but the places in the ARM-side code where the worker thread is being woken - remote_event_signal_local via request_poll - did not do so as it wasn't previously necessary, and since the armed flag was being cleared this lead to a deadlock. Fixes: 852b2876a8a8 ("staging: vchiq: rework remove_event handling") Signed-off-by: Phil Elwell <phil@raspberrypi.org> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
index 9e17ec651bde..53f5a1cb4636 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -446,6 +446,7 @@ remote_event_wait(wait_queue_head_t *wq, struct remote_event *event)
static inline void
remote_event_signal_local(wait_queue_head_t *wq, struct remote_event *event)
{
+ event->fired = 1;
event->armed = 0;
wake_up_all(wq);
}