aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/amthif.c6
-rw-r--r--drivers/misc/mei/client.c27
-rw-r--r--drivers/misc/mei/debugfs.c4
-rw-r--r--drivers/misc/mei/hbm.c239
-rw-r--r--drivers/misc/mei/hbm.h7
-rw-r--r--drivers/misc/mei/hw-me.c40
-rw-r--r--drivers/misc/mei/hw.h3
-rw-r--r--drivers/misc/mei/init.c278
-rw-r--r--drivers/misc/mei/interrupt.c122
-rw-r--r--drivers/misc/mei/main.c2
-rw-r--r--drivers/misc/mei/mei_dev.h33
-rw-r--r--drivers/misc/mei/nfc.c20
-rw-r--r--drivers/misc/mei/pci-me.c27
-rw-r--r--drivers/misc/mei/wd.c1
14 files changed, 506 insertions, 303 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index d22c6864508b..2fad84432829 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -177,7 +177,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
177 unsigned long timeout; 177 unsigned long timeout;
178 int i; 178 int i;
179 179
180 /* Only Posible if we are in timeout */ 180 /* Only possible if we are in timeout */
181 if (!cl || cl != &dev->iamthif_cl) { 181 if (!cl || cl != &dev->iamthif_cl) {
182 dev_dbg(&dev->pdev->dev, "bad file ext.\n"); 182 dev_dbg(&dev->pdev->dev, "bad file ext.\n");
183 return -ETIMEDOUT; 183 return -ETIMEDOUT;
@@ -249,7 +249,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
249 cb->response_buffer.size); 249 cb->response_buffer.size);
250 dev_dbg(&dev->pdev->dev, "amthif cb->buf_idx - %lu\n", cb->buf_idx); 250 dev_dbg(&dev->pdev->dev, "amthif cb->buf_idx - %lu\n", cb->buf_idx);
251 251
252 /* length is being turncated to PAGE_SIZE, however, 252 /* length is being truncated to PAGE_SIZE, however,
253 * the buf_idx may point beyond */ 253 * the buf_idx may point beyond */
254 length = min_t(size_t, length, (cb->buf_idx - *offset)); 254 length = min_t(size_t, length, (cb->buf_idx - *offset));
255 255
@@ -316,6 +316,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
316 mei_hdr.host_addr = dev->iamthif_cl.host_client_id; 316 mei_hdr.host_addr = dev->iamthif_cl.host_client_id;
317 mei_hdr.me_addr = dev->iamthif_cl.me_client_id; 317 mei_hdr.me_addr = dev->iamthif_cl.me_client_id;
318 mei_hdr.reserved = 0; 318 mei_hdr.reserved = 0;
319 mei_hdr.internal = 0;
319 dev->iamthif_msg_buf_index += mei_hdr.length; 320 dev->iamthif_msg_buf_index += mei_hdr.length;
320 ret = mei_write_message(dev, &mei_hdr, dev->iamthif_msg_buf); 321 ret = mei_write_message(dev, &mei_hdr, dev->iamthif_msg_buf);
321 if (ret) 322 if (ret)
@@ -477,6 +478,7 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
477 mei_hdr.host_addr = cl->host_client_id; 478 mei_hdr.host_addr = cl->host_client_id;
478 mei_hdr.me_addr = cl->me_client_id; 479 mei_hdr.me_addr = cl->me_client_id;
479 mei_hdr.reserved = 0; 480 mei_hdr.reserved = 0;
481 mei_hdr.internal = 0;
480 482
481 if (*slots >= msg_slots) { 483 if (*slots >= msg_slots) {
482 mei_hdr.length = len; 484 mei_hdr.length = len;
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 87c96e4669e2..1ee2b9492a82 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -154,7 +154,7 @@ int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length)
154 return 0; 154 return 0;
155} 155}
156/** 156/**
157 * mei_io_cb_alloc_resp_buf - allocate respose buffer 157 * mei_io_cb_alloc_resp_buf - allocate response buffer
158 * 158 *
159 * @cb: io callback structure 159 * @cb: io callback structure
160 * @length: size of the buffer 160 * @length: size of the buffer
@@ -207,7 +207,7 @@ int mei_cl_flush_queues(struct mei_cl *cl)
207 207
208 208
209/** 209/**
210 * mei_cl_init - initializes intialize cl. 210 * mei_cl_init - initializes cl.
211 * 211 *
212 * @cl: host client to be initialized 212 * @cl: host client to be initialized
213 * @dev: mei device 213 * @dev: mei device
@@ -263,10 +263,10 @@ struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl)
263 return NULL; 263 return NULL;
264} 264}
265 265
266/** mei_cl_link: allocte host id in the host map 266/** mei_cl_link: allocate host id in the host map
267 * 267 *
268 * @cl - host client 268 * @cl - host client
269 * @id - fixed host id or -1 for genereting one 269 * @id - fixed host id or -1 for generic one
270 * 270 *
271 * returns 0 on success 271 * returns 0 on success
272 * -EINVAL on incorrect values 272 * -EINVAL on incorrect values
@@ -282,19 +282,19 @@ int mei_cl_link(struct mei_cl *cl, int id)
282 282
283 dev = cl->dev; 283 dev = cl->dev;
284 284
285 /* If Id is not asigned get one*/ 285 /* If Id is not assigned get one*/
286 if (id == MEI_HOST_CLIENT_ID_ANY) 286 if (id == MEI_HOST_CLIENT_ID_ANY)
287 id = find_first_zero_bit(dev->host_clients_map, 287 id = find_first_zero_bit(dev->host_clients_map,
288 MEI_CLIENTS_MAX); 288 MEI_CLIENTS_MAX);
289 289
290 if (id >= MEI_CLIENTS_MAX) { 290 if (id >= MEI_CLIENTS_MAX) {
291 dev_err(&dev->pdev->dev, "id exceded %d", MEI_CLIENTS_MAX) ; 291 dev_err(&dev->pdev->dev, "id exceeded %d", MEI_CLIENTS_MAX);
292 return -EMFILE; 292 return -EMFILE;
293 } 293 }
294 294
295 open_handle_count = dev->open_handle_count + dev->iamthif_open_count; 295 open_handle_count = dev->open_handle_count + dev->iamthif_open_count;
296 if (open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) { 296 if (open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
297 dev_err(&dev->pdev->dev, "open_handle_count exceded %d", 297 dev_err(&dev->pdev->dev, "open_handle_count exceeded %d",
298 MEI_MAX_OPEN_HANDLE_COUNT); 298 MEI_MAX_OPEN_HANDLE_COUNT);
299 return -EMFILE; 299 return -EMFILE;
300 } 300 }
@@ -344,8 +344,6 @@ int mei_cl_unlink(struct mei_cl *cl)
344 344
345 cl->state = MEI_FILE_INITIALIZING; 345 cl->state = MEI_FILE_INITIALIZING;
346 346
347 list_del_init(&cl->link);
348
349 return 0; 347 return 0;
350} 348}
351 349
@@ -372,13 +370,14 @@ void mei_host_client_init(struct work_struct *work)
372 } 370 }
373 371
374 dev->dev_state = MEI_DEV_ENABLED; 372 dev->dev_state = MEI_DEV_ENABLED;
373 dev->reset_count = 0;
375 374
376 mutex_unlock(&dev->device_lock); 375 mutex_unlock(&dev->device_lock);
377} 376}
378 377
379 378
380/** 379/**
381 * mei_cl_disconnect - disconnect host clinet form the me one 380 * mei_cl_disconnect - disconnect host client from the me one
382 * 381 *
383 * @cl: host client 382 * @cl: host client
384 * 383 *
@@ -457,7 +456,7 @@ free:
457 * 456 *
458 * @cl: private data of the file object 457 * @cl: private data of the file object
459 * 458 *
460 * returns ture if other client is connected, 0 - otherwise. 459 * returns true if other client is connected, false - otherwise.
461 */ 460 */
462bool mei_cl_is_other_connecting(struct mei_cl *cl) 461bool mei_cl_is_other_connecting(struct mei_cl *cl)
463{ 462{
@@ -481,7 +480,7 @@ bool mei_cl_is_other_connecting(struct mei_cl *cl)
481} 480}
482 481
483/** 482/**
484 * mei_cl_connect - connect host clinet to the me one 483 * mei_cl_connect - connect host client to the me one
485 * 484 *
486 * @cl: host client 485 * @cl: host client
487 * 486 *
@@ -729,6 +728,7 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
729 mei_hdr.host_addr = cl->host_client_id; 728 mei_hdr.host_addr = cl->host_client_id;
730 mei_hdr.me_addr = cl->me_client_id; 729 mei_hdr.me_addr = cl->me_client_id;
731 mei_hdr.reserved = 0; 730 mei_hdr.reserved = 0;
731 mei_hdr.internal = cb->internal;
732 732
733 if (*slots >= msg_slots) { 733 if (*slots >= msg_slots) {
734 mei_hdr.length = len; 734 mei_hdr.length = len;
@@ -775,7 +775,7 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
775 * @cl: host client 775 * @cl: host client
776 * @cl: write callback with filled data 776 * @cl: write callback with filled data
777 * 777 *
778 * returns numbe of bytes sent on success, <0 on failure. 778 * returns number of bytes sent on success, <0 on failure.
779 */ 779 */
780int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) 780int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
781{ 781{
@@ -828,6 +828,7 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
828 mei_hdr.host_addr = cl->host_client_id; 828 mei_hdr.host_addr = cl->host_client_id;
829 mei_hdr.me_addr = cl->me_client_id; 829 mei_hdr.me_addr = cl->me_client_id;
830 mei_hdr.reserved = 0; 830 mei_hdr.reserved = 0;
831 mei_hdr.internal = cb->internal;
831 832
832 833
833 rets = mei_write_message(dev, &mei_hdr, buf->data); 834 rets = mei_write_message(dev, &mei_hdr, buf->data);
diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c
index e3870f22d238..a3ae154444b2 100644
--- a/drivers/misc/mei/debugfs.c
+++ b/drivers/misc/mei/debugfs.c
@@ -43,7 +43,7 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf,
43 43
44 mutex_lock(&dev->device_lock); 44 mutex_lock(&dev->device_lock);
45 45
46 /* if the driver is not enabled the list won't b consitent */ 46 /* if the driver is not enabled the list won't be consistent */
47 if (dev->dev_state != MEI_DEV_ENABLED) 47 if (dev->dev_state != MEI_DEV_ENABLED)
48 goto out; 48 goto out;
49 49
@@ -101,7 +101,7 @@ static const struct file_operations mei_dbgfs_fops_devstate = {
101 101
102/** 102/**
103 * mei_dbgfs_deregister - Remove the debugfs files and directories 103 * mei_dbgfs_deregister - Remove the debugfs files and directories
104 * @mei - pointer to mei device private dat 104 * @mei - pointer to mei device private data
105 */ 105 */
106void mei_dbgfs_deregister(struct mei_device *dev) 106void mei_dbgfs_deregister(struct mei_device *dev)
107{ 107{
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 9b3a0fb7f265..28cd74c073b9 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -28,9 +28,9 @@
28 * 28 *
29 * @dev: the device structure 29 * @dev: the device structure
30 * 30 *
31 * returns none. 31 * returns 0 on success -ENOMEM on allocation failure
32 */ 32 */
33static void mei_hbm_me_cl_allocate(struct mei_device *dev) 33static int mei_hbm_me_cl_allocate(struct mei_device *dev)
34{ 34{
35 struct mei_me_client *clients; 35 struct mei_me_client *clients;
36 int b; 36 int b;
@@ -44,7 +44,7 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev)
44 dev->me_clients_num++; 44 dev->me_clients_num++;
45 45
46 if (dev->me_clients_num == 0) 46 if (dev->me_clients_num == 0)
47 return; 47 return 0;
48 48
49 kfree(dev->me_clients); 49 kfree(dev->me_clients);
50 dev->me_clients = NULL; 50 dev->me_clients = NULL;
@@ -56,12 +56,10 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev)
56 sizeof(struct mei_me_client), GFP_KERNEL); 56 sizeof(struct mei_me_client), GFP_KERNEL);
57 if (!clients) { 57 if (!clients) {
58 dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n"); 58 dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
59 dev->dev_state = MEI_DEV_RESETTING; 59 return -ENOMEM;
60 mei_reset(dev, 1);
61 return;
62 } 60 }
63 dev->me_clients = clients; 61 dev->me_clients = clients;
64 return; 62 return 0;
65} 63}
66 64
67/** 65/**
@@ -85,12 +83,12 @@ void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len)
85} 83}
86 84
87/** 85/**
88 * same_disconn_addr - tells if they have the same address 86 * mei_hbm_cl_addr_equal - tells if they have the same address
89 * 87 *
90 * @file: private data of the file object. 88 * @cl: - client
91 * @disconn: disconnection request. 89 * @buf: buffer with cl header
92 * 90 *
93 * returns true if addres are same 91 * returns true if addresses are the same
94 */ 92 */
95static inline 93static inline
96bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf) 94bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf)
@@ -128,6 +126,17 @@ static bool is_treat_specially_client(struct mei_cl *cl,
128 return false; 126 return false;
129} 127}
130 128
129/**
130 * mei_hbm_idle - set hbm to idle state
131 *
132 * @dev: the device structure
133 */
134void mei_hbm_idle(struct mei_device *dev)
135{
136 dev->init_clients_timer = 0;
137 dev->hbm_state = MEI_HBM_IDLE;
138}
139
131int mei_hbm_start_wait(struct mei_device *dev) 140int mei_hbm_start_wait(struct mei_device *dev)
132{ 141{
133 int ret; 142 int ret;
@@ -137,7 +146,7 @@ int mei_hbm_start_wait(struct mei_device *dev)
137 mutex_unlock(&dev->device_lock); 146 mutex_unlock(&dev->device_lock);
138 ret = wait_event_interruptible_timeout(dev->wait_recvd_msg, 147 ret = wait_event_interruptible_timeout(dev->wait_recvd_msg,
139 dev->hbm_state == MEI_HBM_IDLE || 148 dev->hbm_state == MEI_HBM_IDLE ||
140 dev->hbm_state > MEI_HBM_START, 149 dev->hbm_state >= MEI_HBM_STARTED,
141 mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT)); 150 mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT));
142 mutex_lock(&dev->device_lock); 151 mutex_lock(&dev->device_lock);
143 152
@@ -153,12 +162,15 @@ int mei_hbm_start_wait(struct mei_device *dev)
153 * mei_hbm_start_req - sends start request message. 162 * mei_hbm_start_req - sends start request message.
154 * 163 *
155 * @dev: the device structure 164 * @dev: the device structure
165 *
166 * returns 0 on success and < 0 on failure
156 */ 167 */
157int mei_hbm_start_req(struct mei_device *dev) 168int mei_hbm_start_req(struct mei_device *dev)
158{ 169{
159 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 170 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
160 struct hbm_host_version_request *start_req; 171 struct hbm_host_version_request *start_req;
161 const size_t len = sizeof(struct hbm_host_version_request); 172 const size_t len = sizeof(struct hbm_host_version_request);
173 int ret;
162 174
163 mei_hbm_hdr(mei_hdr, len); 175 mei_hbm_hdr(mei_hdr, len);
164 176
@@ -170,12 +182,13 @@ int mei_hbm_start_req(struct mei_device *dev)
170 start_req->host_version.minor_version = HBM_MINOR_VERSION; 182 start_req->host_version.minor_version = HBM_MINOR_VERSION;
171 183
172 dev->hbm_state = MEI_HBM_IDLE; 184 dev->hbm_state = MEI_HBM_IDLE;
173 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { 185 ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data);
174 dev_err(&dev->pdev->dev, "version message write failed\n"); 186 if (ret) {
175 dev->dev_state = MEI_DEV_RESETTING; 187 dev_err(&dev->pdev->dev, "version message write failed: ret = %d\n",
176 mei_reset(dev, 1); 188 ret);
177 return -EIO; 189 return ret;
178 } 190 }
191
179 dev->hbm_state = MEI_HBM_START; 192 dev->hbm_state = MEI_HBM_START;
180 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 193 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
181 return 0; 194 return 0;
@@ -186,13 +199,15 @@ int mei_hbm_start_req(struct mei_device *dev)
186 * 199 *
187 * @dev: the device structure 200 * @dev: the device structure
188 * 201 *
189 * returns none. 202 * returns 0 on success and < 0 on failure
190 */ 203 */
191static void mei_hbm_enum_clients_req(struct mei_device *dev) 204static int mei_hbm_enum_clients_req(struct mei_device *dev)
192{ 205{
193 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 206 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
194 struct hbm_host_enum_request *enum_req; 207 struct hbm_host_enum_request *enum_req;
195 const size_t len = sizeof(struct hbm_host_enum_request); 208 const size_t len = sizeof(struct hbm_host_enum_request);
209 int ret;
210
196 /* enumerate clients */ 211 /* enumerate clients */
197 mei_hbm_hdr(mei_hdr, len); 212 mei_hbm_hdr(mei_hdr, len);
198 213
@@ -200,14 +215,15 @@ static void mei_hbm_enum_clients_req(struct mei_device *dev)
200 memset(enum_req, 0, len); 215 memset(enum_req, 0, len);
201 enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; 216 enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
202 217
203 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { 218 ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data);
204 dev->dev_state = MEI_DEV_RESETTING; 219 if (ret) {
205 dev_err(&dev->pdev->dev, "enumeration request write failed.\n"); 220 dev_err(&dev->pdev->dev, "enumeration request write failed: ret = %d.\n",
206 mei_reset(dev, 1); 221 ret);
222 return ret;
207 } 223 }
208 dev->hbm_state = MEI_HBM_ENUM_CLIENTS; 224 dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
209 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 225 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
210 return; 226 return 0;
211} 227}
212 228
213/** 229/**
@@ -215,7 +231,7 @@ static void mei_hbm_enum_clients_req(struct mei_device *dev)
215 * 231 *
216 * @dev: the device structure 232 * @dev: the device structure
217 * 233 *
218 * returns none. 234 * returns 0 on success and < 0 on failure
219 */ 235 */
220 236
221static int mei_hbm_prop_req(struct mei_device *dev) 237static int mei_hbm_prop_req(struct mei_device *dev)
@@ -226,7 +242,7 @@ static int mei_hbm_prop_req(struct mei_device *dev)
226 const size_t len = sizeof(struct hbm_props_request); 242 const size_t len = sizeof(struct hbm_props_request);
227 unsigned long next_client_index; 243 unsigned long next_client_index;
228 unsigned long client_num; 244 unsigned long client_num;
229 245 int ret;
230 246
231 client_num = dev->me_client_presentation_num; 247 client_num = dev->me_client_presentation_num;
232 248
@@ -253,12 +269,11 @@ static int mei_hbm_prop_req(struct mei_device *dev)
253 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; 269 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
254 prop_req->address = next_client_index; 270 prop_req->address = next_client_index;
255 271
256 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { 272 ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data);
257 dev->dev_state = MEI_DEV_RESETTING; 273 if (ret) {
258 dev_err(&dev->pdev->dev, "properties request write failed\n"); 274 dev_err(&dev->pdev->dev, "properties request write failed: ret = %d\n",
259 mei_reset(dev, 1); 275 ret);
260 276 return ret;
261 return -EIO;
262 } 277 }
263 278
264 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 279 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
@@ -268,7 +283,7 @@ static int mei_hbm_prop_req(struct mei_device *dev)
268} 283}
269 284
270/** 285/**
271 * mei_hbm_stop_req_prepare - perpare stop request message 286 * mei_hbm_stop_req_prepare - prepare stop request message
272 * 287 *
273 * @dev - mei device 288 * @dev - mei device
274 * @mei_hdr - mei message header 289 * @mei_hdr - mei message header
@@ -289,7 +304,7 @@ static void mei_hbm_stop_req_prepare(struct mei_device *dev,
289} 304}
290 305
291/** 306/**
292 * mei_hbm_cl_flow_control_req - sends flow control requst. 307 * mei_hbm_cl_flow_control_req - sends flow control request.
293 * 308 *
294 * @dev: the device structure 309 * @dev: the device structure
295 * @cl: client info 310 * @cl: client info
@@ -451,7 +466,7 @@ int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl)
451} 466}
452 467
453/** 468/**
454 * mei_hbm_cl_connect_res - connect resposne from the ME 469 * mei_hbm_cl_connect_res - connect response from the ME
455 * 470 *
456 * @dev: the device structure 471 * @dev: the device structure
457 * @rs: connect response bus message 472 * @rs: connect response bus message
@@ -505,8 +520,8 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
505 520
506 521
507/** 522/**
508 * mei_hbm_fw_disconnect_req - disconnect request initiated by me 523 * mei_hbm_fw_disconnect_req - disconnect request initiated by ME firmware
509 * host sends disoconnect response 524 * host sends disconnect response
510 * 525 *
511 * @dev: the device structure. 526 * @dev: the device structure.
512 * @disconnect_req: disconnect request bus message from the me 527 * @disconnect_req: disconnect request bus message from the me
@@ -559,8 +574,10 @@ bool mei_hbm_version_is_supported(struct mei_device *dev)
559 * 574 *
560 * @dev: the device structure 575 * @dev: the device structure
561 * @mei_hdr: header of bus message 576 * @mei_hdr: header of bus message
577 *
578 * returns 0 on success and < 0 on failure
562 */ 579 */
563void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) 580int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
564{ 581{
565 struct mei_bus_message *mei_msg; 582 struct mei_bus_message *mei_msg;
566 struct mei_me_client *me_client; 583 struct mei_me_client *me_client;
@@ -577,8 +594,20 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
577 mei_read_slots(dev, dev->rd_msg_buf, hdr->length); 594 mei_read_slots(dev, dev->rd_msg_buf, hdr->length);
578 mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; 595 mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;
579 596
597 /* ignore spurious message and prevent reset nesting
598 * hbm is put to idle during system reset
599 */
600 if (dev->hbm_state == MEI_HBM_IDLE) {
601 dev_dbg(&dev->pdev->dev, "hbm: state is idle ignore spurious messages\n");
602 return 0;
603 }
604
580 switch (mei_msg->hbm_cmd) { 605 switch (mei_msg->hbm_cmd) {
581 case HOST_START_RES_CMD: 606 case HOST_START_RES_CMD:
607 dev_dbg(&dev->pdev->dev, "hbm: start: response message received.\n");
608
609 dev->init_clients_timer = 0;
610
582 version_res = (struct hbm_host_version_response *)mei_msg; 611 version_res = (struct hbm_host_version_response *)mei_msg;
583 612
584 dev_dbg(&dev->pdev->dev, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n", 613 dev_dbg(&dev->pdev->dev, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n",
@@ -597,73 +626,89 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
597 } 626 }
598 627
599 if (!mei_hbm_version_is_supported(dev)) { 628 if (!mei_hbm_version_is_supported(dev)) {
600 dev_warn(&dev->pdev->dev, "hbm version mismatch: stopping the driver.\n"); 629 dev_warn(&dev->pdev->dev, "hbm: start: version mismatch - stopping the driver.\n");
601 630
602 dev->hbm_state = MEI_HBM_STOP; 631 dev->hbm_state = MEI_HBM_STOPPED;
603 mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr, 632 mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr,
604 dev->wr_msg.data); 633 dev->wr_msg.data);
605 mei_write_message(dev, &dev->wr_msg.hdr, 634 if (mei_write_message(dev, &dev->wr_msg.hdr,
606 dev->wr_msg.data); 635 dev->wr_msg.data)) {
636 dev_err(&dev->pdev->dev, "hbm: start: failed to send stop request\n");
637 return -EIO;
638 }
639 break;
640 }
607 641
608 return; 642 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
643 dev->hbm_state != MEI_HBM_START) {
644 dev_err(&dev->pdev->dev, "hbm: start: state mismatch, [%d, %d]\n",
645 dev->dev_state, dev->hbm_state);
646 return -EPROTO;
609 } 647 }
610 648
611 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 649 dev->hbm_state = MEI_HBM_STARTED;
612 dev->hbm_state == MEI_HBM_START) { 650
613 dev->init_clients_timer = 0; 651 if (mei_hbm_enum_clients_req(dev)) {
614 mei_hbm_enum_clients_req(dev); 652 dev_err(&dev->pdev->dev, "hbm: start: failed to send enumeration request\n");
615 } else { 653 return -EIO;
616 dev_err(&dev->pdev->dev, "reset: wrong host start response\n");
617 mei_reset(dev, 1);
618 return;
619 } 654 }
620 655
621 wake_up_interruptible(&dev->wait_recvd_msg); 656 wake_up_interruptible(&dev->wait_recvd_msg);
622 dev_dbg(&dev->pdev->dev, "host start response message received.\n");
623 break; 657 break;
624 658
625 case CLIENT_CONNECT_RES_CMD: 659 case CLIENT_CONNECT_RES_CMD:
660 dev_dbg(&dev->pdev->dev, "hbm: client connect response: message received.\n");
661
626 connect_res = (struct hbm_client_connect_response *) mei_msg; 662 connect_res = (struct hbm_client_connect_response *) mei_msg;
627 mei_hbm_cl_connect_res(dev, connect_res); 663 mei_hbm_cl_connect_res(dev, connect_res);
628 dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
629 wake_up(&dev->wait_recvd_msg); 664 wake_up(&dev->wait_recvd_msg);
630 break; 665 break;
631 666
632 case CLIENT_DISCONNECT_RES_CMD: 667 case CLIENT_DISCONNECT_RES_CMD:
668 dev_dbg(&dev->pdev->dev, "hbm: client disconnect response: message received.\n");
669
633 disconnect_res = (struct hbm_client_connect_response *) mei_msg; 670 disconnect_res = (struct hbm_client_connect_response *) mei_msg;
634 mei_hbm_cl_disconnect_res(dev, disconnect_res); 671 mei_hbm_cl_disconnect_res(dev, disconnect_res);
635 dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
636 wake_up(&dev->wait_recvd_msg); 672 wake_up(&dev->wait_recvd_msg);
637 break; 673 break;
638 674
639 case MEI_FLOW_CONTROL_CMD: 675 case MEI_FLOW_CONTROL_CMD:
676 dev_dbg(&dev->pdev->dev, "hbm: client flow control response: message received.\n");
677
640 flow_control = (struct hbm_flow_control *) mei_msg; 678 flow_control = (struct hbm_flow_control *) mei_msg;
641 mei_hbm_cl_flow_control_res(dev, flow_control); 679 mei_hbm_cl_flow_control_res(dev, flow_control);
642 dev_dbg(&dev->pdev->dev, "client flow control response message received.\n");
643 break; 680 break;
644 681
645 case HOST_CLIENT_PROPERTIES_RES_CMD: 682 case HOST_CLIENT_PROPERTIES_RES_CMD:
683 dev_dbg(&dev->pdev->dev, "hbm: properties response: message received.\n");
684
685 dev->init_clients_timer = 0;
686
687 if (dev->me_clients == NULL) {
688 dev_err(&dev->pdev->dev, "hbm: properties response: mei_clients not allocated\n");
689 return -EPROTO;
690 }
691
646 props_res = (struct hbm_props_response *)mei_msg; 692 props_res = (struct hbm_props_response *)mei_msg;
647 me_client = &dev->me_clients[dev->me_client_presentation_num]; 693 me_client = &dev->me_clients[dev->me_client_presentation_num];
648 694
649 if (props_res->status || !dev->me_clients) { 695 if (props_res->status) {
650 dev_err(&dev->pdev->dev, "reset: properties response hbm wrong status.\n"); 696 dev_err(&dev->pdev->dev, "hbm: properties response: wrong status = %d\n",
651 mei_reset(dev, 1); 697 props_res->status);
652 return; 698 return -EPROTO;
653 } 699 }
654 700
655 if (me_client->client_id != props_res->address) { 701 if (me_client->client_id != props_res->address) {
656 dev_err(&dev->pdev->dev, "reset: host properties response address mismatch\n"); 702 dev_err(&dev->pdev->dev, "hbm: properties response: address mismatch %d ?= %d\n",
657 mei_reset(dev, 1); 703 me_client->client_id, props_res->address);
658 return; 704 return -EPROTO;
659 } 705 }
660 706
661 if (dev->dev_state != MEI_DEV_INIT_CLIENTS || 707 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
662 dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) { 708 dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
663 dev_err(&dev->pdev->dev, "reset: unexpected properties response\n"); 709 dev_err(&dev->pdev->dev, "hbm: properties response: state mismatch, [%d, %d]\n",
664 mei_reset(dev, 1); 710 dev->dev_state, dev->hbm_state);
665 711 return -EPROTO;
666 return;
667 } 712 }
668 713
669 me_client->props = props_res->client_properties; 714 me_client->props = props_res->client_properties;
@@ -671,49 +716,70 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
671 dev->me_client_presentation_num++; 716 dev->me_client_presentation_num++;
672 717
673 /* request property for the next client */ 718 /* request property for the next client */
674 mei_hbm_prop_req(dev); 719 if (mei_hbm_prop_req(dev))
720 return -EIO;
675 721
676 break; 722 break;
677 723
678 case HOST_ENUM_RES_CMD: 724 case HOST_ENUM_RES_CMD:
725 dev_dbg(&dev->pdev->dev, "hbm: enumeration response: message received\n");
726
727 dev->init_clients_timer = 0;
728
679 enum_res = (struct hbm_host_enum_response *) mei_msg; 729 enum_res = (struct hbm_host_enum_response *) mei_msg;
680 BUILD_BUG_ON(sizeof(dev->me_clients_map) 730 BUILD_BUG_ON(sizeof(dev->me_clients_map)
681 < sizeof(enum_res->valid_addresses)); 731 < sizeof(enum_res->valid_addresses));
682 memcpy(dev->me_clients_map, enum_res->valid_addresses, 732 memcpy(dev->me_clients_map, enum_res->valid_addresses,
683 sizeof(enum_res->valid_addresses)); 733 sizeof(enum_res->valid_addresses));
684 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 734
685 dev->hbm_state == MEI_HBM_ENUM_CLIENTS) { 735 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
686 dev->init_clients_timer = 0; 736 dev->hbm_state != MEI_HBM_ENUM_CLIENTS) {
687 mei_hbm_me_cl_allocate(dev); 737 dev_err(&dev->pdev->dev, "hbm: enumeration response: state mismatch, [%d, %d]\n",
688 dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES; 738 dev->dev_state, dev->hbm_state);
689 739 return -EPROTO;
690 /* first property reqeust */ 740 }
691 mei_hbm_prop_req(dev); 741
692 } else { 742 if (mei_hbm_me_cl_allocate(dev)) {
693 dev_err(&dev->pdev->dev, "reset: unexpected enumeration response hbm.\n"); 743 dev_err(&dev->pdev->dev, "hbm: enumeration response: cannot allocate clients array\n");
694 mei_reset(dev, 1); 744 return -ENOMEM;
695 return;
696 } 745 }
746
747 dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES;
748
749 /* first property request */
750 if (mei_hbm_prop_req(dev))
751 return -EIO;
752
697 break; 753 break;
698 754
699 case HOST_STOP_RES_CMD: 755 case HOST_STOP_RES_CMD:
756 dev_dbg(&dev->pdev->dev, "hbm: stop response: message received\n");
757
758 dev->init_clients_timer = 0;
700 759
701 if (dev->hbm_state != MEI_HBM_STOP) 760 if (dev->hbm_state != MEI_HBM_STOPPED) {
702 dev_err(&dev->pdev->dev, "unexpected stop response hbm.\n"); 761 dev_err(&dev->pdev->dev, "hbm: stop response: state mismatch, [%d, %d]\n",
703 dev->dev_state = MEI_DEV_DISABLED; 762 dev->dev_state, dev->hbm_state);
704 dev_info(&dev->pdev->dev, "reset: FW stop response.\n"); 763 return -EPROTO;
705 mei_reset(dev, 1); 764 }
765
766 dev->dev_state = MEI_DEV_POWER_DOWN;
767 dev_info(&dev->pdev->dev, "hbm: stop response: resetting.\n");
768 /* force the reset */
769 return -EPROTO;
706 break; 770 break;
707 771
708 case CLIENT_DISCONNECT_REQ_CMD: 772 case CLIENT_DISCONNECT_REQ_CMD:
709 /* search for client */ 773 dev_dbg(&dev->pdev->dev, "hbm: disconnect request: message received\n");
774
710 disconnect_req = (struct hbm_client_connect_request *)mei_msg; 775 disconnect_req = (struct hbm_client_connect_request *)mei_msg;
711 mei_hbm_fw_disconnect_req(dev, disconnect_req); 776 mei_hbm_fw_disconnect_req(dev, disconnect_req);
712 break; 777 break;
713 778
714 case ME_STOP_REQ_CMD: 779 case ME_STOP_REQ_CMD:
780 dev_dbg(&dev->pdev->dev, "hbm: stop request: message received\n");
715 781
716 dev->hbm_state = MEI_HBM_STOP; 782 dev->hbm_state = MEI_HBM_STOPPED;
717 mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr, 783 mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr,
718 dev->wr_ext_msg.data); 784 dev->wr_ext_msg.data);
719 break; 785 break;
@@ -722,5 +788,6 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
722 break; 788 break;
723 789
724 } 790 }
791 return 0;
725} 792}
726 793
diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h
index 4ae2e56e404f..5f92188a5cd7 100644
--- a/drivers/misc/mei/hbm.h
+++ b/drivers/misc/mei/hbm.h
@@ -32,13 +32,13 @@ struct mei_cl;
32enum mei_hbm_state { 32enum mei_hbm_state {
33 MEI_HBM_IDLE = 0, 33 MEI_HBM_IDLE = 0,
34 MEI_HBM_START, 34 MEI_HBM_START,
35 MEI_HBM_STARTED,
35 MEI_HBM_ENUM_CLIENTS, 36 MEI_HBM_ENUM_CLIENTS,
36 MEI_HBM_CLIENT_PROPERTIES, 37 MEI_HBM_CLIENT_PROPERTIES,
37 MEI_HBM_STARTED, 38 MEI_HBM_STOPPED,
38 MEI_HBM_STOP,
39}; 39};
40 40
41void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr); 41int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr);
42 42
43static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) 43static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length)
44{ 44{
@@ -49,6 +49,7 @@ static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length)
49 hdr->reserved = 0; 49 hdr->reserved = 0;
50} 50}
51 51
52void mei_hbm_idle(struct mei_device *dev);
52int mei_hbm_start_req(struct mei_device *dev); 53int mei_hbm_start_req(struct mei_device *dev);
53int mei_hbm_start_wait(struct mei_device *dev); 54int mei_hbm_start_wait(struct mei_device *dev);
54int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl); 55int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl);
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 3412adcdaeb0..6f656c053b14 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -185,7 +185,7 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
185 185
186 mei_me_reg_write(hw, H_CSR, hcsr); 186 mei_me_reg_write(hw, H_CSR, hcsr);
187 187
188 if (dev->dev_state == MEI_DEV_POWER_DOWN) 188 if (intr_enable == false)
189 mei_me_hw_reset_release(dev); 189 mei_me_hw_reset_release(dev);
190 190
191 return 0; 191 return 0;
@@ -469,7 +469,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
469 struct mei_device *dev = (struct mei_device *) dev_id; 469 struct mei_device *dev = (struct mei_device *) dev_id;
470 struct mei_cl_cb complete_list; 470 struct mei_cl_cb complete_list;
471 s32 slots; 471 s32 slots;
472 int rets; 472 int rets = 0;
473 473
474 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); 474 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n");
475 /* initialize our complete list */ 475 /* initialize our complete list */
@@ -482,15 +482,10 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
482 mei_clear_interrupts(dev); 482 mei_clear_interrupts(dev);
483 483
484 /* check if ME wants a reset */ 484 /* check if ME wants a reset */
485 if (!mei_hw_is_ready(dev) && 485 if (!mei_hw_is_ready(dev) && dev->dev_state != MEI_DEV_RESETTING) {
486 dev->dev_state != MEI_DEV_RESETTING && 486 dev_warn(&dev->pdev->dev, "FW not ready: resetting.\n");
487 dev->dev_state != MEI_DEV_INITIALIZING && 487 schedule_work(&dev->reset_work);
488 dev->dev_state != MEI_DEV_POWER_DOWN && 488 goto end;
489 dev->dev_state != MEI_DEV_POWER_UP) {
490 dev_dbg(&dev->pdev->dev, "FW not ready.\n");
491 mei_reset(dev, 1);
492 mutex_unlock(&dev->device_lock);
493 return IRQ_HANDLED;
494 } 489 }
495 490
496 /* check if we need to start the dev */ 491 /* check if we need to start the dev */
@@ -500,15 +495,12 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
500 495
501 dev->recvd_hw_ready = true; 496 dev->recvd_hw_ready = true;
502 wake_up_interruptible(&dev->wait_hw_ready); 497 wake_up_interruptible(&dev->wait_hw_ready);
503
504 mutex_unlock(&dev->device_lock);
505 return IRQ_HANDLED;
506 } else { 498 } else {
499
507 dev_dbg(&dev->pdev->dev, "Reset Completed.\n"); 500 dev_dbg(&dev->pdev->dev, "Reset Completed.\n");
508 mei_me_hw_reset_release(dev); 501 mei_me_hw_reset_release(dev);
509 mutex_unlock(&dev->device_lock);
510 return IRQ_HANDLED;
511 } 502 }
503 goto end;
512 } 504 }
513 /* check slots available for reading */ 505 /* check slots available for reading */
514 slots = mei_count_full_read_slots(dev); 506 slots = mei_count_full_read_slots(dev);
@@ -516,21 +508,23 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
516 /* we have urgent data to send so break the read */ 508 /* we have urgent data to send so break the read */
517 if (dev->wr_ext_msg.hdr.length) 509 if (dev->wr_ext_msg.hdr.length)
518 break; 510 break;
519 dev_dbg(&dev->pdev->dev, "slots =%08x\n", slots); 511 dev_dbg(&dev->pdev->dev, "slots to read = %08x\n", slots);
520 dev_dbg(&dev->pdev->dev, "call mei_irq_read_handler.\n");
521 rets = mei_irq_read_handler(dev, &complete_list, &slots); 512 rets = mei_irq_read_handler(dev, &complete_list, &slots);
522 if (rets) 513 if (rets && dev->dev_state != MEI_DEV_RESETTING) {
514 schedule_work(&dev->reset_work);
523 goto end; 515 goto end;
516 }
524 } 517 }
518
525 rets = mei_irq_write_handler(dev, &complete_list); 519 rets = mei_irq_write_handler(dev, &complete_list);
526end:
527 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
528 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
529 520
530 mutex_unlock(&dev->device_lock); 521 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
531 522
532 mei_irq_compl_handler(dev, &complete_list); 523 mei_irq_compl_handler(dev, &complete_list);
533 524
525end:
526 dev_dbg(&dev->pdev->dev, "interrupt thread end ret = %d\n", rets);
527 mutex_unlock(&dev->device_lock);
534 return IRQ_HANDLED; 528 return IRQ_HANDLED;
535} 529}
536static const struct mei_hw_ops mei_me_hw_ops = { 530static const struct mei_hw_ops mei_me_hw_ops = {
diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h
index cb2f556b4252..dd44e33ad2b6 100644
--- a/drivers/misc/mei/hw.h
+++ b/drivers/misc/mei/hw.h
@@ -111,7 +111,8 @@ struct mei_msg_hdr {
111 u32 me_addr:8; 111 u32 me_addr:8;
112 u32 host_addr:8; 112 u32 host_addr:8;
113 u32 length:9; 113 u32 length:9;
114 u32 reserved:6; 114 u32 reserved:5;
115 u32 internal:1;
115 u32 msg_complete:1; 116 u32 msg_complete:1;
116} __packed; 117} __packed;
117 118
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index f7f3abbe12b6..cdd31c2a2a2b 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -43,41 +43,119 @@ const char *mei_dev_state_str(int state)
43#undef MEI_DEV_STATE 43#undef MEI_DEV_STATE
44} 44}
45 45
46void mei_device_init(struct mei_device *dev)
47{
48 /* setup our list array */
49 INIT_LIST_HEAD(&dev->file_list);
50 INIT_LIST_HEAD(&dev->device_list);
51 mutex_init(&dev->device_lock);
52 init_waitqueue_head(&dev->wait_hw_ready);
53 init_waitqueue_head(&dev->wait_recvd_msg);
54 init_waitqueue_head(&dev->wait_stop_wd);
55 dev->dev_state = MEI_DEV_INITIALIZING;
56 46
57 mei_io_list_init(&dev->read_list); 47/**
58 mei_io_list_init(&dev->write_list); 48 * mei_cancel_work. Cancel mei background jobs
59 mei_io_list_init(&dev->write_waiting_list); 49 *
60 mei_io_list_init(&dev->ctrl_wr_list); 50 * @dev: the device structure
61 mei_io_list_init(&dev->ctrl_rd_list); 51 *
52 * returns 0 on success or < 0 if the reset hasn't succeeded
53 */
54void mei_cancel_work(struct mei_device *dev)
55{
56 cancel_work_sync(&dev->init_work);
57 cancel_work_sync(&dev->reset_work);
62 58
63 INIT_DELAYED_WORK(&dev->timer_work, mei_timer); 59 cancel_delayed_work(&dev->timer_work);
64 INIT_WORK(&dev->init_work, mei_host_client_init); 60}
61EXPORT_SYMBOL_GPL(mei_cancel_work);
65 62
66 INIT_LIST_HEAD(&dev->wd_cl.link); 63/**
67 INIT_LIST_HEAD(&dev->iamthif_cl.link); 64 * mei_reset - resets host and fw.
68 mei_io_list_init(&dev->amthif_cmd_list); 65 *
69 mei_io_list_init(&dev->amthif_rd_complete_list); 66 * @dev: the device structure
67 */
68int mei_reset(struct mei_device *dev)
69{
70 enum mei_dev_state state = dev->dev_state;
71 bool interrupts_enabled;
72 int ret;
70 73
71 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX); 74 if (state != MEI_DEV_INITIALIZING &&
72 dev->open_handle_count = 0; 75 state != MEI_DEV_DISABLED &&
76 state != MEI_DEV_POWER_DOWN &&
77 state != MEI_DEV_POWER_UP)
78 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
79 mei_dev_state_str(state));
73 80
74 /* 81 /* we're already in reset, cancel the init timer
75 * Reserving the first client ID 82 * if the reset was called due the hbm protocol error
76 * 0: Reserved for MEI Bus Message communications 83 * we need to call it before hw start
84 * so the hbm watchdog won't kick in
77 */ 85 */
78 bitmap_set(dev->host_clients_map, 0, 1); 86 mei_hbm_idle(dev);
87
88 /* enter reset flow */
89 interrupts_enabled = state != MEI_DEV_POWER_DOWN;
90 dev->dev_state = MEI_DEV_RESETTING;
91
92 dev->reset_count++;
93 if (dev->reset_count > MEI_MAX_CONSEC_RESET) {
94 dev_err(&dev->pdev->dev, "reset: reached maximal consecutive resets: disabling the device\n");
95 dev->dev_state = MEI_DEV_DISABLED;
96 return -ENODEV;
97 }
98
99 ret = mei_hw_reset(dev, interrupts_enabled);
100 /* fall through and remove the sw state even if hw reset has failed */
101
102 /* no need to clean up software state in case of power up */
103 if (state != MEI_DEV_INITIALIZING &&
104 state != MEI_DEV_POWER_UP) {
105
106 /* remove all waiting requests */
107 mei_cl_all_write_clear(dev);
108
109 mei_cl_all_disconnect(dev);
110
111 /* wake up all readers and writers so they can be interrupted */
112 mei_cl_all_wakeup(dev);
113
114 /* remove entry if already in list */
115 dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
116 mei_cl_unlink(&dev->wd_cl);
117 mei_cl_unlink(&dev->iamthif_cl);
118 mei_amthif_reset_params(dev);
119 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
120 }
121
122
123 dev->me_clients_num = 0;
124 dev->rd_msg_hdr = 0;
125 dev->wd_pending = false;
126
127 if (ret) {
128 dev_err(&dev->pdev->dev, "hw_reset failed ret = %d\n", ret);
129 dev->dev_state = MEI_DEV_DISABLED;
130 return ret;
131 }
132
133 if (state == MEI_DEV_POWER_DOWN) {
134 dev_dbg(&dev->pdev->dev, "powering down: end of reset\n");
135 dev->dev_state = MEI_DEV_DISABLED;
136 return 0;
137 }
138
139 ret = mei_hw_start(dev);
140 if (ret) {
141 dev_err(&dev->pdev->dev, "hw_start failed ret = %d\n", ret);
142 dev->dev_state = MEI_DEV_DISABLED;
143 return ret;
144 }
145
146 dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
147
148 dev->dev_state = MEI_DEV_INIT_CLIENTS;
149 ret = mei_hbm_start_req(dev);
150 if (ret) {
151 dev_err(&dev->pdev->dev, "hbm_start failed ret = %d\n", ret);
152 dev->dev_state = MEI_DEV_DISABLED;
153 return ret;
154 }
155
156 return 0;
79} 157}
80EXPORT_SYMBOL_GPL(mei_device_init); 158EXPORT_SYMBOL_GPL(mei_reset);
81 159
82/** 160/**
83 * mei_start - initializes host and fw to start work. 161 * mei_start - initializes host and fw to start work.
@@ -90,14 +168,21 @@ int mei_start(struct mei_device *dev)
90{ 168{
91 mutex_lock(&dev->device_lock); 169 mutex_lock(&dev->device_lock);
92 170
93 /* acknowledge interrupt and stop interupts */ 171 /* acknowledge interrupt and stop interrupts */
94 mei_clear_interrupts(dev); 172 mei_clear_interrupts(dev);
95 173
96 mei_hw_config(dev); 174 mei_hw_config(dev);
97 175
98 dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); 176 dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n");
99 177
100 mei_reset(dev, 1); 178 dev->dev_state = MEI_DEV_INITIALIZING;
179 dev->reset_count = 0;
180 mei_reset(dev);
181
182 if (dev->dev_state == MEI_DEV_DISABLED) {
183 dev_err(&dev->pdev->dev, "reset failed");
184 goto err;
185 }
101 186
102 if (mei_hbm_start_wait(dev)) { 187 if (mei_hbm_start_wait(dev)) {
103 dev_err(&dev->pdev->dev, "HBM haven't started"); 188 dev_err(&dev->pdev->dev, "HBM haven't started");
@@ -132,101 +217,64 @@ err:
132EXPORT_SYMBOL_GPL(mei_start); 217EXPORT_SYMBOL_GPL(mei_start);
133 218
134/** 219/**
135 * mei_reset - resets host and fw. 220 * mei_restart - restart device after suspend
136 * 221 *
137 * @dev: the device structure 222 * @dev: the device structure
138 * @interrupts_enabled: if interrupt should be enabled after reset. 223 *
224 * returns 0 on success or -ENODEV if the restart hasn't succeeded
139 */ 225 */
140void mei_reset(struct mei_device *dev, int interrupts_enabled) 226int mei_restart(struct mei_device *dev)
141{ 227{
142 bool unexpected; 228 int err;
143 int ret;
144
145 unexpected = (dev->dev_state != MEI_DEV_INITIALIZING &&
146 dev->dev_state != MEI_DEV_DISABLED &&
147 dev->dev_state != MEI_DEV_POWER_DOWN &&
148 dev->dev_state != MEI_DEV_POWER_UP);
149 229
150 if (unexpected) 230 mutex_lock(&dev->device_lock);
151 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
152 mei_dev_state_str(dev->dev_state));
153
154 ret = mei_hw_reset(dev, interrupts_enabled);
155 if (ret) {
156 dev_err(&dev->pdev->dev, "hw reset failed disabling the device\n");
157 interrupts_enabled = false;
158 dev->dev_state = MEI_DEV_DISABLED;
159 }
160
161 dev->hbm_state = MEI_HBM_IDLE;
162 231
163 if (dev->dev_state != MEI_DEV_INITIALIZING && 232 mei_clear_interrupts(dev);
164 dev->dev_state != MEI_DEV_POWER_UP) {
165 if (dev->dev_state != MEI_DEV_DISABLED &&
166 dev->dev_state != MEI_DEV_POWER_DOWN)
167 dev->dev_state = MEI_DEV_RESETTING;
168 233
169 /* remove all waiting requests */ 234 dev->dev_state = MEI_DEV_POWER_UP;
170 mei_cl_all_write_clear(dev); 235 dev->reset_count = 0;
171 236
172 mei_cl_all_disconnect(dev); 237 err = mei_reset(dev);
173 238
174 /* wake up all readings so they can be interrupted */ 239 mutex_unlock(&dev->device_lock);
175 mei_cl_all_wakeup(dev);
176
177 /* remove entry if already in list */
178 dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
179 mei_cl_unlink(&dev->wd_cl);
180 mei_cl_unlink(&dev->iamthif_cl);
181 mei_amthif_reset_params(dev);
182 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
183 }
184 240
185 /* we're already in reset, cancel the init timer */ 241 if (err || dev->dev_state == MEI_DEV_DISABLED)
186 dev->init_clients_timer = 0; 242 return -ENODEV;
187 243
188 dev->me_clients_num = 0; 244 return 0;
189 dev->rd_msg_hdr = 0; 245}
190 dev->wd_pending = false; 246EXPORT_SYMBOL_GPL(mei_restart);
191 247
192 if (!interrupts_enabled) {
193 dev_dbg(&dev->pdev->dev, "intr not enabled end of reset\n");
194 return;
195 }
196 248
197 ret = mei_hw_start(dev); 249static void mei_reset_work(struct work_struct *work)
198 if (ret) { 250{
199 dev_err(&dev->pdev->dev, "hw_start failed disabling the device\n"); 251 struct mei_device *dev =
200 dev->dev_state = MEI_DEV_DISABLED; 252 container_of(work, struct mei_device, reset_work);
201 return;
202 }
203 253
204 dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); 254 mutex_lock(&dev->device_lock);
205 /* link is established * start sending messages. */
206 255
207 dev->dev_state = MEI_DEV_INIT_CLIENTS; 256 mei_reset(dev);
208 257
209 mei_hbm_start_req(dev); 258 mutex_unlock(&dev->device_lock);
210 259
260 if (dev->dev_state == MEI_DEV_DISABLED)
261 dev_err(&dev->pdev->dev, "reset failed");
211} 262}
212EXPORT_SYMBOL_GPL(mei_reset);
213 263
214void mei_stop(struct mei_device *dev) 264void mei_stop(struct mei_device *dev)
215{ 265{
216 dev_dbg(&dev->pdev->dev, "stopping the device.\n"); 266 dev_dbg(&dev->pdev->dev, "stopping the device.\n");
217 267
218 flush_scheduled_work(); 268 mei_cancel_work(dev);
219 269
220 mutex_lock(&dev->device_lock); 270 mei_nfc_host_exit(dev);
221 271
222 cancel_delayed_work(&dev->timer_work); 272 mutex_lock(&dev->device_lock);
223 273
224 mei_wd_stop(dev); 274 mei_wd_stop(dev);
225 275
226 mei_nfc_host_exit();
227
228 dev->dev_state = MEI_DEV_POWER_DOWN; 276 dev->dev_state = MEI_DEV_POWER_DOWN;
229 mei_reset(dev, 0); 277 mei_reset(dev);
230 278
231 mutex_unlock(&dev->device_lock); 279 mutex_unlock(&dev->device_lock);
232 280
@@ -236,3 +284,41 @@ EXPORT_SYMBOL_GPL(mei_stop);
236 284
237 285
238 286
287void mei_device_init(struct mei_device *dev)
288{
289 /* setup our list array */
290 INIT_LIST_HEAD(&dev->file_list);
291 INIT_LIST_HEAD(&dev->device_list);
292 mutex_init(&dev->device_lock);
293 init_waitqueue_head(&dev->wait_hw_ready);
294 init_waitqueue_head(&dev->wait_recvd_msg);
295 init_waitqueue_head(&dev->wait_stop_wd);
296 dev->dev_state = MEI_DEV_INITIALIZING;
297 dev->reset_count = 0;
298
299 mei_io_list_init(&dev->read_list);
300 mei_io_list_init(&dev->write_list);
301 mei_io_list_init(&dev->write_waiting_list);
302 mei_io_list_init(&dev->ctrl_wr_list);
303 mei_io_list_init(&dev->ctrl_rd_list);
304
305 INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
306 INIT_WORK(&dev->init_work, mei_host_client_init);
307 INIT_WORK(&dev->reset_work, mei_reset_work);
308
309 INIT_LIST_HEAD(&dev->wd_cl.link);
310 INIT_LIST_HEAD(&dev->iamthif_cl.link);
311 mei_io_list_init(&dev->amthif_cmd_list);
312 mei_io_list_init(&dev->amthif_rd_complete_list);
313
314 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
315 dev->open_handle_count = 0;
316
317 /*
318 * Reserving the first client ID
319 * 0: Reserved for MEI Bus Message communications
320 */
321 bitmap_set(dev->host_clients_map, 0, 1);
322}
323EXPORT_SYMBOL_GPL(mei_device_init);
324
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 7a95c07e59a6..f0fbb5179f80 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -31,7 +31,7 @@
31 31
32 32
33/** 33/**
34 * mei_irq_compl_handler - dispatch complete handelers 34 * mei_irq_compl_handler - dispatch complete handlers
35 * for the completed callbacks 35 * for the completed callbacks
36 * 36 *
37 * @dev - mei device 37 * @dev - mei device
@@ -301,13 +301,11 @@ int mei_irq_read_handler(struct mei_device *dev,
301 struct mei_cl_cb *cmpl_list, s32 *slots) 301 struct mei_cl_cb *cmpl_list, s32 *slots)
302{ 302{
303 struct mei_msg_hdr *mei_hdr; 303 struct mei_msg_hdr *mei_hdr;
304 struct mei_cl *cl_pos = NULL; 304 struct mei_cl *cl;
305 struct mei_cl *cl_next = NULL; 305 int ret;
306 int ret = 0;
307 306
308 if (!dev->rd_msg_hdr) { 307 if (!dev->rd_msg_hdr) {
309 dev->rd_msg_hdr = mei_read_hdr(dev); 308 dev->rd_msg_hdr = mei_read_hdr(dev);
310 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
311 (*slots)--; 309 (*slots)--;
312 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 310 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
313 } 311 }
@@ -315,61 +313,67 @@ int mei_irq_read_handler(struct mei_device *dev,
315 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); 313 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
316 314
317 if (mei_hdr->reserved || !dev->rd_msg_hdr) { 315 if (mei_hdr->reserved || !dev->rd_msg_hdr) {
318 dev_dbg(&dev->pdev->dev, "corrupted message header.\n"); 316 dev_err(&dev->pdev->dev, "corrupted message header 0x%08X\n",
317 dev->rd_msg_hdr);
319 ret = -EBADMSG; 318 ret = -EBADMSG;
320 goto end; 319 goto end;
321 } 320 }
322 321
323 if (mei_hdr->host_addr || mei_hdr->me_addr) { 322 if (mei_slots2data(*slots) < mei_hdr->length) {
324 list_for_each_entry_safe(cl_pos, cl_next, 323 dev_err(&dev->pdev->dev, "less data available than length=%08x.\n",
325 &dev->file_list, link) {
326 dev_dbg(&dev->pdev->dev,
327 "list_for_each_entry_safe read host"
328 " client = %d, ME client = %d\n",
329 cl_pos->host_client_id,
330 cl_pos->me_client_id);
331 if (mei_cl_hbm_equal(cl_pos, mei_hdr))
332 break;
333 }
334
335 if (&cl_pos->link == &dev->file_list) {
336 dev_dbg(&dev->pdev->dev, "corrupted message header\n");
337 ret = -EBADMSG;
338 goto end;
339 }
340 }
341 if (((*slots) * sizeof(u32)) < mei_hdr->length) {
342 dev_err(&dev->pdev->dev,
343 "we can't read the message slots =%08x.\n",
344 *slots); 324 *slots);
345 /* we can't read the message */ 325 /* we can't read the message */
346 ret = -ERANGE; 326 ret = -ERANGE;
347 goto end; 327 goto end;
348 } 328 }
349 329
350 /* decide where to read the message too */ 330 /* HBM message */
351 if (!mei_hdr->host_addr) { 331 if (mei_hdr->host_addr == 0 && mei_hdr->me_addr == 0) {
352 dev_dbg(&dev->pdev->dev, "call mei_hbm_dispatch.\n"); 332 ret = mei_hbm_dispatch(dev, mei_hdr);
353 mei_hbm_dispatch(dev, mei_hdr); 333 if (ret) {
354 dev_dbg(&dev->pdev->dev, "end mei_hbm_dispatch.\n"); 334 dev_dbg(&dev->pdev->dev, "mei_hbm_dispatch failed ret = %d\n",
355 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && 335 ret);
356 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && 336 goto end;
357 (dev->iamthif_state == MEI_IAMTHIF_READING)) { 337 }
338 goto reset_slots;
339 }
340
341 /* find recipient cl */
342 list_for_each_entry(cl, &dev->file_list, link) {
343 if (mei_cl_hbm_equal(cl, mei_hdr)) {
344 cl_dbg(dev, cl, "got a message\n");
345 break;
346 }
347 }
348
349 /* if no recipient cl was found we assume corrupted header */
350 if (&cl->link == &dev->file_list) {
351 dev_err(&dev->pdev->dev, "no destination client found 0x%08X\n",
352 dev->rd_msg_hdr);
353 ret = -EBADMSG;
354 goto end;
355 }
358 356
359 dev_dbg(&dev->pdev->dev, "call mei_amthif_irq_read_msg.\n"); 357 if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
360 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); 358 MEI_FILE_CONNECTED == dev->iamthif_cl.state &&
359 dev->iamthif_state == MEI_IAMTHIF_READING) {
361 360
362 ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list); 361 ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list);
363 if (ret) 362 if (ret) {
363 dev_err(&dev->pdev->dev, "mei_amthif_irq_read_msg failed = %d\n",
364 ret);
364 goto end; 365 goto end;
366 }
365 } else { 367 } else {
366 dev_dbg(&dev->pdev->dev, "call mei_cl_irq_read_msg.\n");
367 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
368 ret = mei_cl_irq_read_msg(dev, mei_hdr, cmpl_list); 368 ret = mei_cl_irq_read_msg(dev, mei_hdr, cmpl_list);
369 if (ret) 369 if (ret) {
370 dev_err(&dev->pdev->dev, "mei_cl_irq_read_msg failed = %d\n",
371 ret);
370 goto end; 372 goto end;
373 }
371 } 374 }
372 375
376reset_slots:
373 /* reset the number of slots and header */ 377 /* reset the number of slots and header */
374 *slots = mei_count_full_read_slots(dev); 378 *slots = mei_count_full_read_slots(dev);
375 dev->rd_msg_hdr = 0; 379 dev->rd_msg_hdr = 0;
@@ -533,7 +537,6 @@ EXPORT_SYMBOL_GPL(mei_irq_write_handler);
533 * 537 *
534 * @work: pointer to the work_struct structure 538 * @work: pointer to the work_struct structure
535 * 539 *
536 * NOTE: This function is called by timer interrupt work
537 */ 540 */
538void mei_timer(struct work_struct *work) 541void mei_timer(struct work_struct *work)
539{ 542{
@@ -548,24 +551,30 @@ void mei_timer(struct work_struct *work)
548 551
549 552
550 mutex_lock(&dev->device_lock); 553 mutex_lock(&dev->device_lock);
551 if (dev->dev_state != MEI_DEV_ENABLED) { 554
552 if (dev->dev_state == MEI_DEV_INIT_CLIENTS) { 555 /* Catch interrupt stalls during HBM init handshake */
553 if (dev->init_clients_timer) { 556 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
554 if (--dev->init_clients_timer == 0) { 557 dev->hbm_state != MEI_HBM_IDLE) {
555 dev_err(&dev->pdev->dev, "reset: init clients timeout hbm_state = %d.\n", 558
556 dev->hbm_state); 559 if (dev->init_clients_timer) {
557 mei_reset(dev, 1); 560 if (--dev->init_clients_timer == 0) {
558 } 561 dev_err(&dev->pdev->dev, "timer: init clients timeout hbm_state = %d.\n",
562 dev->hbm_state);
563 mei_reset(dev);
564 goto out;
559 } 565 }
560 } 566 }
561 goto out;
562 } 567 }
568
569 if (dev->dev_state != MEI_DEV_ENABLED)
570 goto out;
571
563 /*** connect/disconnect timeouts ***/ 572 /*** connect/disconnect timeouts ***/
564 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { 573 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
565 if (cl_pos->timer_count) { 574 if (cl_pos->timer_count) {
566 if (--cl_pos->timer_count == 0) { 575 if (--cl_pos->timer_count == 0) {
567 dev_err(&dev->pdev->dev, "reset: connect/disconnect timeout.\n"); 576 dev_err(&dev->pdev->dev, "timer: connect/disconnect timeout.\n");
568 mei_reset(dev, 1); 577 mei_reset(dev);
569 goto out; 578 goto out;
570 } 579 }
571 } 580 }
@@ -573,8 +582,8 @@ void mei_timer(struct work_struct *work)
573 582
574 if (dev->iamthif_stall_timer) { 583 if (dev->iamthif_stall_timer) {
575 if (--dev->iamthif_stall_timer == 0) { 584 if (--dev->iamthif_stall_timer == 0) {
576 dev_err(&dev->pdev->dev, "reset: amthif hanged.\n"); 585 dev_err(&dev->pdev->dev, "timer: amthif hanged.\n");
577 mei_reset(dev, 1); 586 mei_reset(dev);
578 dev->iamthif_msg_buf_size = 0; 587 dev->iamthif_msg_buf_size = 0;
579 dev->iamthif_msg_buf_index = 0; 588 dev->iamthif_msg_buf_index = 0;
580 dev->iamthif_canceled = false; 589 dev->iamthif_canceled = false;
@@ -627,7 +636,8 @@ void mei_timer(struct work_struct *work)
627 } 636 }
628 } 637 }
629out: 638out:
630 schedule_delayed_work(&dev->timer_work, 2 * HZ); 639 if (dev->dev_state != MEI_DEV_DISABLED)
640 schedule_delayed_work(&dev->timer_work, 2 * HZ);
631 mutex_unlock(&dev->device_lock); 641 mutex_unlock(&dev->device_lock);
632} 642}
633 643
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 9661a812f550..5424f8ff3f7f 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -48,7 +48,7 @@
48 * 48 *
49 * @inode: pointer to inode structure 49 * @inode: pointer to inode structure
50 * @file: pointer to file structure 50 * @file: pointer to file structure
51 e 51 *
52 * returns 0 on success, <0 on error 52 * returns 0 on success, <0 on error
53 */ 53 */
54static int mei_open(struct inode *inode, struct file *file) 54static int mei_open(struct inode *inode, struct file *file)
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 406f68e05b4e..f7de95b4cdd9 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -61,11 +61,16 @@ extern const uuid_le mei_wd_guid;
61#define MEI_CLIENTS_MAX 256 61#define MEI_CLIENTS_MAX 256
62 62
63/* 63/*
64 * maximum number of consecutive resets
65 */
66#define MEI_MAX_CONSEC_RESET 3
67
68/*
64 * Number of File descriptors/handles 69 * Number of File descriptors/handles
65 * that can be opened to the driver. 70 * that can be opened to the driver.
66 * 71 *
67 * Limit to 255: 256 Total Clients 72 * Limit to 255: 256 Total Clients
68 * minus internal client for MEI Bus Messags 73 * minus internal client for MEI Bus Messages
69 */ 74 */
70#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1) 75#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1)
71 76
@@ -178,9 +183,10 @@ struct mei_cl_cb {
178 unsigned long buf_idx; 183 unsigned long buf_idx;
179 unsigned long read_time; 184 unsigned long read_time;
180 struct file *file_object; 185 struct file *file_object;
186 u32 internal:1;
181}; 187};
182 188
183/* MEI client instance carried as file->pirvate_data*/ 189/* MEI client instance carried as file->private_data*/
184struct mei_cl { 190struct mei_cl {
185 struct list_head link; 191 struct list_head link;
186 struct mei_device *dev; 192 struct mei_device *dev;
@@ -326,6 +332,7 @@ struct mei_cl_device {
326/** 332/**
327 * struct mei_device - MEI private device struct 333 * struct mei_device - MEI private device struct
328 334
335 * @reset_count - limits the number of consecutive resets
329 * @hbm_state - state of host bus message protocol 336 * @hbm_state - state of host bus message protocol
330 * @mem_addr - mem mapped base register address 337 * @mem_addr - mem mapped base register address
331 338
@@ -369,6 +376,7 @@ struct mei_device {
369 /* 376 /*
370 * mei device states 377 * mei device states
371 */ 378 */
379 unsigned long reset_count;
372 enum mei_dev_state dev_state; 380 enum mei_dev_state dev_state;
373 enum mei_hbm_state hbm_state; 381 enum mei_hbm_state hbm_state;
374 u16 init_clients_timer; 382 u16 init_clients_timer;
@@ -427,6 +435,7 @@ struct mei_device {
427 bool iamthif_canceled; 435 bool iamthif_canceled;
428 436
429 struct work_struct init_work; 437 struct work_struct init_work;
438 struct work_struct reset_work;
430 439
431 /* List of bus devices */ 440 /* List of bus devices */
432 struct list_head device_list; 441 struct list_head device_list;
@@ -456,13 +465,25 @@ static inline u32 mei_data2slots(size_t length)
456 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4); 465 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
457} 466}
458 467
468/**
469 * mei_slots2data- get data in slots - bytes from slots
470 * @slots - number of available slots
471 * returns - number of bytes in slots
472 */
473static inline u32 mei_slots2data(int slots)
474{
475 return slots * 4;
476}
477
459/* 478/*
460 * mei init function prototypes 479 * mei init function prototypes
461 */ 480 */
462void mei_device_init(struct mei_device *dev); 481void mei_device_init(struct mei_device *dev);
463void mei_reset(struct mei_device *dev, int interrupts); 482int mei_reset(struct mei_device *dev);
464int mei_start(struct mei_device *dev); 483int mei_start(struct mei_device *dev);
484int mei_restart(struct mei_device *dev);
465void mei_stop(struct mei_device *dev); 485void mei_stop(struct mei_device *dev);
486void mei_cancel_work(struct mei_device *dev);
466 487
467/* 488/*
468 * MEI interrupt functions prototype 489 * MEI interrupt functions prototype
@@ -510,7 +531,7 @@ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
510 * NFC functions 531 * NFC functions
511 */ 532 */
512int mei_nfc_host_init(struct mei_device *dev); 533int mei_nfc_host_init(struct mei_device *dev);
513void mei_nfc_host_exit(void); 534void mei_nfc_host_exit(struct mei_device *dev);
514 535
515/* 536/*
516 * NFC Client UUID 537 * NFC Client UUID
@@ -626,9 +647,9 @@ static inline void mei_dbgfs_deregister(struct mei_device *dev) {}
626int mei_register(struct mei_device *dev); 647int mei_register(struct mei_device *dev);
627void mei_deregister(struct mei_device *dev); 648void mei_deregister(struct mei_device *dev);
628 649
629#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d comp=%1d" 650#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d internal=%1d comp=%1d"
630#define MEI_HDR_PRM(hdr) \ 651#define MEI_HDR_PRM(hdr) \
631 (hdr)->host_addr, (hdr)->me_addr, \ 652 (hdr)->host_addr, (hdr)->me_addr, \
632 (hdr)->length, (hdr)->msg_complete 653 (hdr)->length, (hdr)->internal, (hdr)->msg_complete
633 654
634#endif 655#endif
diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c
index 994ca4aff1a3..a58320c0c049 100644
--- a/drivers/misc/mei/nfc.c
+++ b/drivers/misc/mei/nfc.c
@@ -92,7 +92,7 @@ struct mei_nfc_hci_hdr {
92 * @cl: NFC host client 92 * @cl: NFC host client
93 * @cl_info: NFC info host client 93 * @cl_info: NFC info host client
94 * @init_work: perform connection to the info client 94 * @init_work: perform connection to the info client
95 * @fw_ivn: NFC Intervace Version Number 95 * @fw_ivn: NFC Interface Version Number
96 * @vendor_id: NFC manufacturer ID 96 * @vendor_id: NFC manufacturer ID
97 * @radio_type: NFC radio type 97 * @radio_type: NFC radio type
98 */ 98 */
@@ -163,7 +163,7 @@ static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev)
163 return 0; 163 return 0;
164 164
165 default: 165 default:
166 dev_err(&dev->pdev->dev, "Unknow radio type 0x%x\n", 166 dev_err(&dev->pdev->dev, "Unknown radio type 0x%x\n",
167 ndev->radio_type); 167 ndev->radio_type);
168 168
169 return -EINVAL; 169 return -EINVAL;
@@ -175,14 +175,14 @@ static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev)
175 ndev->bus_name = "pn544"; 175 ndev->bus_name = "pn544";
176 return 0; 176 return 0;
177 default: 177 default:
178 dev_err(&dev->pdev->dev, "Unknow radio type 0x%x\n", 178 dev_err(&dev->pdev->dev, "Unknown radio type 0x%x\n",
179 ndev->radio_type); 179 ndev->radio_type);
180 180
181 return -EINVAL; 181 return -EINVAL;
182 } 182 }
183 183
184 default: 184 default:
185 dev_err(&dev->pdev->dev, "Unknow vendor ID 0x%x\n", 185 dev_err(&dev->pdev->dev, "Unknown vendor ID 0x%x\n",
186 ndev->vendor_id); 186 ndev->vendor_id);
187 187
188 return -EINVAL; 188 return -EINVAL;
@@ -428,7 +428,7 @@ static void mei_nfc_init(struct work_struct *work)
428 mutex_unlock(&dev->device_lock); 428 mutex_unlock(&dev->device_lock);
429 429
430 if (mei_nfc_if_version(ndev) < 0) { 430 if (mei_nfc_if_version(ndev) < 0) {
431 dev_err(&dev->pdev->dev, "Could not get the NFC interfave version"); 431 dev_err(&dev->pdev->dev, "Could not get the NFC interface version");
432 432
433 goto err; 433 goto err;
434 } 434 }
@@ -469,7 +469,9 @@ static void mei_nfc_init(struct work_struct *work)
469 return; 469 return;
470 470
471err: 471err:
472 mutex_lock(&dev->device_lock);
472 mei_nfc_free(ndev); 473 mei_nfc_free(ndev);
474 mutex_unlock(&dev->device_lock);
473 475
474 return; 476 return;
475} 477}
@@ -481,7 +483,7 @@ int mei_nfc_host_init(struct mei_device *dev)
481 struct mei_cl *cl_info, *cl = NULL; 483 struct mei_cl *cl_info, *cl = NULL;
482 int i, ret; 484 int i, ret;
483 485
484 /* already initialzed */ 486 /* already initialized */
485 if (ndev->cl_info) 487 if (ndev->cl_info)
486 return 0; 488 return 0;
487 489
@@ -547,12 +549,16 @@ err:
547 return ret; 549 return ret;
548} 550}
549 551
550void mei_nfc_host_exit(void) 552void mei_nfc_host_exit(struct mei_device *dev)
551{ 553{
552 struct mei_nfc_dev *ndev = &nfc_dev; 554 struct mei_nfc_dev *ndev = &nfc_dev;
553 555
556 cancel_work_sync(&ndev->init_work);
557
558 mutex_lock(&dev->device_lock);
554 if (ndev->cl && ndev->cl->device) 559 if (ndev->cl && ndev->cl->device)
555 mei_cl_remove_device(ndev->cl->device); 560 mei_cl_remove_device(ndev->cl->device);
556 561
557 mei_nfc_free(ndev); 562 mei_nfc_free(ndev);
563 mutex_unlock(&dev->device_lock);
558} 564}
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index 2cab3c0a6805..ddadd08956f4 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -144,6 +144,21 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
144 dev_err(&pdev->dev, "failed to get pci regions.\n"); 144 dev_err(&pdev->dev, "failed to get pci regions.\n");
145 goto disable_device; 145 goto disable_device;
146 } 146 }
147
148 if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) ||
149 dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
150
151 err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
152 if (err)
153 err = dma_set_coherent_mask(&pdev->dev,
154 DMA_BIT_MASK(32));
155 }
156 if (err) {
157 dev_err(&pdev->dev, "No usable DMA configuration, aborting\n");
158 goto release_regions;
159 }
160
161
147 /* allocates and initializes the mei dev structure */ 162 /* allocates and initializes the mei dev structure */
148 dev = mei_me_dev_init(pdev); 163 dev = mei_me_dev_init(pdev);
149 if (!dev) { 164 if (!dev) {
@@ -197,8 +212,8 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
197 return 0; 212 return 0;
198 213
199release_irq: 214release_irq:
215 mei_cancel_work(dev);
200 mei_disable_interrupts(dev); 216 mei_disable_interrupts(dev);
201 flush_scheduled_work();
202 free_irq(pdev->irq, dev); 217 free_irq(pdev->irq, dev);
203disable_msi: 218disable_msi:
204 pci_disable_msi(pdev); 219 pci_disable_msi(pdev);
@@ -306,16 +321,14 @@ static int mei_me_pci_resume(struct device *device)
306 return err; 321 return err;
307 } 322 }
308 323
309 mutex_lock(&dev->device_lock); 324 err = mei_restart(dev);
310 dev->dev_state = MEI_DEV_POWER_UP; 325 if (err)
311 mei_clear_interrupts(dev); 326 return err;
312 mei_reset(dev, 1);
313 mutex_unlock(&dev->device_lock);
314 327
315 /* Start timer if stopped in suspend */ 328 /* Start timer if stopped in suspend */
316 schedule_delayed_work(&dev->timer_work, HZ); 329 schedule_delayed_work(&dev->timer_work, HZ);
317 330
318 return err; 331 return 0;
319} 332}
320static SIMPLE_DEV_PM_OPS(mei_me_pm_ops, mei_me_pci_suspend, mei_me_pci_resume); 333static SIMPLE_DEV_PM_OPS(mei_me_pm_ops, mei_me_pci_suspend, mei_me_pci_resume);
321#define MEI_ME_PM_OPS (&mei_me_pm_ops) 334#define MEI_ME_PM_OPS (&mei_me_pm_ops)
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 9e354216c163..f70945ed96f6 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -115,6 +115,7 @@ int mei_wd_send(struct mei_device *dev)
115 hdr.me_addr = dev->wd_cl.me_client_id; 115 hdr.me_addr = dev->wd_cl.me_client_id;
116 hdr.msg_complete = 1; 116 hdr.msg_complete = 1;
117 hdr.reserved = 0; 117 hdr.reserved = 0;
118 hdr.internal = 0;
118 119
119 if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE)) 120 if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE))
120 hdr.length = MEI_WD_START_MSG_SIZE; 121 hdr.length = MEI_WD_START_MSG_SIZE;