Commit 850f8940 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman

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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a1f9ae2b
...@@ -230,25 +230,30 @@ static void mei_cl_bus_event_work(struct work_struct *work) ...@@ -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 * mei_cl_bus_notify_event - schedule notify cb on bus client
* *
* @cl: host 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; struct mei_cl_device *cldev = cl->cldev;
if (!cldev || !cldev->event_cb) if (!cldev || !cldev->event_cb)
return; return false;
if (!(cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF))) if (!(cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)))
return; return false;
if (!cl->notify_ev) if (!cl->notify_ev)
return; return false;
set_bit(MEI_CL_EVENT_NOTIF, &cldev->events); set_bit(MEI_CL_EVENT_NOTIF, &cldev->events);
schedule_work(&cldev->event_work); schedule_work(&cldev->event_work);
cl->notify_ev = false; cl->notify_ev = false;
return true;
} }
/** /**
......
...@@ -1363,12 +1363,12 @@ void mei_cl_notify(struct mei_cl *cl) ...@@ -1363,12 +1363,12 @@ void mei_cl_notify(struct mei_cl *cl)
cl_dbg(dev, cl, "notify event"); cl_dbg(dev, cl, "notify event");
cl->notify_ev = true; 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) if (cl->ev_async)
kill_fasync(&cl->ev_async, SIGIO, POLL_PRI); kill_fasync(&cl->ev_async, SIGIO, POLL_PRI);
mei_cl_bus_notify_event(cl);
} }
/** /**
......
...@@ -317,7 +317,7 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, ...@@ -317,7 +317,7 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
bool blocking); bool blocking);
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length); ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length);
bool mei_cl_bus_rx_event(struct mei_cl *cl); 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); void mei_cl_bus_remove_devices(struct mei_device *bus);
int mei_cl_bus_init(void); int mei_cl_bus_init(void);
void mei_cl_bus_exit(void); void mei_cl_bus_exit(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment