aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/mei/hbm.c53
-rw-r--r--drivers/misc/mei/hbm.h25
-rw-r--r--drivers/misc/mei/hw-me.c12
-rw-r--r--drivers/misc/mei/init.c22
-rw-r--r--drivers/misc/mei/interrupt.c4
-rw-r--r--drivers/misc/mei/main.c2
-rw-r--r--drivers/misc/mei/mei_dev.h13
7 files changed, 72 insertions, 59 deletions
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index de7f5ba3194f..4de80d9b7c45 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -123,12 +123,33 @@ static bool is_treat_specially_client(struct mei_cl *cl,
123 return false; 123 return false;
124} 124}
125 125
126int mei_hbm_start_wait(struct mei_device *dev)
127{
128 int ret;
129 if (dev->hbm_state > MEI_HBM_START)
130 return 0;
131
132 mutex_unlock(&dev->device_lock);
133 ret = wait_event_interruptible_timeout(dev->wait_recvd_msg,
134 dev->hbm_state == MEI_HBM_IDLE ||
135 dev->hbm_state > MEI_HBM_START,
136 mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT));
137 mutex_lock(&dev->device_lock);
138
139 if (ret <= 0 && (dev->hbm_state <= MEI_HBM_START)) {
140 dev->hbm_state = MEI_HBM_IDLE;
141 dev_err(&dev->pdev->dev, "wating for mei start failed\n");
142 return -ETIMEDOUT;
143 }
144 return 0;
145}
146
126/** 147/**
127 * mei_hbm_start_req - sends start request message. 148 * mei_hbm_start_req - sends start request message.
128 * 149 *
129 * @dev: the device structure 150 * @dev: the device structure
130 */ 151 */
131void mei_hbm_start_req(struct mei_device *dev) 152int mei_hbm_start_req(struct mei_device *dev)
132{ 153{
133 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 154 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
134 struct hbm_host_version_request *start_req; 155 struct hbm_host_version_request *start_req;
@@ -143,18 +164,19 @@ void mei_hbm_start_req(struct mei_device *dev)
143 start_req->host_version.major_version = HBM_MAJOR_VERSION; 164 start_req->host_version.major_version = HBM_MAJOR_VERSION;
144 start_req->host_version.minor_version = HBM_MINOR_VERSION; 165 start_req->host_version.minor_version = HBM_MINOR_VERSION;
145 166
146 dev->recvd_msg = false; 167 dev->hbm_state = MEI_HBM_IDLE;
147 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { 168 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
148 dev_err(&dev->pdev->dev, "version message writet failed\n"); 169 dev_err(&dev->pdev->dev, "version message writet failed\n");
149 dev->dev_state = MEI_DEV_RESETING; 170 dev->dev_state = MEI_DEV_RESETING;
150 mei_reset(dev, 1); 171 mei_reset(dev, 1);
172 return -ENODEV;
151 } 173 }
152 dev->init_clients_state = MEI_START_MESSAGE; 174 dev->hbm_state = MEI_HBM_START;
153 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 175 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
154 return ; 176 return 0;
155} 177}
156 178
157/** 179/*
158 * mei_hbm_enum_clients_req - sends enumeration client request message. 180 * mei_hbm_enum_clients_req - sends enumeration client request message.
159 * 181 *
160 * @dev: the device structure 182 * @dev: the device structure
@@ -178,7 +200,7 @@ static void mei_hbm_enum_clients_req(struct mei_device *dev)
178 dev_err(&dev->pdev->dev, "enumeration request write failed.\n"); 200 dev_err(&dev->pdev->dev, "enumeration request write failed.\n");
179 mei_reset(dev, 1); 201 mei_reset(dev, 1);
180 } 202 }
181 dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE; 203 dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
182 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 204 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
183 return; 205 return;
184} 206}
@@ -208,6 +230,7 @@ static int mei_hbm_prop_req(struct mei_device *dev)
208 230
209 /* We got all client properties */ 231 /* We got all client properties */
210 if (next_client_index == MEI_CLIENTS_MAX) { 232 if (next_client_index == MEI_CLIENTS_MAX) {
233 dev->hbm_state = MEI_HBM_STARTED;
211 schedule_work(&dev->init_work); 234 schedule_work(&dev->init_work);
212 235
213 return 0; 236 return 0;
@@ -542,27 +565,28 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
542 dev->version = version_res->me_max_version; 565 dev->version = version_res->me_max_version;
543 dev_dbg(&dev->pdev->dev, "version mismatch.\n"); 566 dev_dbg(&dev->pdev->dev, "version mismatch.\n");
544 567
568 dev->hbm_state = MEI_HBM_STOP;
545 mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr, 569 mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr,
546 dev->wr_msg.data); 570 dev->wr_msg.data);
547 mei_write_message(dev, &dev->wr_msg.hdr, 571 mei_write_message(dev, &dev->wr_msg.hdr,
548 dev->wr_msg.data); 572 dev->wr_msg.data);
573
549 return; 574 return;
550 } 575 }
551 576
552 dev->version.major_version = HBM_MAJOR_VERSION; 577 dev->version.major_version = HBM_MAJOR_VERSION;
553 dev->version.minor_version = HBM_MINOR_VERSION; 578 dev->version.minor_version = HBM_MINOR_VERSION;
554 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 579 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
555 dev->init_clients_state == MEI_START_MESSAGE) { 580 dev->hbm_state == MEI_HBM_START) {
556 dev->init_clients_timer = 0; 581 dev->init_clients_timer = 0;
557 mei_hbm_enum_clients_req(dev); 582 mei_hbm_enum_clients_req(dev);
558 } else { 583 } else {
559 dev->recvd_msg = false;
560 dev_err(&dev->pdev->dev, "reset: wrong host start response\n"); 584 dev_err(&dev->pdev->dev, "reset: wrong host start response\n");
561 mei_reset(dev, 1); 585 mei_reset(dev, 1);
562 return; 586 return;
563 } 587 }
564 588
565 dev->recvd_msg = true; 589 wake_up_interruptible(&dev->wait_recvd_msg);
566 dev_dbg(&dev->pdev->dev, "host start response message received.\n"); 590 dev_dbg(&dev->pdev->dev, "host start response message received.\n");
567 break; 591 break;
568 592
@@ -603,7 +627,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
603 } 627 }
604 628
605 if (dev->dev_state != MEI_DEV_INIT_CLIENTS || 629 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
606 dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) { 630 dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
607 dev_err(&dev->pdev->dev, "reset: unexpected properties response\n"); 631 dev_err(&dev->pdev->dev, "reset: unexpected properties response\n");
608 mei_reset(dev, 1); 632 mei_reset(dev, 1);
609 633
@@ -623,13 +647,12 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
623 enum_res = (struct hbm_host_enum_response *) mei_msg; 647 enum_res = (struct hbm_host_enum_response *) mei_msg;
624 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); 648 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
625 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 649 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
626 dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) { 650 dev->hbm_state == MEI_HBM_ENUM_CLIENTS) {
627 dev->init_clients_timer = 0; 651 dev->init_clients_timer = 0;
628 dev->me_client_presentation_num = 0; 652 dev->me_client_presentation_num = 0;
629 dev->me_client_index = 0; 653 dev->me_client_index = 0;
630 mei_hbm_me_cl_allocate(dev); 654 mei_hbm_me_cl_allocate(dev);
631 dev->init_clients_state = 655 dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES;
632 MEI_CLIENT_PROPERTIES_MESSAGE;
633 656
634 /* first property reqeust */ 657 /* first property reqeust */
635 mei_hbm_prop_req(dev); 658 mei_hbm_prop_req(dev);
@@ -641,6 +664,9 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
641 break; 664 break;
642 665
643 case HOST_STOP_RES_CMD: 666 case HOST_STOP_RES_CMD:
667
668 if (dev->hbm_state != MEI_HBM_STOP)
669 dev_err(&dev->pdev->dev, "unexpected stop response hbm.\n");
644 dev->dev_state = MEI_DEV_DISABLED; 670 dev->dev_state = MEI_DEV_DISABLED;
645 dev_info(&dev->pdev->dev, "reset: FW stop response.\n"); 671 dev_info(&dev->pdev->dev, "reset: FW stop response.\n");
646 mei_reset(dev, 1); 672 mei_reset(dev, 1);
@@ -654,6 +680,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
654 680
655 case ME_STOP_REQ_CMD: 681 case ME_STOP_REQ_CMD:
656 682
683 dev->hbm_state = MEI_HBM_STOP;
657 mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr, 684 mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr,
658 dev->wr_ext_msg.data); 685 dev->wr_ext_msg.data);
659 break; 686 break;
diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h
index b552afbaf85c..e80dc24ef3e2 100644
--- a/drivers/misc/mei/hbm.h
+++ b/drivers/misc/mei/hbm.h
@@ -17,6 +17,27 @@
17#ifndef _MEI_HBM_H_ 17#ifndef _MEI_HBM_H_
18#define _MEI_HBM_H_ 18#define _MEI_HBM_H_
19 19
20struct mei_device;
21struct mei_msg_hdr;
22struct mei_cl;
23
24/**
25 * enum mei_hbm_state - host bus message protocol state
26 *
27 * @MEI_HBM_IDLE : protocol not started
28 * @MEI_HBM_START : start request message was sent
29 * @MEI_HBM_ENUM_CLIENTS : enumeration request was sent
30 * @MEI_HBM_CLIENT_PROPERTIES : acquiring clients properties
31 */
32enum mei_hbm_state {
33 MEI_HBM_IDLE = 0,
34 MEI_HBM_START,
35 MEI_HBM_ENUM_CLIENTS,
36 MEI_HBM_CLIENT_PROPERTIES,
37 MEI_HBM_STARTED,
38 MEI_HBM_STOP,
39};
40
20void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr); 41void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr);
21 42
22static 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)
@@ -28,8 +49,8 @@ static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length)
28 hdr->reserved = 0; 49 hdr->reserved = 0;
29} 50}
30 51
31void mei_hbm_start_req(struct mei_device *dev); 52int mei_hbm_start_req(struct mei_device *dev);
32 53int mei_hbm_start_wait(struct mei_device *dev);
33int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl); 54int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl);
34int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl); 55int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl);
35int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl); 56int mei_hbm_cl_connect_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 5ad53ebf57b9..3d6dfa35b1d7 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -468,8 +468,6 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
468 struct mei_cl_cb complete_list; 468 struct mei_cl_cb complete_list;
469 s32 slots; 469 s32 slots;
470 int rets; 470 int rets;
471 bool bus_message_received;
472
473 471
474 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); 472 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n");
475 /* initialize our complete list */ 473 /* initialize our complete list */
@@ -525,17 +523,7 @@ end:
525 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); 523 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
526 dev->hbuf_is_ready = mei_hbuf_is_ready(dev); 524 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
527 525
528 bus_message_received = false;
529 if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
530 dev_dbg(&dev->pdev->dev, "received waiting bus message\n");
531 bus_message_received = true;
532 }
533 mutex_unlock(&dev->device_lock); 526 mutex_unlock(&dev->device_lock);
534 if (bus_message_received) {
535 dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n");
536 wake_up_interruptible(&dev->wait_recvd_msg);
537 bus_message_received = false;
538 }
539 527
540 mei_irq_compl_handler(dev, &complete_list); 528 mei_irq_compl_handler(dev, &complete_list);
541 529
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 4e102ad7ebc0..59159e05446c 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -80,8 +80,6 @@ EXPORT_SYMBOL_GPL(mei_device_init);
80 */ 80 */
81int mei_start(struct mei_device *dev) 81int mei_start(struct mei_device *dev)
82{ 82{
83 int ret = 0;
84
85 mutex_lock(&dev->device_lock); 83 mutex_lock(&dev->device_lock);
86 84
87 /* acknowledge interrupt and stop interupts */ 85 /* acknowledge interrupt and stop interupts */
@@ -89,29 +87,15 @@ int mei_start(struct mei_device *dev)
89 87
90 mei_hw_config(dev); 88 mei_hw_config(dev);
91 89
92 dev->recvd_msg = false;
93 dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); 90 dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n");
94 91
95 mei_reset(dev, 1); 92 mei_reset(dev, 1);
96 93
97 /* wait for ME to turn on ME_RDY */ 94 if (mei_hbm_start_wait(dev)) {
98 if (!dev->recvd_msg) { 95 dev_err(&dev->pdev->dev, "HBM haven't started");
99 mutex_unlock(&dev->device_lock);
100 ret = wait_event_interruptible_timeout(dev->wait_recvd_msg,
101 dev->recvd_msg,
102 mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT));
103 mutex_lock(&dev->device_lock);
104 }
105
106 if (ret <= 0 && !dev->recvd_msg) {
107 dev->dev_state = MEI_DEV_DISABLED;
108 dev_dbg(&dev->pdev->dev,
109 "wait_event_interruptible_timeout failed"
110 "on wait for ME to turn on ME_RDY.\n");
111 goto err; 96 goto err;
112 } 97 }
113 98
114
115 if (!mei_host_is_ready(dev)) { 99 if (!mei_host_is_ready(dev)) {
116 dev_err(&dev->pdev->dev, "host is not ready.\n"); 100 dev_err(&dev->pdev->dev, "host is not ready.\n");
117 goto err; 101 goto err;
@@ -128,7 +112,6 @@ int mei_start(struct mei_device *dev)
128 goto err; 112 goto err;
129 } 113 }
130 114
131 dev->recvd_msg = false;
132 dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); 115 dev_dbg(&dev->pdev->dev, "link layer has been established.\n");
133 116
134 mutex_unlock(&dev->device_lock); 117 mutex_unlock(&dev->device_lock);
@@ -158,6 +141,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
158 141
159 mei_hw_reset(dev, interrupts_enabled); 142 mei_hw_reset(dev, interrupts_enabled);
160 143
144 dev->hbm_state = MEI_HBM_IDLE;
161 145
162 if (dev->dev_state != MEI_DEV_INITIALIZING) { 146 if (dev->dev_state != MEI_DEV_INITIALIZING) {
163 if (dev->dev_state != MEI_DEV_DISABLED && 147 if (dev->dev_state != MEI_DEV_DISABLED &&
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 9ff8c61fe457..c1cc462cce0e 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -623,8 +623,8 @@ void mei_timer(struct work_struct *work)
623 if (dev->dev_state == MEI_DEV_INIT_CLIENTS) { 623 if (dev->dev_state == MEI_DEV_INIT_CLIENTS) {
624 if (dev->init_clients_timer) { 624 if (dev->init_clients_timer) {
625 if (--dev->init_clients_timer == 0) { 625 if (--dev->init_clients_timer == 0) {
626 dev_err(&dev->pdev->dev, "reset: init clients timeout ,init clients state = %d.\n", 626 dev_err(&dev->pdev->dev, "reset: init clients timeout hbm_state = %d.\n",
627 dev->init_clients_state); 627 dev->hbm_state);
628 mei_reset(dev, 1); 628 mei_reset(dev, 1);
629 } 629 }
630 } 630 }
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index cb11b36512b5..78b4da5ed96c 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 * 51 e
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 cd5b6d4bbbd4..56dee56ab9cc 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -25,6 +25,7 @@
25 25
26#include "hw.h" 26#include "hw.h"
27#include "hw-me-regs.h" 27#include "hw-me-regs.h"
28#include "hbm.h"
28 29
29/* 30/*
30 * watch dog definition 31 * watch dog definition
@@ -104,13 +105,6 @@ enum mei_dev_state {
104 105
105const char *mei_dev_state_str(int state); 106const char *mei_dev_state_str(int state);
106 107
107/* init clients states*/
108enum mei_init_clients_states {
109 MEI_START_MESSAGE = 0,
110 MEI_ENUM_CLIENTS_MESSAGE,
111 MEI_CLIENT_PROPERTIES_MESSAGE
112};
113
114enum iamthif_states { 108enum iamthif_states {
115 MEI_IAMTHIF_IDLE, 109 MEI_IAMTHIF_IDLE,
116 MEI_IAMTHIF_WRITING, 110 MEI_IAMTHIF_WRITING,
@@ -338,6 +332,7 @@ struct mei_cl_device {
338/** 332/**
339 * struct mei_device - MEI private device struct 333 * struct mei_device - MEI private device struct
340 334
335 * @hbm_state - state of host bus message protocol
341 * @mem_addr - mem mapped base register address 336 * @mem_addr - mem mapped base register address
342 337
343 * @hbuf_depth - depth of hardware host/write buffer is slots 338 * @hbuf_depth - depth of hardware host/write buffer is slots
@@ -370,8 +365,6 @@ struct mei_device {
370 struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */ 365 struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */
371 366
372 bool recvd_hw_ready; 367 bool recvd_hw_ready;
373 bool recvd_msg;
374
375 /* 368 /*
376 * waiting queue for receive message from FW 369 * waiting queue for receive message from FW
377 */ 370 */
@@ -383,7 +376,7 @@ struct mei_device {
383 * mei device states 376 * mei device states
384 */ 377 */
385 enum mei_dev_state dev_state; 378 enum mei_dev_state dev_state;
386 enum mei_init_clients_states init_clients_state; 379 enum mei_hbm_state hbm_state;
387 u16 init_clients_timer; 380 u16 init_clients_timer;
388 381
389 unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ 382 unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */