aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/mei/bus-fixup.c4
-rw-r--r--drivers/misc/mei/bus.c31
-rw-r--r--drivers/misc/mei/mei_dev.h7
-rw-r--r--include/linux/mei_cl_bus.h6
4 files changed, 41 insertions, 7 deletions
diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
index 7f2cef9011ae..18e05ca7584f 100644
--- a/drivers/misc/mei/bus-fixup.c
+++ b/drivers/misc/mei/bus-fixup.c
@@ -141,7 +141,7 @@ static int mei_osver(struct mei_cl_device *cldev)
141 if (ret < 0) 141 if (ret < 0)
142 return ret; 142 return ret;
143 143
144 ret = __mei_cl_recv(cldev->cl, buf, length); 144 ret = __mei_cl_recv(cldev->cl, buf, length, 0);
145 if (ret < 0) 145 if (ret < 0)
146 return ret; 146 return ret;
147 147
@@ -272,7 +272,7 @@ static int mei_nfc_if_version(struct mei_cl *cl,
272 return -ENOMEM; 272 return -ENOMEM;
273 273
274 ret = 0; 274 ret = 0;
275 bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length); 275 bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0);
276 if (bytes_recv < if_version_length) { 276 if (bytes_recv < if_version_length) {
277 dev_err(bus->dev, "Could not read IF version\n"); 277 dev_err(bus->dev, "Could not read IF version\n");
278 ret = -EIO; 278 ret = -EIO;
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 2fd254ecde2f..0037153c80a6 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -98,15 +98,18 @@ out:
98 * @cl: host client 98 * @cl: host client
99 * @buf: buffer to receive 99 * @buf: buffer to receive
100 * @length: buffer length 100 * @length: buffer length
101 * @mode: io mode
101 * 102 *
102 * Return: read size in bytes of < 0 on error 103 * Return: read size in bytes of < 0 on error
103 */ 104 */
104ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) 105ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
106 unsigned int mode)
105{ 107{
106 struct mei_device *bus; 108 struct mei_device *bus;
107 struct mei_cl_cb *cb; 109 struct mei_cl_cb *cb;
108 size_t r_length; 110 size_t r_length;
109 ssize_t rets; 111 ssize_t rets;
112 bool nonblock = !!(mode & MEI_CL_IO_RX_NONBLOCK);
110 113
111 if (WARN_ON(!cl || !cl->dev)) 114 if (WARN_ON(!cl || !cl->dev))
112 return -ENODEV; 115 return -ENODEV;
@@ -127,6 +130,11 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
127 if (rets && rets != -EBUSY) 130 if (rets && rets != -EBUSY)
128 goto out; 131 goto out;
129 132
133 if (nonblock) {
134 rets = -EAGAIN;
135 goto out;
136 }
137
130 /* wait on event only if there is no other waiter */ 138 /* wait on event only if there is no other waiter */
131 /* synchronized under device mutex */ 139 /* synchronized under device mutex */
132 if (!waitqueue_active(&cl->rx_wait)) { 140 if (!waitqueue_active(&cl->rx_wait)) {
@@ -192,6 +200,25 @@ ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
192EXPORT_SYMBOL_GPL(mei_cldev_send); 200EXPORT_SYMBOL_GPL(mei_cldev_send);
193 201
194/** 202/**
203 * mei_cldev_recv_nonblock - non block client receive (read)
204 *
205 * @cldev: me client device
206 * @buf: buffer to receive
207 * @length: buffer length
208 *
209 * Return: read size in bytes of < 0 on error
210 * -EAGAIN if function will block.
211 */
212ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
213 size_t length)
214{
215 struct mei_cl *cl = cldev->cl;
216
217 return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK);
218}
219EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);
220
221/**
195 * mei_cldev_recv - client receive (read) 222 * mei_cldev_recv - client receive (read)
196 * 223 *
197 * @cldev: me client device 224 * @cldev: me client device
@@ -204,7 +231,7 @@ ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
204{ 231{
205 struct mei_cl *cl = cldev->cl; 232 struct mei_cl *cl = cldev->cl;
206 233
207 return __mei_cl_recv(cl, buf, length); 234 return __mei_cl_recv(cl, buf, length, 0);
208} 235}
209EXPORT_SYMBOL_GPL(mei_cldev_recv); 236EXPORT_SYMBOL_GPL(mei_cldev_recv);
210 237
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 0e94df517410..699693cd8c59 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -115,10 +115,14 @@ enum mei_cb_file_ops {
115 * 115 *
116 * @MEI_CL_IO_TX_BLOCKING: send is blocking 116 * @MEI_CL_IO_TX_BLOCKING: send is blocking
117 * @MEI_CL_IO_TX_INTERNAL: internal communication between driver and FW 117 * @MEI_CL_IO_TX_INTERNAL: internal communication between driver and FW
118 *
119 * @MEI_CL_IO_RX_NONBLOCK: recv is non-blocking
118 */ 120 */
119enum mei_cl_io_mode { 121enum mei_cl_io_mode {
120 MEI_CL_IO_TX_BLOCKING = BIT(0), 122 MEI_CL_IO_TX_BLOCKING = BIT(0),
121 MEI_CL_IO_TX_INTERNAL = BIT(1), 123 MEI_CL_IO_TX_INTERNAL = BIT(1),
124
125 MEI_CL_IO_RX_NONBLOCK = BIT(2),
122}; 126};
123 127
124/* 128/*
@@ -319,7 +323,8 @@ void mei_cl_bus_rescan_work(struct work_struct *work);
319void mei_cl_bus_dev_fixup(struct mei_cl_device *dev); 323void mei_cl_bus_dev_fixup(struct mei_cl_device *dev);
320ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, 324ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
321 unsigned int mode); 325 unsigned int mode);
322ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length); 326ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
327 unsigned int mode);
323bool mei_cl_bus_rx_event(struct mei_cl *cl); 328bool mei_cl_bus_rx_event(struct mei_cl *cl);
324bool mei_cl_bus_notify_event(struct mei_cl *cl); 329bool mei_cl_bus_notify_event(struct mei_cl *cl);
325void mei_cl_bus_remove_devices(struct mei_device *bus); 330void mei_cl_bus_remove_devices(struct mei_device *bus);
diff --git a/include/linux/mei_cl_bus.h b/include/linux/mei_cl_bus.h
index 017f5232b3de..a0d274fe08f1 100644
--- a/include/linux/mei_cl_bus.h
+++ b/include/linux/mei_cl_bus.h
@@ -75,7 +75,7 @@ void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv);
75/** 75/**
76 * module_mei_cl_driver - Helper macro for registering mei cl driver 76 * module_mei_cl_driver - Helper macro for registering mei cl driver
77 * 77 *
78 * @__mei_cldrv mei_cl_driver structure 78 * @__mei_cldrv: mei_cl_driver structure
79 * 79 *
80 * Helper macro for mei cl drivers which do not do anything special in module 80 * Helper macro for mei cl drivers which do not do anything special in module
81 * init/exit, for eliminating a boilerplate code. 81 * init/exit, for eliminating a boilerplate code.
@@ -86,7 +86,9 @@ void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv);
86 mei_cldev_driver_unregister) 86 mei_cldev_driver_unregister)
87 87
88ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length); 88ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length);
89ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length); 89ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length);
90ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
91 size_t length);
90 92
91int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb); 93int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb);
92int mei_cldev_register_notif_cb(struct mei_cl_device *cldev, 94int mei_cldev_register_notif_cb(struct mei_cl_device *cldev,