Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+9 −4
Original line number Original line Diff line number Diff line
@@ -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;
}
}


/**
/**
+2 −2
Original line number Original line Diff line number Diff line
@@ -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);
}
}


/**
/**
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);