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 <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
a1f9ae2bd2
commit
850f8940a6
@ -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)
|
|||||||
|
|
||||||
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,
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user