aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-14 19:43:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-14 19:43:47 -0500
commit6ae840e7cc4be0be3aa40d9f67c35c75cfc67d83 (patch)
tree9c83c87a8670ef678d95f8d6f76a07f24a09a49f /drivers/misc/mei
parente6b5be2be4e30037eb551e0ed09dd97bd00d85d3 (diff)
parent91905b6f4afe51e23a3f58df93e4cdc5e49cf40c (diff)
Merge tag 'char-misc-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here's the big char/misc driver update for 3.19-rc1 Lots of little things all over the place in different drivers, and a new subsystem, "coresight" has been added. Full details are in the shortlog" * tag 'char-misc-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (73 commits) parport: parport_pc, do not remove parent devices early spmi: Remove shutdown/suspend/resume kernel-doc carma-fpga-program: drop videobuf dependency carma-fpga: drop videobuf dependency carma-fpga-program.c: fix compile errors i8k: Fix temperature bug handling in i8k_get_temp() cxl: Name interrupts in /proc/interrupt CXL: Return error to PSL if IRQ demultiplexing fails & print clearer warning coresight-replicator: remove .owner field for driver coresight: fixed comments in coresight.h coresight: fix typo in comment in coresight-priv.h coresight: bindings for coresight drivers coresight: Adding ABI documentation w1: support auto-load of w1_bq27000 module. w1: avoid potential u16 overflow cn: verify msg->len before making callback mei: export fw status registers through sysfs mei: read and print all six FW status registers mei: txe: add cherrytrail device id mei: kill cached host and me csr values ...
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/amthif.c34
-rw-r--r--drivers/misc/mei/bus.c4
-rw-r--r--drivers/misc/mei/client.c2
-rw-r--r--drivers/misc/mei/debugfs.c8
-rw-r--r--drivers/misc/mei/hbm.c23
-rw-r--r--drivers/misc/mei/hbm.h4
-rw-r--r--drivers/misc/mei/hw-me-regs.h12
-rw-r--r--drivers/misc/mei/hw-me.c49
-rw-r--r--drivers/misc/mei/hw-me.h10
-rw-r--r--drivers/misc/mei/hw-txe.c7
-rw-r--r--drivers/misc/mei/init.c38
-rw-r--r--drivers/misc/mei/interrupt.c12
-rw-r--r--drivers/misc/mei/main.c43
-rw-r--r--drivers/misc/mei/mei_dev.h39
-rw-r--r--drivers/misc/mei/nfc.c52
-rw-r--r--drivers/misc/mei/pci-me.c12
-rw-r--r--drivers/misc/mei/pci-txe.c1
-rw-r--r--drivers/misc/mei/wd.c9
18 files changed, 239 insertions, 120 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 6cdce8477f57..79f53941779d 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -262,6 +262,7 @@ out:
262static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) 262static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
263{ 263{
264 struct mei_msg_hdr mei_hdr; 264 struct mei_msg_hdr mei_hdr;
265 struct mei_cl *cl;
265 int ret; 266 int ret;
266 267
267 if (!dev || !cb) 268 if (!dev || !cb)
@@ -277,8 +278,9 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
277 dev->iamthif_msg_buf_size = cb->request_buffer.size; 278 dev->iamthif_msg_buf_size = cb->request_buffer.size;
278 memcpy(dev->iamthif_msg_buf, cb->request_buffer.data, 279 memcpy(dev->iamthif_msg_buf, cb->request_buffer.data,
279 cb->request_buffer.size); 280 cb->request_buffer.size);
281 cl = &dev->iamthif_cl;
280 282
281 ret = mei_cl_flow_ctrl_creds(&dev->iamthif_cl); 283 ret = mei_cl_flow_ctrl_creds(cl);
282 if (ret < 0) 284 if (ret < 0)
283 return ret; 285 return ret;
284 286
@@ -292,8 +294,8 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
292 mei_hdr.msg_complete = 1; 294 mei_hdr.msg_complete = 1;
293 } 295 }
294 296
295 mei_hdr.host_addr = dev->iamthif_cl.host_client_id; 297 mei_hdr.host_addr = cl->host_client_id;
296 mei_hdr.me_addr = dev->iamthif_cl.me_client_id; 298 mei_hdr.me_addr = cl->me_client_id;
297 mei_hdr.reserved = 0; 299 mei_hdr.reserved = 0;
298 mei_hdr.internal = 0; 300 mei_hdr.internal = 0;
299 dev->iamthif_msg_buf_index += mei_hdr.length; 301 dev->iamthif_msg_buf_index += mei_hdr.length;
@@ -302,7 +304,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
302 return ret; 304 return ret;
303 305
304 if (mei_hdr.msg_complete) { 306 if (mei_hdr.msg_complete) {
305 if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl)) 307 if (mei_cl_flow_ctrl_reduce(cl))
306 return -EIO; 308 return -EIO;
307 dev->iamthif_flow_control_pending = true; 309 dev->iamthif_flow_control_pending = true;
308 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; 310 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
@@ -360,8 +362,7 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb)
360void mei_amthif_run_next_cmd(struct mei_device *dev) 362void mei_amthif_run_next_cmd(struct mei_device *dev)
361{ 363{
362 struct mei_cl_cb *cb; 364 struct mei_cl_cb *cb;
363 struct mei_cl_cb *next; 365 int ret;
364 int status;
365 366
366 if (!dev) 367 if (!dev)
367 return; 368 return;
@@ -376,16 +377,14 @@ void mei_amthif_run_next_cmd(struct mei_device *dev)
376 377
377 dev_dbg(dev->dev, "complete amthif cmd_list cb.\n"); 378 dev_dbg(dev->dev, "complete amthif cmd_list cb.\n");
378 379
379 list_for_each_entry_safe(cb, next, &dev->amthif_cmd_list.list, list) { 380 cb = list_first_entry_or_null(&dev->amthif_cmd_list.list,
380 list_del(&cb->list); 381 typeof(*cb), list);
381 if (!cb->cl) 382 if (!cb)
382 continue; 383 return;
383 status = mei_amthif_send_cmd(dev, cb); 384 list_del(&cb->list);
384 if (status) 385 ret = mei_amthif_send_cmd(dev, cb);
385 dev_warn(dev->dev, "amthif write failed status = %d\n", 386 if (ret)
386 status); 387 dev_warn(dev->dev, "amthif write failed status = %d\n", ret);
387 break;
388 }
389} 388}
390 389
391 390
@@ -536,9 +535,6 @@ int mei_amthif_irq_read_msg(struct mei_device *dev,
536 cb = dev->iamthif_current_cb; 535 cb = dev->iamthif_current_cb;
537 dev->iamthif_current_cb = NULL; 536 dev->iamthif_current_cb = NULL;
538 537
539 if (!cb->cl)
540 return -ENODEV;
541
542 dev->iamthif_stall_timer = 0; 538 dev->iamthif_stall_timer = 0;
543 cb->buf_idx = dev->iamthif_msg_buf_index; 539 cb->buf_idx = dev->iamthif_msg_buf_index;
544 cb->read_time = jiffies; 540 cb->read_time = jiffies;
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 4d20d60ca38d..b3a72bca5242 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -140,7 +140,7 @@ static struct device_type mei_cl_device_type = {
140 .release = mei_cl_dev_release, 140 .release = mei_cl_dev_release,
141}; 141};
142 142
143static struct mei_cl *mei_bus_find_mei_cl_by_uuid(struct mei_device *dev, 143struct mei_cl *mei_cl_bus_find_cl_by_uuid(struct mei_device *dev,
144 uuid_le uuid) 144 uuid_le uuid)
145{ 145{
146 struct mei_cl *cl; 146 struct mei_cl *cl;
@@ -160,7 +160,7 @@ struct mei_cl_device *mei_cl_add_device(struct mei_device *dev,
160 struct mei_cl *cl; 160 struct mei_cl *cl;
161 int status; 161 int status;
162 162
163 cl = mei_bus_find_mei_cl_by_uuid(dev, uuid); 163 cl = mei_cl_bus_find_cl_by_uuid(dev, uuid);
164 if (cl == NULL) 164 if (cl == NULL)
165 return NULL; 165 return NULL;
166 166
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index bc9ba5359bc6..1382d551d7ed 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -146,7 +146,7 @@ static void __mei_io_list_flush(struct mei_cl_cb *list,
146 146
147 /* enable removing everything if no cl is specified */ 147 /* enable removing everything if no cl is specified */
148 list_for_each_entry_safe(cb, next, &list->list, list) { 148 list_for_each_entry_safe(cb, next, &list->list, list) {
149 if (!cl || (cb->cl && mei_cl_cmp_id(cl, cb->cl))) { 149 if (!cl || mei_cl_cmp_id(cl, cb->cl)) {
150 list_del(&cb->list); 150 list_del(&cb->list);
151 if (free) 151 if (free)
152 mei_io_cb_free(cb); 152 mei_io_cb_free(cb);
diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c
index ce1566715f80..b60b4263cf0f 100644
--- a/drivers/misc/mei/debugfs.c
+++ b/drivers/misc/mei/debugfs.c
@@ -34,7 +34,7 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf,
34 int pos = 0; 34 int pos = 0;
35 int ret; 35 int ret;
36 36
37#define HDR " |id|addr| UUID |con|msg len|sb|\n" 37#define HDR " |id|fix| UUID |con|msg len|sb|\n"
38 38
39 mutex_lock(&dev->device_lock); 39 mutex_lock(&dev->device_lock);
40 40
@@ -56,12 +56,8 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf,
56 56
57 list_for_each_entry(me_cl, &dev->me_clients, list) { 57 list_for_each_entry(me_cl, &dev->me_clients, list) {
58 58
59 /* skip me clients that cannot be connected */
60 if (me_cl->props.max_number_of_connections == 0)
61 continue;
62
63 pos += scnprintf(buf + pos, bufsz - pos, 59 pos += scnprintf(buf + pos, bufsz - pos,
64 "%2d|%2d|%4d|%pUl|%3d|%7d|%2d|\n", 60 "%2d|%2d|%3d|%pUl|%3d|%7d|%2d|\n",
65 i++, me_cl->client_id, 61 i++, me_cl->client_id,
66 me_cl->props.fixed_address, 62 me_cl->props.fixed_address,
67 &me_cl->props.protocol_name, 63 &me_cl->props.protocol_name,
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 49a2653d91a5..239d7f5d6a92 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -562,17 +562,17 @@ int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl)
562 * mei_hbm_cl_disconnect_res - update the client state according 562 * mei_hbm_cl_disconnect_res - update the client state according
563 * disconnect response 563 * disconnect response
564 * 564 *
565 * @dev: the device structure
565 * @cl: mei host client 566 * @cl: mei host client
566 * @cmd: disconnect client response host bus message 567 * @cmd: disconnect client response host bus message
567 */ 568 */
568static void mei_hbm_cl_disconnect_res(struct mei_cl *cl, 569static void mei_hbm_cl_disconnect_res(struct mei_device *dev, struct mei_cl *cl,
569 struct mei_hbm_cl_cmd *cmd) 570 struct mei_hbm_cl_cmd *cmd)
570{ 571{
571 struct hbm_client_connect_response *rs = 572 struct hbm_client_connect_response *rs =
572 (struct hbm_client_connect_response *)cmd; 573 (struct hbm_client_connect_response *)cmd;
573 574
574 dev_dbg(cl->dev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n", 575 cl_dbg(dev, cl, "hbm: disconnect response status=%d\n", rs->status);
575 rs->me_addr, rs->host_addr, rs->status);
576 576
577 if (rs->status == MEI_CL_DISCONN_SUCCESS) 577 if (rs->status == MEI_CL_DISCONN_SUCCESS)
578 cl->state = MEI_FILE_DISCONNECTED; 578 cl->state = MEI_FILE_DISCONNECTED;
@@ -598,17 +598,17 @@ int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl)
598 * mei_hbm_cl_connect_res - update the client state according 598 * mei_hbm_cl_connect_res - update the client state according
599 * connection response 599 * connection response
600 * 600 *
601 * @dev: the device structure
601 * @cl: mei host client 602 * @cl: mei host client
602 * @cmd: connect client response host bus message 603 * @cmd: connect client response host bus message
603 */ 604 */
604static void mei_hbm_cl_connect_res(struct mei_cl *cl, 605static void mei_hbm_cl_connect_res(struct mei_device *dev, struct mei_cl *cl,
605 struct mei_hbm_cl_cmd *cmd) 606 struct mei_hbm_cl_cmd *cmd)
606{ 607{
607 struct hbm_client_connect_response *rs = 608 struct hbm_client_connect_response *rs =
608 (struct hbm_client_connect_response *)cmd; 609 (struct hbm_client_connect_response *)cmd;
609 610
610 dev_dbg(cl->dev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n", 611 cl_dbg(dev, cl, "hbm: connect response status=%s\n",
611 rs->me_addr, rs->host_addr,
612 mei_cl_conn_status_str(rs->status)); 612 mei_cl_conn_status_str(rs->status));
613 613
614 if (rs->status == MEI_CL_CONN_SUCCESS) 614 if (rs->status == MEI_CL_CONN_SUCCESS)
@@ -637,11 +637,6 @@ static void mei_hbm_cl_res(struct mei_device *dev,
637 list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) { 637 list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) {
638 638
639 cl = cb->cl; 639 cl = cb->cl;
640 /* this should not happen */
641 if (WARN_ON(!cl)) {
642 list_del_init(&cb->list);
643 continue;
644 }
645 640
646 if (cb->fop_type != fop_type) 641 if (cb->fop_type != fop_type)
647 continue; 642 continue;
@@ -657,10 +652,10 @@ static void mei_hbm_cl_res(struct mei_device *dev,
657 652
658 switch (fop_type) { 653 switch (fop_type) {
659 case MEI_FOP_CONNECT: 654 case MEI_FOP_CONNECT:
660 mei_hbm_cl_connect_res(cl, rs); 655 mei_hbm_cl_connect_res(dev, cl, rs);
661 break; 656 break;
662 case MEI_FOP_DISCONNECT: 657 case MEI_FOP_DISCONNECT:
663 mei_hbm_cl_disconnect_res(cl, rs); 658 mei_hbm_cl_disconnect_res(dev, cl, rs);
664 break; 659 break;
665 default: 660 default:
666 return; 661 return;
@@ -811,8 +806,6 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
811 return -EPROTO; 806 return -EPROTO;
812 } 807 }
813 808
814 dev->hbm_state = MEI_HBM_STARTED;
815
816 if (mei_hbm_enum_clients_req(dev)) { 809 if (mei_hbm_enum_clients_req(dev)) {
817 dev_err(dev->dev, "hbm: start: failed to send enumeration request\n"); 810 dev_err(dev->dev, "hbm: start: failed to send enumeration request\n");
818 return -EIO; 811 return -EIO;
diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h
index b7cd3d857fd5..2544db7d1649 100644
--- a/drivers/misc/mei/hbm.h
+++ b/drivers/misc/mei/hbm.h
@@ -26,17 +26,17 @@ struct mei_cl;
26 * 26 *
27 * @MEI_HBM_IDLE : protocol not started 27 * @MEI_HBM_IDLE : protocol not started
28 * @MEI_HBM_STARTING : start request message was sent 28 * @MEI_HBM_STARTING : start request message was sent
29 * @MEI_HBM_STARTED : start reply message was received
30 * @MEI_HBM_ENUM_CLIENTS : enumeration request was sent 29 * @MEI_HBM_ENUM_CLIENTS : enumeration request was sent
31 * @MEI_HBM_CLIENT_PROPERTIES : acquiring clients properties 30 * @MEI_HBM_CLIENT_PROPERTIES : acquiring clients properties
31 * @MEI_HBM_STARTED : enumeration was completed
32 * @MEI_HBM_STOPPED : stopping exchange 32 * @MEI_HBM_STOPPED : stopping exchange
33 */ 33 */
34enum mei_hbm_state { 34enum mei_hbm_state {
35 MEI_HBM_IDLE = 0, 35 MEI_HBM_IDLE = 0,
36 MEI_HBM_STARTING, 36 MEI_HBM_STARTING,
37 MEI_HBM_STARTED,
38 MEI_HBM_ENUM_CLIENTS, 37 MEI_HBM_ENUM_CLIENTS,
39 MEI_HBM_CLIENT_PROPERTIES, 38 MEI_HBM_CLIENT_PROPERTIES,
39 MEI_HBM_STARTED,
40 MEI_HBM_STOPPED, 40 MEI_HBM_STOPPED,
41}; 41};
42 42
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
index c5feafdd58a8..9eb7ed70ace2 100644
--- a/drivers/misc/mei/hw-me-regs.h
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -117,14 +117,18 @@
117#define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */ 117#define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */
118#define MEI_DEV_ID_WPT_LP_2 0x9CBB /* Wildcat Point LP 2 */ 118#define MEI_DEV_ID_WPT_LP_2 0x9CBB /* Wildcat Point LP 2 */
119 119
120/* Host Firmware Status Registers in PCI Config Space */
121#define PCI_CFG_HFS_1 0x40
122#define PCI_CFG_HFS_2 0x48
123
124/* 120/*
125 * MEI HW Section 121 * MEI HW Section
126 */ 122 */
127 123
124/* Host Firmware Status Registers in PCI Config Space */
125#define PCI_CFG_HFS_1 0x40
126#define PCI_CFG_HFS_2 0x48
127#define PCI_CFG_HFS_3 0x60
128#define PCI_CFG_HFS_4 0x64
129#define PCI_CFG_HFS_5 0x68
130#define PCI_CFG_HFS_6 0x6C
131
128/* MEI registers */ 132/* MEI registers */
129/* H_CB_WW - Host Circular Buffer (CB) Write Window register */ 133/* H_CB_WW - Host Circular Buffer (CB) Write Window register */
130#define H_CB_WW 0 134#define H_CB_WW 0
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 4f2fd6fc1e23..ff2755062b44 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -270,10 +270,10 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
270static void mei_me_host_set_ready(struct mei_device *dev) 270static void mei_me_host_set_ready(struct mei_device *dev)
271{ 271{
272 struct mei_me_hw *hw = to_me_hw(dev); 272 struct mei_me_hw *hw = to_me_hw(dev);
273 u32 hcsr = mei_hcsr_read(hw);
273 274
274 hw->host_hw_state = mei_hcsr_read(hw); 275 hcsr |= H_IE | H_IG | H_RDY;
275 hw->host_hw_state |= H_IE | H_IG | H_RDY; 276 mei_hcsr_set(hw, hcsr);
276 mei_hcsr_set(hw, hw->host_hw_state);
277} 277}
278 278
279/** 279/**
@@ -285,9 +285,9 @@ static void mei_me_host_set_ready(struct mei_device *dev)
285static bool mei_me_host_is_ready(struct mei_device *dev) 285static bool mei_me_host_is_ready(struct mei_device *dev)
286{ 286{
287 struct mei_me_hw *hw = to_me_hw(dev); 287 struct mei_me_hw *hw = to_me_hw(dev);
288 u32 hcsr = mei_hcsr_read(hw);
288 289
289 hw->host_hw_state = mei_hcsr_read(hw); 290 return (hcsr & H_RDY) == H_RDY;
290 return (hw->host_hw_state & H_RDY) == H_RDY;
291} 291}
292 292
293/** 293/**
@@ -299,9 +299,9 @@ static bool mei_me_host_is_ready(struct mei_device *dev)
299static bool mei_me_hw_is_ready(struct mei_device *dev) 299static bool mei_me_hw_is_ready(struct mei_device *dev)
300{ 300{
301 struct mei_me_hw *hw = to_me_hw(dev); 301 struct mei_me_hw *hw = to_me_hw(dev);
302 u32 mecsr = mei_me_mecsr_read(hw);
302 303
303 hw->me_hw_state = mei_me_mecsr_read(hw); 304 return (mecsr & ME_RDY_HRA) == ME_RDY_HRA;
304 return (hw->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA;
305} 305}
306 306
307/** 307/**
@@ -356,12 +356,13 @@ static int mei_me_hw_start(struct mei_device *dev)
356static unsigned char mei_hbuf_filled_slots(struct mei_device *dev) 356static unsigned char mei_hbuf_filled_slots(struct mei_device *dev)
357{ 357{
358 struct mei_me_hw *hw = to_me_hw(dev); 358 struct mei_me_hw *hw = to_me_hw(dev);
359 u32 hcsr;
359 char read_ptr, write_ptr; 360 char read_ptr, write_ptr;
360 361
361 hw->host_hw_state = mei_hcsr_read(hw); 362 hcsr = mei_hcsr_read(hw);
362 363
363 read_ptr = (char) ((hw->host_hw_state & H_CBRP) >> 8); 364 read_ptr = (char) ((hcsr & H_CBRP) >> 8);
364 write_ptr = (char) ((hw->host_hw_state & H_CBWP) >> 16); 365 write_ptr = (char) ((hcsr & H_CBWP) >> 16);
365 366
366 return (unsigned char) (write_ptr - read_ptr); 367 return (unsigned char) (write_ptr - read_ptr);
367} 368}
@@ -474,13 +475,14 @@ static int mei_me_write_message(struct mei_device *dev,
474static int mei_me_count_full_read_slots(struct mei_device *dev) 475static int mei_me_count_full_read_slots(struct mei_device *dev)
475{ 476{
476 struct mei_me_hw *hw = to_me_hw(dev); 477 struct mei_me_hw *hw = to_me_hw(dev);
478 u32 me_csr;
477 char read_ptr, write_ptr; 479 char read_ptr, write_ptr;
478 unsigned char buffer_depth, filled_slots; 480 unsigned char buffer_depth, filled_slots;
479 481
480 hw->me_hw_state = mei_me_mecsr_read(hw); 482 me_csr = mei_me_mecsr_read(hw);
481 buffer_depth = (unsigned char)((hw->me_hw_state & ME_CBD_HRA) >> 24); 483 buffer_depth = (unsigned char)((me_csr & ME_CBD_HRA) >> 24);
482 read_ptr = (char) ((hw->me_hw_state & ME_CBRP_HRA) >> 8); 484 read_ptr = (char) ((me_csr & ME_CBRP_HRA) >> 8);
483 write_ptr = (char) ((hw->me_hw_state & ME_CBWP_HRA) >> 16); 485 write_ptr = (char) ((me_csr & ME_CBWP_HRA) >> 16);
484 filled_slots = (unsigned char) (write_ptr - read_ptr); 486 filled_slots = (unsigned char) (write_ptr - read_ptr);
485 487
486 /* check for overflow */ 488 /* check for overflow */
@@ -833,6 +835,14 @@ static bool mei_me_fw_type_sps(struct pci_dev *pdev)
833 .fw_status.status[0] = PCI_CFG_HFS_1, \ 835 .fw_status.status[0] = PCI_CFG_HFS_1, \
834 .fw_status.status[1] = PCI_CFG_HFS_2 836 .fw_status.status[1] = PCI_CFG_HFS_2
835 837
838#define MEI_CFG_PCH8_HFS \
839 .fw_status.count = 6, \
840 .fw_status.status[0] = PCI_CFG_HFS_1, \
841 .fw_status.status[1] = PCI_CFG_HFS_2, \
842 .fw_status.status[2] = PCI_CFG_HFS_3, \
843 .fw_status.status[3] = PCI_CFG_HFS_4, \
844 .fw_status.status[4] = PCI_CFG_HFS_5, \
845 .fw_status.status[5] = PCI_CFG_HFS_6
836 846
837/* ICH Legacy devices */ 847/* ICH Legacy devices */
838const struct mei_cfg mei_me_legacy_cfg = { 848const struct mei_cfg mei_me_legacy_cfg = {
@@ -856,9 +866,14 @@ const struct mei_cfg mei_me_pch_cpt_pbg_cfg = {
856 MEI_CFG_FW_NM, 866 MEI_CFG_FW_NM,
857}; 867};
858 868
859/* PCH Lynx Point with quirk for SPS Firmware exclusion */ 869/* PCH8 Lynx Point and newer devices */
860const struct mei_cfg mei_me_lpt_cfg = { 870const struct mei_cfg mei_me_pch8_cfg = {
861 MEI_CFG_PCH_HFS, 871 MEI_CFG_PCH8_HFS,
872};
873
874/* PCH8 Lynx Point with quirk for SPS Firmware exclusion */
875const struct mei_cfg mei_me_pch8_sps_cfg = {
876 MEI_CFG_PCH8_HFS,
862 MEI_CFG_FW_SPS, 877 MEI_CFG_FW_SPS,
863}; 878};
864 879
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
index e6a59a62573a..d6567af44377 100644
--- a/drivers/misc/mei/hw-me.h
+++ b/drivers/misc/mei/hw-me.h
@@ -51,18 +51,11 @@ struct mei_cfg {
51 * 51 *
52 * @cfg: per device generation config and ops 52 * @cfg: per device generation config and ops
53 * @mem_addr: io memory address 53 * @mem_addr: io memory address
54 * @host_hw_state: cached host state
55 * @me_hw_state: cached me (fw) state
56 * @pg_state: power gating state 54 * @pg_state: power gating state
57 */ 55 */
58struct mei_me_hw { 56struct mei_me_hw {
59 const struct mei_cfg *cfg; 57 const struct mei_cfg *cfg;
60 void __iomem *mem_addr; 58 void __iomem *mem_addr;
61 /*
62 * hw states of host and fw(ME)
63 */
64 u32 host_hw_state;
65 u32 me_hw_state;
66 enum mei_pg_state pg_state; 59 enum mei_pg_state pg_state;
67}; 60};
68 61
@@ -72,7 +65,8 @@ extern const struct mei_cfg mei_me_legacy_cfg;
72extern const struct mei_cfg mei_me_ich_cfg; 65extern const struct mei_cfg mei_me_ich_cfg;
73extern const struct mei_cfg mei_me_pch_cfg; 66extern const struct mei_cfg mei_me_pch_cfg;
74extern const struct mei_cfg mei_me_pch_cpt_pbg_cfg; 67extern const struct mei_cfg mei_me_pch_cpt_pbg_cfg;
75extern const struct mei_cfg mei_me_lpt_cfg; 68extern const struct mei_cfg mei_me_pch8_cfg;
69extern const struct mei_cfg mei_me_pch8_sps_cfg;
76 70
77struct mei_device *mei_me_dev_init(struct pci_dev *pdev, 71struct mei_device *mei_me_dev_init(struct pci_dev *pdev,
78 const struct mei_cfg *cfg); 72 const struct mei_cfg *cfg);
diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c
index c5e1902e493f..618ea721aca8 100644
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -700,11 +700,10 @@ static int mei_txe_write(struct mei_device *dev,
700 mei_txe_input_ready_interrupt_enable(dev); 700 mei_txe_input_ready_interrupt_enable(dev);
701 701
702 if (!mei_txe_is_input_ready(dev)) { 702 if (!mei_txe_is_input_ready(dev)) {
703 struct mei_fw_status fw_status; 703 char fw_sts_str[MEI_FW_STATUS_STR_SZ];
704 704
705 mei_fw_status(dev, &fw_status); 705 mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ);
706 dev_err(dev->dev, "Input is not ready " FW_STS_FMT "\n", 706 dev_err(dev->dev, "Input is not ready %s\n", fw_sts_str);
707 FW_STS_PRM(fw_status));
708 return -EAGAIN; 707 return -EAGAIN;
709 } 708 }
710 709
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 7901d076c127..9306219d5675 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -54,6 +54,35 @@ const char *mei_pg_state_str(enum mei_pg_state state)
54#undef MEI_PG_STATE 54#undef MEI_PG_STATE
55} 55}
56 56
57/**
58 * mei_fw_status2str - convert fw status registers to printable string
59 *
60 * @fw_status: firmware status
61 * @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ
62 * @len: buffer len must be >= MEI_FW_STATUS_STR_SZ
63 *
64 * Return: number of bytes written or -EINVAL if buffer is to small
65 */
66ssize_t mei_fw_status2str(struct mei_fw_status *fw_status,
67 char *buf, size_t len)
68{
69 ssize_t cnt = 0;
70 int i;
71
72 buf[0] = '\0';
73
74 if (len < MEI_FW_STATUS_STR_SZ)
75 return -EINVAL;
76
77 for (i = 0; i < fw_status->count; i++)
78 cnt += scnprintf(buf + cnt, len - cnt, "%08X ",
79 fw_status->status[i]);
80
81 /* drop last space */
82 buf[cnt] = '\0';
83 return cnt;
84}
85EXPORT_SYMBOL_GPL(mei_fw_status2str);
57 86
58/** 87/**
59 * mei_cancel_work - Cancel mei background jobs 88 * mei_cancel_work - Cancel mei background jobs
@@ -86,12 +115,11 @@ int mei_reset(struct mei_device *dev)
86 state != MEI_DEV_DISABLED && 115 state != MEI_DEV_DISABLED &&
87 state != MEI_DEV_POWER_DOWN && 116 state != MEI_DEV_POWER_DOWN &&
88 state != MEI_DEV_POWER_UP) { 117 state != MEI_DEV_POWER_UP) {
89 struct mei_fw_status fw_status; 118 char fw_sts_str[MEI_FW_STATUS_STR_SZ];
90 119
91 mei_fw_status(dev, &fw_status); 120 mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ);
92 dev_warn(dev->dev, 121 dev_warn(dev->dev, "unexpected reset: dev_state = %s fw status = %s\n",
93 "unexpected reset: dev_state = %s " FW_STS_FMT "\n", 122 mei_dev_state_str(state), fw_sts_str);
94 mei_dev_state_str(state), FW_STS_PRM(fw_status));
95 } 123 }
96 124
97 /* we're already in reset, cancel the init timer 125 /* we're already in reset, cancel the init timer
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 20c6c511f438..711cddfa9c99 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -44,8 +44,6 @@ void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list)
44 list_for_each_entry_safe(cb, next, &compl_list->list, list) { 44 list_for_each_entry_safe(cb, next, &compl_list->list, list) {
45 cl = cb->cl; 45 cl = cb->cl;
46 list_del(&cb->list); 46 list_del(&cb->list);
47 if (!cl)
48 continue;
49 47
50 dev_dbg(dev->dev, "completing call back.\n"); 48 dev_dbg(dev->dev, "completing call back.\n");
51 if (cl == &dev->iamthif_cl) 49 if (cl == &dev->iamthif_cl)
@@ -105,7 +103,7 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
105 103
106 list_for_each_entry_safe(cb, next, &dev->read_list.list, list) { 104 list_for_each_entry_safe(cb, next, &dev->read_list.list, list) {
107 cl = cb->cl; 105 cl = cb->cl;
108 if (!cl || !mei_cl_is_reading(cl, mei_hdr)) 106 if (!mei_cl_is_reading(cl, mei_hdr))
109 continue; 107 continue;
110 108
111 cl->reading_state = MEI_READING; 109 cl->reading_state = MEI_READING;
@@ -449,8 +447,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
449 list = &dev->write_waiting_list; 447 list = &dev->write_waiting_list;
450 list_for_each_entry_safe(cb, next, &list->list, list) { 448 list_for_each_entry_safe(cb, next, &list->list, list) {
451 cl = cb->cl; 449 cl = cb->cl;
452 if (cl == NULL)
453 continue;
454 450
455 cl->status = 0; 451 cl->status = 0;
456 list_del(&cb->list); 452 list_del(&cb->list);
@@ -489,10 +485,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
489 dev_dbg(dev->dev, "complete control write list cb.\n"); 485 dev_dbg(dev->dev, "complete control write list cb.\n");
490 list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list.list, list) { 486 list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list.list, list) {
491 cl = cb->cl; 487 cl = cb->cl;
492 if (!cl) {
493 list_del(&cb->list);
494 return -ENODEV;
495 }
496 switch (cb->fop_type) { 488 switch (cb->fop_type) {
497 case MEI_FOP_DISCONNECT: 489 case MEI_FOP_DISCONNECT:
498 /* send disconnect message */ 490 /* send disconnect message */
@@ -530,8 +522,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
530 dev_dbg(dev->dev, "complete write list cb.\n"); 522 dev_dbg(dev->dev, "complete write list cb.\n");
531 list_for_each_entry_safe(cb, next, &dev->write_list.list, list) { 523 list_for_each_entry_safe(cb, next, &dev->write_list.list, list) {
532 cl = cb->cl; 524 cl = cb->cl;
533 if (cl == NULL)
534 continue;
535 if (cl == &dev->iamthif_cl) 525 if (cl == &dev->iamthif_cl)
536 ret = mei_amthif_irq_write(cl, cb, cmpl_list); 526 ret = mei_amthif_irq_write(cl, cb, cmpl_list);
537 else 527 else
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index beedc91f03a6..ae56ba6ca0e3 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -631,6 +631,44 @@ out:
631 return mask; 631 return mask;
632} 632}
633 633
634/**
635 * fw_status_show - mei device attribute show method
636 *
637 * @device: device pointer
638 * @attr: attribute pointer
639 * @buf: char out buffer
640 *
641 * Return: number of the bytes printed into buf or error
642 */
643static ssize_t fw_status_show(struct device *device,
644 struct device_attribute *attr, char *buf)
645{
646 struct mei_device *dev = dev_get_drvdata(device);
647 struct mei_fw_status fw_status;
648 int err, i;
649 ssize_t cnt = 0;
650
651 mutex_lock(&dev->device_lock);
652 err = mei_fw_status(dev, &fw_status);
653 mutex_unlock(&dev->device_lock);
654 if (err) {
655 dev_err(device, "read fw_status error = %d\n", err);
656 return err;
657 }
658
659 for (i = 0; i < fw_status.count; i++)
660 cnt += scnprintf(buf + cnt, PAGE_SIZE - cnt, "%08X\n",
661 fw_status.status[i]);
662 return cnt;
663}
664static DEVICE_ATTR_RO(fw_status);
665
666static struct attribute *mei_attrs[] = {
667 &dev_attr_fw_status.attr,
668 NULL
669};
670ATTRIBUTE_GROUPS(mei);
671
634/* 672/*
635 * file operations structure will be used for mei char device. 673 * file operations structure will be used for mei char device.
636 */ 674 */
@@ -710,8 +748,9 @@ int mei_register(struct mei_device *dev, struct device *parent)
710 goto err_dev_add; 748 goto err_dev_add;
711 } 749 }
712 750
713 clsdev = device_create(mei_class, parent, devno, 751 clsdev = device_create_with_groups(mei_class, parent, devno,
714 NULL, "mei%d", dev->minor); 752 dev, mei_groups,
753 "mei%d", dev->minor);
715 754
716 if (IS_ERR(clsdev)) { 755 if (IS_ERR(clsdev)) {
717 dev_err(parent, "unable to create device %d:%d\n", 756 dev_err(parent, "unable to create device %d:%d\n",
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 61b04d7646f1..3dad74a8d496 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -152,7 +152,10 @@ struct mei_msg_data {
152}; 152};
153 153
154/* Maximum number of processed FW status registers */ 154/* Maximum number of processed FW status registers */
155#define MEI_FW_STATUS_MAX 2 155#define MEI_FW_STATUS_MAX 6
156/* Minimal buffer for FW status string (8 bytes in dw + space or '\0') */
157#define MEI_FW_STATUS_STR_SZ (MEI_FW_STATUS_MAX * (8 + 1))
158
156 159
157/* 160/*
158 * struct mei_fw_status - storage of FW status data 161 * struct mei_fw_status - storage of FW status data
@@ -349,6 +352,7 @@ void mei_cl_bus_rx_event(struct mei_cl *cl);
349void mei_cl_bus_remove_devices(struct mei_device *dev); 352void mei_cl_bus_remove_devices(struct mei_device *dev);
350int mei_cl_bus_init(void); 353int mei_cl_bus_init(void);
351void mei_cl_bus_exit(void); 354void mei_cl_bus_exit(void);
355struct mei_cl *mei_cl_bus_find_cl_by_uuid(struct mei_device *dev, uuid_le uuid);
352 356
353 357
354/** 358/**
@@ -804,11 +808,6 @@ static inline int mei_fw_status(struct mei_device *dev,
804 return dev->ops->fw_status(dev, fw_status); 808 return dev->ops->fw_status(dev, fw_status);
805} 809}
806 810
807#define FW_STS_FMT "%08X %08X"
808#define FW_STS_PRM(fw_status) \
809 (fw_status).count > 0 ? (fw_status).status[0] : 0xDEADBEEF, \
810 (fw_status).count > 1 ? (fw_status).status[1] : 0xDEADBEEF
811
812bool mei_hbuf_acquire(struct mei_device *dev); 811bool mei_hbuf_acquire(struct mei_device *dev);
813 812
814bool mei_write_is_idle(struct mei_device *dev); 813bool mei_write_is_idle(struct mei_device *dev);
@@ -832,4 +831,32 @@ void mei_deregister(struct mei_device *dev);
832 (hdr)->host_addr, (hdr)->me_addr, \ 831 (hdr)->host_addr, (hdr)->me_addr, \
833 (hdr)->length, (hdr)->internal, (hdr)->msg_complete 832 (hdr)->length, (hdr)->internal, (hdr)->msg_complete
834 833
834ssize_t mei_fw_status2str(struct mei_fw_status *fw_sts, char *buf, size_t len);
835/**
836 * mei_fw_status_str - fetch and convert fw status registers to printable string
837 *
838 * @dev: the device structure
839 * @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ
840 * @len: buffer len must be >= MEI_FW_STATUS_STR_SZ
841 *
842 * Return: number of bytes written or < 0 on failure
843 */
844static inline ssize_t mei_fw_status_str(struct mei_device *dev,
845 char *buf, size_t len)
846{
847 struct mei_fw_status fw_status;
848 int ret;
849
850 buf[0] = '\0';
851
852 ret = mei_fw_status(dev, &fw_status);
853 if (ret)
854 return ret;
855
856 ret = mei_fw_status2str(&fw_status, buf, MEI_FW_STATUS_STR_SZ);
857
858 return ret;
859}
860
861
835#endif 862#endif
diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c
index 622654323177..60ca9240368e 100644
--- a/drivers/misc/mei/nfc.c
+++ b/drivers/misc/mei/nfc.c
@@ -117,8 +117,6 @@ struct mei_nfc_dev {
117 u16 recv_req_id; 117 u16 recv_req_id;
118}; 118};
119 119
120static struct mei_nfc_dev nfc_dev;
121
122/* UUIDs for NFC F/W clients */ 120/* UUIDs for NFC F/W clients */
123const uuid_le mei_nfc_guid = UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, 121const uuid_le mei_nfc_guid = UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50,
124 0x94, 0xd4, 0x50, 0x26, 122 0x94, 0xd4, 0x50, 0x26,
@@ -138,6 +136,9 @@ static const uuid_le mei_nfc_info_guid = UUID_LE(0xd2de1625, 0x382d, 0x417d,
138 136
139static void mei_nfc_free(struct mei_nfc_dev *ndev) 137static void mei_nfc_free(struct mei_nfc_dev *ndev)
140{ 138{
139 if (!ndev)
140 return;
141
141 if (ndev->cl) { 142 if (ndev->cl) {
142 list_del(&ndev->cl->device_link); 143 list_del(&ndev->cl->device_link);
143 mei_cl_unlink(ndev->cl); 144 mei_cl_unlink(ndev->cl);
@@ -150,7 +151,7 @@ static void mei_nfc_free(struct mei_nfc_dev *ndev)
150 kfree(ndev->cl_info); 151 kfree(ndev->cl_info);
151 } 152 }
152 153
153 memset(ndev, 0, sizeof(struct mei_nfc_dev)); 154 kfree(ndev);
154} 155}
155 156
156static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev) 157static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev)
@@ -319,9 +320,10 @@ err:
319static int mei_nfc_enable(struct mei_cl_device *cldev) 320static int mei_nfc_enable(struct mei_cl_device *cldev)
320{ 321{
321 struct mei_device *dev; 322 struct mei_device *dev;
322 struct mei_nfc_dev *ndev = &nfc_dev; 323 struct mei_nfc_dev *ndev;
323 int ret; 324 int ret;
324 325
326 ndev = (struct mei_nfc_dev *)cldev->priv_data;
325 dev = ndev->cl->dev; 327 dev = ndev->cl->dev;
326 328
327 ret = mei_nfc_connect(ndev); 329 ret = mei_nfc_connect(ndev);
@@ -479,15 +481,25 @@ err:
479 481
480int mei_nfc_host_init(struct mei_device *dev) 482int mei_nfc_host_init(struct mei_device *dev)
481{ 483{
482 struct mei_nfc_dev *ndev = &nfc_dev; 484 struct mei_nfc_dev *ndev;
483 struct mei_cl *cl_info, *cl = NULL; 485 struct mei_cl *cl_info, *cl = NULL;
484 struct mei_me_client *me_cl; 486 struct mei_me_client *me_cl;
485 int ret; 487 int ret;
486 488
487 /* already initialized */ 489
488 if (ndev->cl_info) 490 /* in case of internal reset bail out
491 * as the device is already setup
492 */
493 cl = mei_cl_bus_find_cl_by_uuid(dev, mei_nfc_guid);
494 if (cl)
489 return 0; 495 return 0;
490 496
497 ndev = kzalloc(sizeof(struct mei_nfc_dev), GFP_KERNEL);
498 if (!ndev) {
499 ret = -ENOMEM;
500 goto err;
501 }
502
491 ndev->cl_info = mei_cl_allocate(dev); 503 ndev->cl_info = mei_cl_allocate(dev);
492 ndev->cl = mei_cl_allocate(dev); 504 ndev->cl = mei_cl_allocate(dev);
493 505
@@ -550,9 +562,31 @@ err:
550 562
551void mei_nfc_host_exit(struct mei_device *dev) 563void mei_nfc_host_exit(struct mei_device *dev)
552{ 564{
553 struct mei_nfc_dev *ndev = &nfc_dev; 565 struct mei_nfc_dev *ndev;
566 struct mei_cl *cl;
567 struct mei_cl_device *cldev;
568
569 cl = mei_cl_bus_find_cl_by_uuid(dev, mei_nfc_guid);
570 if (!cl)
571 return;
572
573 cldev = cl->device;
574 if (!cldev)
575 return;
554 576
555 cancel_work_sync(&ndev->init_work); 577 ndev = (struct mei_nfc_dev *)cldev->priv_data;
578 if (ndev)
579 cancel_work_sync(&ndev->init_work);
580
581 cldev->priv_data = NULL;
582
583 mutex_lock(&dev->device_lock);
584 /* Need to remove the device here
585 * since mei_nfc_free will unlink the clients
586 */
587 mei_cl_remove_device(cldev);
588 mei_nfc_free(ndev);
589 mutex_unlock(&dev->device_lock);
556} 590}
557 591
558 592
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index cf20d397068a..bd3039ab8f98 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -76,12 +76,12 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
76 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, mei_me_pch_cfg)}, 76 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, mei_me_pch_cfg)},
77 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, mei_me_pch_cfg)}, 77 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, mei_me_pch_cfg)},
78 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, mei_me_pch_cfg)}, 78 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, mei_me_pch_cfg)},
79 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, mei_me_lpt_cfg)}, 79 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, mei_me_pch8_sps_cfg)},
80 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, mei_me_lpt_cfg)}, 80 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, mei_me_pch8_sps_cfg)},
81 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, mei_me_pch_cfg)}, 81 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, mei_me_pch8_cfg)},
82 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_lpt_cfg)}, 82 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_pch8_sps_cfg)},
83 {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, mei_me_pch_cfg)}, 83 {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, mei_me_pch8_cfg)},
84 {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, mei_me_pch_cfg)}, 84 {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, mei_me_pch8_cfg)},
85 85
86 /* required last entry */ 86 /* required last entry */
87 {0, } 87 {0, }
diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c
index 1f572deacf54..c86e2ddbe30a 100644
--- a/drivers/misc/mei/pci-txe.c
+++ b/drivers/misc/mei/pci-txe.c
@@ -37,6 +37,7 @@
37 37
38static const struct pci_device_id mei_txe_pci_tbl[] = { 38static const struct pci_device_id mei_txe_pci_tbl[] = {
39 {PCI_VDEVICE(INTEL, 0x0F18)}, /* Baytrail */ 39 {PCI_VDEVICE(INTEL, 0x0F18)}, /* Baytrail */
40 {PCI_VDEVICE(INTEL, 0x2298)}, /* Cherrytrail */
40 41
41 {0, } 42 {0, }
42}; 43};
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index b836dfffceb5..b1d892cea94d 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -270,15 +270,18 @@ static int mei_wd_ops_stop(struct watchdog_device *wd_dev)
270static int mei_wd_ops_ping(struct watchdog_device *wd_dev) 270static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
271{ 271{
272 struct mei_device *dev; 272 struct mei_device *dev;
273 struct mei_cl *cl;
273 int ret; 274 int ret;
274 275
275 dev = watchdog_get_drvdata(wd_dev); 276 dev = watchdog_get_drvdata(wd_dev);
276 if (!dev) 277 if (!dev)
277 return -ENODEV; 278 return -ENODEV;
278 279
280 cl = &dev->wd_cl;
281
279 mutex_lock(&dev->device_lock); 282 mutex_lock(&dev->device_lock);
280 283
281 if (dev->wd_cl.state != MEI_FILE_CONNECTED) { 284 if (cl->state != MEI_FILE_CONNECTED) {
282 dev_err(dev->dev, "wd: not connected.\n"); 285 dev_err(dev->dev, "wd: not connected.\n");
283 ret = -ENODEV; 286 ret = -ENODEV;
284 goto end; 287 goto end;
@@ -286,12 +289,12 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
286 289
287 dev->wd_state = MEI_WD_RUNNING; 290 dev->wd_state = MEI_WD_RUNNING;
288 291
289 ret = mei_cl_flow_ctrl_creds(&dev->wd_cl); 292 ret = mei_cl_flow_ctrl_creds(cl);
290 if (ret < 0) 293 if (ret < 0)
291 goto end; 294 goto end;
295
292 /* Check if we can send the ping to HW*/ 296 /* Check if we can send the ping to HW*/
293 if (ret && mei_hbuf_acquire(dev)) { 297 if (ret && mei_hbuf_acquire(dev)) {
294
295 dev_dbg(dev->dev, "wd: sending ping\n"); 298 dev_dbg(dev->dev, "wd: sending ping\n");
296 299
297 ret = mei_wd_send(dev); 300 ret = mei_wd_send(dev);