Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1192475 > unrolled thread

[char-misc-next 0/9 RESEND] mei: support for async event notifications

Started byTomas Winkler <tomas.winkler@intel.com>
First post2015-07-26 09:00 +0200
Last post2015-08-04 13:10 +0200
Articles 8 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [char-misc-next 0/9 RESEND] mei: support for async event notifications Tomas Winkler <tomas.winkler@intel.com> - 2015-07-26 09:00 +0200
    [char-misc-next 9/9 RESEND] mei: bus: add and call callback on notify event Tomas Winkler <tomas.winkler@intel.com> - 2015-07-26 09:00 +0200
    [char-misc-next 3/9 RESEND] mei: enable async event notifications only from hbm version 2.0 Tomas Winkler <tomas.winkler@intel.com> - 2015-07-26 09:00 +0200
    [char-misc-next 4/9 RESEND] mei: add mei_cl_notify_request command Tomas Winkler <tomas.winkler@intel.com> - 2015-07-26 09:00 +0200
    [char-misc-next 7/9 RESEND] mei: support polling for event notification Tomas Winkler <tomas.winkler@intel.com> - 2015-07-26 09:00 +0200
    [char-misc-next 5/9 RESEND] mei: add a handler that waits for notification on event Tomas Winkler <tomas.winkler@intel.com> - 2015-07-26 09:00 +0200
    Re: [char-misc-next 0/9 RESEND] mei: support for async event  notifications Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2015-08-04 02:20 +0200
      RE: [char-misc-next 0/9 RESEND] mei: support for async event  notifications "Winkler, Tomas" <tomas.winkler@intel.com> - 2015-08-04 13:10 +0200

#1192475 — [char-misc-next 0/9 RESEND] mei: support for async event notifications

FromTomas Winkler <tomas.winkler@intel.com>
Date2015-07-26 09:00 +0200
Subject[char-misc-next 0/9 RESEND] mei: support for async event notifications
Message-ID<pQo4G-3U0-3@gated-at.bofh.it>
FW has gained new capability where a FW client can asynchronously
notify the host that an event has occurred in its process.
The notification doesn't provide any data and host may need to query
further the FW client in order to get details of the event.
New IOCTLs are introduced for the user space to enable/disable
and consume the event notifications.
The asynchronous nature is provided via poll and fasync.


Alexander Usyskin (1):
  mei: bus: add and call callback on notify event

Tomas Winkler (8):
  mei: define async notification hbm commands
  mei: implement async notification hbm messages
  mei: enable async event notifications only from hbm version 2.0
  mei: add mei_cl_notify_request command
  mei: add a handler that waits for notification on event
  mei: add async event notification ioctls
  mei: support polling for event notification
  mei: implement fasync for event notification

 Documentation/ioctl/ioctl-number.txt   |   2 +
 Documentation/misc-devices/mei/mei.txt |  45 ++++++-
 drivers/misc/mei/bus.c                 |  50 +++++++-
 drivers/misc/mei/client.c              | 224 +++++++++++++++++++++++++++++++++
 drivers/misc/mei/client.h              |   8 ++
 drivers/misc/mei/debugfs.c             |   2 +
 drivers/misc/mei/hbm.c                 | 136 ++++++++++++++++++++
 drivers/misc/mei/hbm.h                 |   2 +
 drivers/misc/mei/hw.h                  |  68 ++++++++++
 drivers/misc/mei/interrupt.c           |   7 ++
 drivers/misc/mei/main.c                |  96 ++++++++++++++
 drivers/misc/mei/mei_dev.h             |  15 +++
 drivers/nfc/mei_phy.c                  |   3 +-
 include/linux/mei_cl_bus.h             |   4 +
 include/uapi/linux/mei.h               |  19 +++
 15 files changed, 675 insertions(+), 6 deletions(-)

-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1192476 — [char-misc-next 9/9 RESEND] mei: bus: add and call callback on notify event

FromTomas Winkler <tomas.winkler@intel.com>
Date2015-07-26 09:00 +0200
Subject[char-misc-next 9/9 RESEND] mei: bus: add and call callback on notify event
Message-ID<pQo4G-3U0-11@gated-at.bofh.it>
In reply to#1192475
From: Alexander Usyskin <alexander.usyskin@intel.com>

Enable drivers on mei client bus to subscribe
to asynchronous event notifications.
Introduce events_mask to the existing callback infrastructure
so it is possible to handle both RX and event notification.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/bus.c     | 50 ++++++++++++++++++++++++++++++++++++++++++----
 drivers/misc/mei/client.c  |  2 ++
 drivers/misc/mei/mei_dev.h |  1 +
 drivers/nfc/mei_phy.c      |  3 ++-
 include/linux/mei_cl_bus.h |  4 ++++
 5 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 3ab08e522fb8..eef1c6b46ad8 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -222,7 +222,33 @@ static void mei_bus_event_work(struct work_struct *work)
 	cldev->events = 0;
 
 	/* Prepare for the next read */
-	mei_cl_read_start(cldev->cl, 0, NULL);
+	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX))
+		mei_cl_read_start(cldev->cl, 0, NULL);
+}
+
+/**
+ * mei_cl_bus_notify_event - schedule notify cb on bus client
+ *
+ * @cl: host client
+ */
+void mei_cl_bus_notify_event(struct mei_cl *cl)
+{
+	struct mei_cl_device *cldev = cl->cldev;
+
+	if (!cldev || !cldev->event_cb)
+		return;
+
+	if (!(cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)))
+		return;
+
+	if (!cl->notify_ev)
+		return;
+
+	set_bit(MEI_CL_EVENT_NOTIF, &cldev->events);
+
+	schedule_work(&cldev->event_work);
+
+	cl->notify_ev = false;
 }
 
 /**
@@ -237,6 +263,9 @@ void mei_cl_bus_rx_event(struct mei_cl *cl)
 	if (!cldev || !cldev->event_cb)
 		return;
 
+	if (!(cldev->events_mask & BIT(MEI_CL_EVENT_RX)))
+		return;
+
 	set_bit(MEI_CL_EVENT_RX, &cldev->events);
 
 	schedule_work(&cldev->event_work);
@@ -247,6 +276,7 @@ void mei_cl_bus_rx_event(struct mei_cl *cl)
  *
  * @cldev: me client devices
  * @event_cb: callback function
+ * @events_mask: requested events bitmask
  * @context: driver context data
  *
  * Return: 0 on success
@@ -254,6 +284,7 @@ void mei_cl_bus_rx_event(struct mei_cl *cl)
  *         <0 on other errors
  */
 int mei_cl_register_event_cb(struct mei_cl_device *cldev,
+			  unsigned long events_mask,
 			  mei_cl_event_cb_t event_cb, void *context)
 {
 	int ret;
@@ -262,13 +293,24 @@ int mei_cl_register_event_cb(struct mei_cl_device *cldev,
 		return -EALREADY;
 
 	cldev->events = 0;
+	cldev->events_mask = events_mask;
 	cldev->event_cb = event_cb;
 	cldev->event_context = context;
 	INIT_WORK(&cldev->event_work, mei_bus_event_work);
 
-	ret = mei_cl_read_start(cldev->cl, 0, NULL);
-	if (ret && ret != -EBUSY)
-		return ret;
+	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
+		ret = mei_cl_read_start(cldev->cl, 0, NULL);
+		if (ret && ret != -EBUSY)
+			return ret;
+	}
+
+	if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) {
+		mutex_lock(&cldev->cl->dev->device_lock);
+		ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0);
+		mutex_unlock(&cldev->cl->dev->device_lock);
+		if (ret)
+			return ret;
+	}
 
 	return 0;
 }
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index db2436aee2dc..5fcd70bcdf96 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -1375,6 +1375,8 @@ void mei_cl_notify(struct mei_cl *cl)
 
 	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 c960aaa538c0..e25ee16c658e 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -345,6 +345,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);
 void mei_cl_bus_rx_event(struct mei_cl *cl);
+void 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);
diff --git a/drivers/nfc/mei_phy.c b/drivers/nfc/mei_phy.c
index 2b77ccf77f81..754a9bb0f58d 100644
--- a/drivers/nfc/mei_phy.c
+++ b/drivers/nfc/mei_phy.c
@@ -355,7 +355,8 @@ static int nfc_mei_phy_enable(void *phy_id)
 		goto err;
 	}
 
-	r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy);
+	r = mei_cl_register_event_cb(phy->device, BIT(MEI_CL_EVENT_RX),
+				     nfc_mei_event_cb, phy);
 	if (r) {
 		pr_err("Event cb registration failed %d\n", r);
 		goto err;
diff --git a/include/linux/mei_cl_bus.h b/include/linux/mei_cl_bus.h
index 81ab56dd0ae0..0962b2ca628a 100644
--- a/include/linux/mei_cl_bus.h
+++ b/include/linux/mei_cl_bus.h
@@ -28,6 +28,7 @@ typedef void (*mei_cl_event_cb_t)(struct mei_cl_device *device,
  * @event_cb: Drivers register this callback to get asynchronous ME
  *	events (e.g. Rx buffer pending) notifications.
  * @event_context: event callback run context
+ * @events_mask: Events bit mask requested by driver.
  * @events: Events bitmask sent to the driver.
  *
  * @do_match: wheather device can be matched with a driver
@@ -46,6 +47,7 @@ struct mei_cl_device {
 	struct work_struct event_work;
 	mei_cl_event_cb_t event_cb;
 	void *event_context;
+	unsigned long events_mask;
 	unsigned long events;
 
 	unsigned int do_match:1;
@@ -76,10 +78,12 @@ ssize_t mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length);
 ssize_t  mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length);
 
 int mei_cl_register_event_cb(struct mei_cl_device *device,
+			  unsigned long event_mask,
 			  mei_cl_event_cb_t read_cb, void *context);
 
 #define MEI_CL_EVENT_RX 0
 #define MEI_CL_EVENT_TX 1
+#define MEI_CL_EVENT_NOTIF 2
 
 void *mei_cl_get_drvdata(const struct mei_cl_device *device);
 void mei_cl_set_drvdata(struct mei_cl_device *device, void *data);
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1192477 — [char-misc-next 3/9 RESEND] mei: enable async event notifications only from hbm version 2.0

FromTomas Winkler <tomas.winkler@intel.com>
Date2015-07-26 09:00 +0200
Subject[char-misc-next 3/9 RESEND] mei: enable async event notifications only from hbm version 2.0
Message-ID<pQo4G-3U0-13@gated-at.bofh.it>
In reply to#1192475
Only FW version 2.0 and newer support the async event
notification. For backward compatibility block the feature
if the FW version is older then 2.0

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/debugfs.c | 2 ++
 drivers/misc/mei/hbm.c     | 4 ++++
 drivers/misc/mei/hw.h      | 6 ++++++
 drivers/misc/mei/mei_dev.h | 2 ++
 4 files changed, 14 insertions(+)

diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c
index e39cfe6bc5bc..4b469cf9e60f 100644
--- a/drivers/misc/mei/debugfs.c
+++ b/drivers/misc/mei/debugfs.c
@@ -158,6 +158,8 @@ static ssize_t mei_dbgfs_read_devstate(struct file *fp, char __user *ubuf,
 				 dev->hbm_f_dc_supported);
 		pos += scnprintf(buf + pos, bufsz - pos, "\tDOT: %01d\n",
 				 dev->hbm_f_dot_supported);
+		pos += scnprintf(buf + pos, bufsz - pos, "\tEV: %01d\n",
+				 dev->hbm_f_ev_supported);
 	}
 
 	pos += scnprintf(buf + pos, bufsz - pos, "pg:  %s, %s\n",
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 8a73fa06f3c4..95e918c84a6c 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -903,6 +903,10 @@ static void mei_hbm_config_features(struct mei_device *dev)
 	/* disconnect on connect timeout instead of link reset */
 	if (dev->version.major_version >= HBM_MAJOR_VERSION_DOT)
 		dev->hbm_f_dot_supported = 1;
+
+	/* Notification Event Support */
+	if (dev->version.major_version >= HBM_MAJOR_VERSION_EV)
+		dev->hbm_f_ev_supported = 1;
 }
 
 /**
diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h
index a2c7aaba25d4..3f8901a503a6 100644
--- a/drivers/misc/mei/hw.h
+++ b/drivers/misc/mei/hw.h
@@ -58,6 +58,12 @@
 #define HBM_MINOR_VERSION_DOT              0
 #define HBM_MAJOR_VERSION_DOT              2
 
+/*
+ * MEI version with notifcation support
+ */
+#define HBM_MINOR_VERSION_EV               0
+#define HBM_MAJOR_VERSION_EV               2
+
 /* Host bus message command opcode */
 #define MEI_HBM_CMD_OP_MSK                  0x7f
 /* Host bus message command RESPONSE */
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 362ebb15ccd9..e22bd21bb754 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -419,6 +419,7 @@ const char *mei_pg_state_str(enum mei_pg_state state);
  * @hbm_f_pg_supported  : hbm feature pgi protocol
  * @hbm_f_dc_supported  : hbm feature dynamic clients
  * @hbm_f_dot_supported : hbm feature disconnect on timeout
+ * @hbm_f_ev_supported  : hbm feature event notification
  *
  * @me_clients_rwsem: rw lock over me_clients list
  * @me_clients  : list of FW clients
@@ -514,6 +515,7 @@ struct mei_device {
 	unsigned int hbm_f_pg_supported:1;
 	unsigned int hbm_f_dc_supported:1;
 	unsigned int hbm_f_dot_supported:1;
+	unsigned int hbm_f_ev_supported:1;
 
 	struct rw_semaphore me_clients_rwsem;
 	struct list_head me_clients;
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1192478 — [char-misc-next 4/9 RESEND] mei: add mei_cl_notify_request command

FromTomas Winkler <tomas.winkler@intel.com>
Date2015-07-26 09:00 +0200
Subject[char-misc-next 4/9 RESEND] mei: add mei_cl_notify_request command
Message-ID<pQo4G-3U0-17@gated-at.bofh.it>
In reply to#1192475
Add per client notification request infrastructure
that allows client to enable or disable async
event notification.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/client.c    | 143 +++++++++++++++++++++++++++++++++++++++++++
 drivers/misc/mei/client.h    |   6 ++
 drivers/misc/mei/hbm.c       |   5 +-
 drivers/misc/mei/interrupt.c |   7 +++
 4 files changed, 157 insertions(+), 4 deletions(-)

diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 40285e02b612..fae4050413a2 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -1209,6 +1209,147 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
 }
 
 /**
+ *  mei_cl_notify_fop2req - convert fop to proper request
+ *
+ * @fop: client notification start response command
+ *
+ * Return:  MEI_HBM_NOTIFICATION_START/STOP
+ */
+u8 mei_cl_notify_fop2req(enum mei_cb_file_ops fop)
+{
+	if (fop == MEI_FOP_NOTIFY_START)
+		return MEI_HBM_NOTIFICATION_START;
+	else
+		return MEI_HBM_NOTIFICATION_STOP;
+}
+
+/**
+ *  mei_cl_notify_req2fop - convert notification request top file operation type
+ *
+ * @req: hbm notification request type
+ *
+ * Return:  MEI_FOP_NOTIFY_START/STOP
+ */
+enum mei_cb_file_ops mei_cl_notify_req2fop(u8 req)
+{
+	if (req == MEI_HBM_NOTIFICATION_START)
+		return MEI_FOP_NOTIFY_START;
+	else
+		return MEI_FOP_NOTIFY_STOP;
+}
+
+/**
+ * mei_cl_irq_notify - send notification request in irq_thread context
+ *
+ * @cl: client
+ * @cb: callback block.
+ * @cmpl_list: complete list.
+ *
+ * Return: 0 on such and error otherwise.
+ */
+int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb,
+		      struct mei_cl_cb *cmpl_list)
+{
+	struct mei_device *dev = cl->dev;
+	u32 msg_slots;
+	int slots;
+	int ret;
+	bool request;
+
+	msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request));
+	slots = mei_hbuf_empty_slots(dev);
+
+	if (slots < msg_slots)
+		return -EMSGSIZE;
+
+	request = mei_cl_notify_fop2req(cb->fop_type);
+	ret = mei_hbm_cl_notify_req(dev, cl, request);
+	if (ret) {
+		cl->status = ret;
+		list_move_tail(&cb->list, &cmpl_list->list);
+		return ret;
+	}
+
+	list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
+	return 0;
+}
+
+/**
+ * mei_cl_notify_request - send notification stop/start request
+ *
+ * @cl: host client
+ * @file: associate request with file
+ * @request: 1 for start or 0 for stop
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * Return: 0 on such and error otherwise.
+ */
+int mei_cl_notify_request(struct mei_cl *cl, struct file *file, u8 request)
+{
+	struct mei_device *dev;
+	struct mei_cl_cb *cb;
+	enum mei_cb_file_ops fop_type;
+	int rets;
+
+	if (WARN_ON(!cl || !cl->dev))
+		return -ENODEV;
+
+	dev = cl->dev;
+
+	if (!dev->hbm_f_ev_supported) {
+		cl_dbg(dev, cl, "notifications not supported\n");
+		return -EOPNOTSUPP;
+	}
+
+	rets = pm_runtime_get(dev->dev);
+	if (rets < 0 && rets != -EINPROGRESS) {
+		pm_runtime_put_noidle(dev->dev);
+		cl_err(dev, cl, "rpm: get failed %d\n", rets);
+		return rets;
+	}
+
+	fop_type = mei_cl_notify_req2fop(request);
+	cb = mei_io_cb_init(cl, fop_type, file);
+	if (!cb) {
+		rets = -ENOMEM;
+		goto out;
+	}
+
+	if (mei_hbuf_acquire(dev)) {
+		if (mei_hbm_cl_notify_req(dev, cl, request)) {
+			rets = -ENODEV;
+			goto out;
+		}
+		list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
+	} else {
+		list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
+	}
+
+	mutex_unlock(&dev->device_lock);
+	wait_event_timeout(cl->wait, cl->notify_en == request,
+			mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
+	mutex_lock(&dev->device_lock);
+
+	if (cl->notify_en != request) {
+		mei_io_list_flush(&dev->ctrl_rd_list, cl);
+		mei_io_list_flush(&dev->ctrl_wr_list, cl);
+		if (!cl->status)
+			cl->status = -EFAULT;
+	}
+
+	rets = cl->status;
+
+out:
+	cl_dbg(dev, cl, "rpm: autosuspend\n");
+	pm_runtime_mark_last_busy(dev->dev);
+	pm_runtime_put_autosuspend(dev->dev);
+
+	mei_io_cb_free(cb);
+	return rets;
+}
+
+/**
  * mei_cl_read_start - the start read client message function.
  *
  * @cl: host client
@@ -1516,6 +1657,8 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
 
 	case MEI_FOP_CONNECT:
 	case MEI_FOP_DISCONNECT:
+	case MEI_FOP_NOTIFY_STOP:
+	case MEI_FOP_NOTIFY_START:
 		if (waitqueue_active(&cl->wait))
 			wake_up(&cl->wait);
 
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 8d7f057f1045..506b7d40d427 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -219,6 +219,12 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb);
 
 void mei_host_client_init(struct work_struct *work);
 
+u8 mei_cl_notify_fop2req(enum mei_cb_file_ops fop);
+enum mei_cb_file_ops mei_cl_notify_req2fop(u8 request);
+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);
+
 void mei_cl_all_disconnect(struct mei_device *dev);
 void mei_cl_all_wakeup(struct mei_device *dev);
 void mei_cl_all_write_clear(struct mei_device *dev);
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 95e918c84a6c..12229ff4bc7e 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -446,10 +446,7 @@ static inline enum mei_cb_file_ops notify_res_to_fop(struct mei_hbm_cl_cmd *cmd)
 	struct hbm_notification_response *rs =
 		(struct hbm_notification_response *)cmd;
 
-	if (rs->start == MEI_HBM_NOTIFICATION_START)
-		return MEI_FOP_NOTIFY_START;
-	else
-		return MEI_FOP_NOTIFY_STOP;
+	return mei_cl_notify_req2fop(rs->start);
 }
 
 /**
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 89d8e1304077..c418d7888994 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -403,6 +403,13 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
 			if (ret)
 				return ret;
 			break;
+
+		case MEI_FOP_NOTIFY_START:
+		case MEI_FOP_NOTIFY_STOP:
+			ret = mei_cl_irq_notify(cl, cb, cmpl_list);
+			if (ret)
+				return ret;
+			break;
 		default:
 			BUG();
 		}
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1192479 — [char-misc-next 7/9 RESEND] mei: support polling for event notification

FromTomas Winkler <tomas.winkler@intel.com>
Date2015-07-26 09:00 +0200
Subject[char-misc-next 7/9 RESEND] mei: support polling for event notification
Message-ID<pQo4G-3U0-19@gated-at.bofh.it>
In reply to#1192475
Polling on priority events is translated on waiting for event
notification. One need to enable notification prior for
calling select or poll system call otherwise process
will not wait.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/main.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index ffa70035af29..17b356f26686 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -608,6 +608,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait)
 	struct mei_cl *cl = file->private_data;
 	struct mei_device *dev;
 	unsigned int mask = 0;
+	bool notify_en;
 
 	if (WARN_ON(!cl || !cl->dev))
 		return POLLERR;
@@ -616,6 +617,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait)
 
 	mutex_lock(&dev->device_lock);
 
+	notify_en = cl->notify_en && (req_events & POLLPRI);
 
 	if (dev->dev_state != MEI_DEV_ENABLED ||
 	    !mei_cl_is_connected(cl)) {
@@ -628,6 +630,12 @@ static unsigned int mei_poll(struct file *file, poll_table *wait)
 		goto out;
 	}
 
+	if (notify_en) {
+		poll_wait(file, &cl->ev_wait, wait);
+		if (cl->notify_ev)
+			mask |= POLLPRI;
+	}
+
 	if (req_events & (POLLIN | POLLRDNORM)) {
 		poll_wait(file, &cl->rx_wait, wait);
 
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1192480 — [char-misc-next 5/9 RESEND] mei: add a handler that waits for notification on event

FromTomas Winkler <tomas.winkler@intel.com>
Date2015-07-26 09:00 +0200
Subject[char-misc-next 5/9 RESEND] mei: add a handler that waits for notification on event
Message-ID<pQo4G-3U0-21@gated-at.bofh.it>
In reply to#1192475
mei_cl_notify_get is to be called by a host client
to wait, receive, and ack the event notification.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/client.c  | 52 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/misc/mei/client.h  |  1 +
 drivers/misc/mei/hbm.c     |  4 +++-
 drivers/misc/mei/mei_dev.h |  2 ++
 4 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index fae4050413a2..d9396838774c 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -555,6 +555,7 @@ void mei_cl_init(struct mei_cl *cl, struct mei_device *dev)
 	init_waitqueue_head(&cl->wait);
 	init_waitqueue_head(&cl->rx_wait);
 	init_waitqueue_head(&cl->tx_wait);
+	init_waitqueue_head(&cl->ev_wait);
 	INIT_LIST_HEAD(&cl->rd_completed);
 	INIT_LIST_HEAD(&cl->rd_pending);
 	INIT_LIST_HEAD(&cl->link);
@@ -1350,6 +1351,51 @@ out:
 }
 
 /**
+ * mei_cl_notify_get - get or wait for notification event
+ *
+ * @cl: host client
+ * @block: this request is blocking
+ * @notify_ev: true if notification event was received
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * Return: 0 on such and error otherwise.
+ */
+int mei_cl_notify_get(struct mei_cl *cl, bool block, bool *notify_ev)
+{
+	struct mei_device *dev;
+	int rets;
+
+	*notify_ev = false;
+
+	if (WARN_ON(!cl || !cl->dev))
+		return -ENODEV;
+
+	dev = cl->dev;
+
+	if (!mei_cl_is_connected(cl))
+		return -ENODEV;
+
+	if (cl->notify_ev)
+		goto out;
+
+	if (!block)
+		return -EAGAIN;
+
+	mutex_unlock(&dev->device_lock);
+	rets = wait_event_interruptible(cl->ev_wait, cl->notify_ev);
+	mutex_lock(&dev->device_lock);
+
+	if (rets < 0)
+		return rets;
+
+out:
+	*notify_ev = cl->notify_ev;
+	cl->notify_ev = false;
+	return 0;
+}
+
+/**
  * mei_cl_read_start - the start read client message function.
  *
  * @cl: host client
@@ -1701,6 +1747,12 @@ void mei_cl_all_wakeup(struct mei_device *dev)
 			cl_dbg(dev, cl, "Waking up writing client!\n");
 			wake_up_interruptible(&cl->tx_wait);
 		}
+
+		/* synchronized under device mutex */
+		if (waitqueue_active(&cl->ev_wait)) {
+			cl_dbg(dev, cl, "Waking up waiting for event clients!\n");
+			wake_up_interruptible(&cl->ev_wait);
+		}
 	}
 }
 
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 506b7d40d427..58a4b49701fe 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -224,6 +224,7 @@ enum mei_cb_file_ops mei_cl_notify_req2fop(u8 request);
 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_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 12229ff4bc7e..70c94a9cd905 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -514,8 +514,10 @@ 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)
+	if (cl && cl->notify_en) {
 		cl->notify_ev = true;
+		wake_up_interruptible(&cl->ev_wait);
+	}
 }
 
 /**
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index e22bd21bb754..6f8f5e1e909e 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -235,6 +235,7 @@ struct mei_cl_cb {
  * @tx_wait: wait queue for tx completion
  * @rx_wait: wait queue for rx completion
  * @wait:  wait queue for management operation
+ * @ev_wait: notification wait queue
  * @status: connection status
  * @me_cl: fw client connected
  * @host_client_id: host id
@@ -256,6 +257,7 @@ struct mei_cl {
 	wait_queue_head_t tx_wait;
 	wait_queue_head_t rx_wait;
 	wait_queue_head_t wait;
+	wait_queue_head_t ev_wait;
 	int status;
 	struct mei_me_client *me_cl;
 	u8 host_client_id;
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1199336 — Re: [char-misc-next 0/9 RESEND] mei: support for async event notifications

FromGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Date2015-08-04 02:20 +0200
SubjectRe: [char-misc-next 0/9 RESEND] mei: support for async event notifications
Message-ID<pTy7w-2iW-3@gated-at.bofh.it>
In reply to#1192475
On Mon, Jul 27, 2015 at 06:36:18AM +0000, Winkler, Tomas wrote:
> 
> > 
> > On Sun, Jul 26, 2015 at 09:54:14AM +0300, Tomas Winkler wrote:
> > > FW has gained new capability where a FW client can asynchronously
> > > notify the host that an event has occurred in its process.
> > > The notification doesn't provide any data and host may need to query
> > > further the FW client in order to get details of the event.
> > > New IOCTLs are introduced for the user space to enable/disable
> > > and consume the event notifications.
> > > The asynchronous nature is provided via poll and fasync.
> > 
> > What changed to require a RESEND?
> 
> You've asked for it.

You might want to give me some context, as I have no idea why I asked
for a resend.  Obviously you must have done something to the series from
the previous one, right?

thanks,

greg "short term memory of a squirrel" k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1199670 — RE: [char-misc-next 0/9 RESEND] mei: support for async event notifications

From"Winkler, Tomas" <tomas.winkler@intel.com>
Date2015-08-04 13:10 +0200
SubjectRE: [char-misc-next 0/9 RESEND] mei: support for async event notifications
Message-ID<pTIgz-h7-71@gated-at.bofh.it>
In reply to#1199336
> > > > and consume the event notifications.
> > > > The asynchronous nature is provided via poll and fasync.
> > >
> > > What changed to require a RESEND?
> >
> > You've asked for it.
> 
> You might want to give me some context, as I have no idea why I asked
> for a resend.  Obviously you must have done something to the series from
> the previous one, right?

Quoting from (https://lkml.org/lkml/2015/7/23/5) and referring to the second sentence.

'Due to the changes in Linus's tree, this doesn't apply to 4.2-rc3.  Can
you refresh this series and resend?  Same for the other outstanding mei
patches you have sent that I haven't applied.'

Thanks
Tomas
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web