From: Tomas Winkler Date: Sun, 7 Feb 2016 21:35:31 +0000 (+0200) Subject: mei: bus: fix notification event delivery X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=850f8940a6a38563ff401073fd845414ab49c5ed;p=linux-beck.git mei: bus: fix notification event delivery Call wake_up cl->ev_wait only in case there is no bus client registered to the event notification. Second, since we don't have exclusive waiter wake_up_interruptible_all is not used correctly here. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index a40d8e24ecda..990f4f65c35e 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -230,25 +230,30 @@ static void mei_cl_bus_event_work(struct work_struct *work) * mei_cl_bus_notify_event - schedule notify cb on bus client * * @cl: host client + * + * Return: true if event was scheduled + * false if the client is not waiting for event */ -void mei_cl_bus_notify_event(struct mei_cl *cl) +bool mei_cl_bus_notify_event(struct mei_cl *cl) { struct mei_cl_device *cldev = cl->cldev; if (!cldev || !cldev->event_cb) - return; + return false; if (!(cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF))) - return; + return false; if (!cl->notify_ev) - return; + return false; set_bit(MEI_CL_EVENT_NOTIF, &cldev->events); schedule_work(&cldev->event_work); cl->notify_ev = false; + + return true; } /** diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 574f7394fb2b..3fd070a698ce 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1363,12 +1363,12 @@ void mei_cl_notify(struct mei_cl *cl) cl_dbg(dev, cl, "notify event"); cl->notify_ev = true; - wake_up_interruptible_all(&cl->ev_wait); + if (!mei_cl_bus_notify_event(cl)) + wake_up_interruptible(&cl->ev_wait); if (cl->ev_async) kill_fasync(&cl->ev_async, SIGIO, POLL_PRI); - mei_cl_bus_notify_event(cl); } /** diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index be97b8f2a883..70c4da015401 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -317,7 +317,7 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, bool blocking); ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length); bool mei_cl_bus_rx_event(struct mei_cl *cl); -void mei_cl_bus_notify_event(struct mei_cl *cl); +bool mei_cl_bus_notify_event(struct mei_cl *cl); void mei_cl_bus_remove_devices(struct mei_device *bus); int mei_cl_bus_init(void); void mei_cl_bus_exit(void);