diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2015-07-26 09:54:22 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-08-03 17:30:00 -0700 |
commit | 237092bf034a648611f61eb1f0965e9ba1b08871 (patch) | |
tree | 64dec996bf6840cd2cdfcfbd51909015b64246df /drivers | |
parent | 2c84c2970c1acf83827aa97ab0e6addc3d2aa960 (diff) |
mei: implement fasync for event notification
A process can be informed about client notification also via
SIGIO with POLL_PRI event.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/misc/mei/client.c | 27 | ||||
-rw-r--r-- | drivers/misc/mei/client.h | 1 | ||||
-rw-r--r-- | drivers/misc/mei/hbm.c | 6 | ||||
-rw-r--r-- | drivers/misc/mei/main.c | 21 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 2 |
5 files changed, 53 insertions, 4 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index d9396838774c..db2436aee2dc 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1351,6 +1351,33 @@ out: } /** + * mei_cl_notify - raise notification + * + * @cl: host client + * + * Locking: called under "dev->device_lock" lock + */ +void mei_cl_notify(struct mei_cl *cl) +{ + struct mei_device *dev; + + if (!cl || !cl->dev) + return; + + dev = cl->dev; + + if (!cl->notify_en) + return; + + cl_dbg(dev, cl, "notify event"); + cl->notify_ev = true; + wake_up_interruptible_all(&cl->ev_wait); + + if (cl->ev_async) + kill_fasync(&cl->ev_async, SIGIO, POLL_PRI); +} + +/** * mei_cl_notify_get - get or wait for notification event * * @cl: host client diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index 58a4b49701fe..1c7cad07d731 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -225,6 +225,7 @@ int mei_cl_notify_request(struct mei_cl *cl, struct file *file, u8 request); int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list); int mei_cl_notify_get(struct mei_cl *cl, bool block, bool *notify_ev); +void mei_cl_notify(struct mei_cl *cl); void mei_cl_all_disconnect(struct mei_device *dev); void mei_cl_all_wakeup(struct mei_device *dev); diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 70c94a9cd905..7f53597e697a 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -514,10 +514,8 @@ static void mei_hbm_cl_notify(struct mei_device *dev, struct mei_cl *cl; cl = mei_hbm_cl_find_by_cmd(dev, cmd); - if (cl && cl->notify_en) { - cl->notify_ev = true; - wake_up_interruptible(&cl->ev_wait); - } + if (cl) + mei_cl_notify(cl); } /** diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 17b356f26686..b2f2486b3d75 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -651,6 +651,26 @@ out: } /** + * mei_fasync - asynchronous io support + * + * @fd: file descriptor + * @file: pointer to file structure + * @band: band bitmap + * + * Return: poll mask + */ +static int mei_fasync(int fd, struct file *file, int band) +{ + + struct mei_cl *cl = file->private_data; + + if (!mei_cl_is_connected(cl)) + return POLLERR; + + return fasync_helper(fd, file, band, &cl->ev_async); +} + +/** * fw_status_show - mei device attribute show method * * @device: device pointer @@ -702,6 +722,7 @@ static const struct file_operations mei_fops = { .release = mei_release, .write = mei_write, .poll = mei_poll, + .fasync = mei_fasync, .llseek = no_llseek }; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 6f8f5e1e909e..c960aaa538c0 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -236,6 +236,7 @@ struct mei_cl_cb { * @rx_wait: wait queue for rx completion * @wait: wait queue for management operation * @ev_wait: notification wait queue + * @ev_async: event async notification * @status: connection status * @me_cl: fw client connected * @host_client_id: host id @@ -258,6 +259,7 @@ struct mei_cl { wait_queue_head_t rx_wait; wait_queue_head_t wait; wait_queue_head_t ev_wait; + struct fasync_struct *ev_async; int status; struct mei_me_client *me_cl; u8 host_client_id; |