aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-03 11:06:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-03 11:06:56 -0400
commit4046136afbd1038d776bad9c59e1e4cca78186fb (patch)
tree1888ca7bd978c0bba891ac9ee51224fd06d1162e /drivers/misc
parentb55a0ff8df92646696c858a8fea4dbf38509f202 (diff)
parenta100d88df1e924e5c9678fabf054d1bae7ab74fb (diff)
Merge tag 'char-misc-3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc into next
Pull char/misc driver patches from Greg KH: "Here is the big char / misc driver update for 3.16-rc1. Lots of different driver updates for a variety of different drivers and minor driver subsystems. All have been in linux-next with no reported issues" * tag 'char-misc-3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (79 commits) hv: use correct order when freeing monitor_pages spmi: of: fixup generic SPMI devicetree binding example applicom: dereferencing NULL on error path misc: genwqe: fix uninitialized return value in genwqe_free_sync_sgl() miscdevice.h: Simple syntax fix to make pointers consistent. MAINTAINERS: Add miscdevice.h to file list for char/misc drivers. mcb: Add support for shared PCI IRQs drivers: Remove duplicate conditionally included subdirs misc: atmel_pwm: only build for supported platforms mei: me: move probe quirk to cfg structure mei: add per device configuration mei: me: read H_CSR after asserting reset mei: me: drop harmful wait optimization mei: me: fix hw ready reset flow mei: fix memory leak of mei_clients array uio: fix vma io range check in mmap drivers: uio_dmem_genirq: Fix memory leak in uio_dmem_genirq_probe() w1: do not unlock unheld list_mutex in __w1_remove_master_device() w1: optional bundling of netlink kernel replies connector: allow multiple messages to be sent in one packet ...
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig5
-rw-r--r--drivers/misc/arm-charlcd.c7
-rw-r--r--drivers/misc/ds1682.c5
-rw-r--r--drivers/misc/genwqe/card_debugfs.c4
-rw-r--r--drivers/misc/genwqe/card_utils.c2
-rw-r--r--drivers/misc/mei/amthif.c2
-rw-r--r--drivers/misc/mei/bus.c4
-rw-r--r--drivers/misc/mei/client.c90
-rw-r--r--drivers/misc/mei/hbm.c97
-rw-r--r--drivers/misc/mei/hbm.h2
-rw-r--r--drivers/misc/mei/hw-me-regs.h9
-rw-r--r--drivers/misc/mei/hw-me.c322
-rw-r--r--drivers/misc/mei/hw-me.h15
-rw-r--r--drivers/misc/mei/hw-txe-regs.h2
-rw-r--r--drivers/misc/mei/hw-txe.c111
-rw-r--r--drivers/misc/mei/hw-txe.h21
-rw-r--r--drivers/misc/mei/hw.h25
-rw-r--r--drivers/misc/mei/init.c60
-rw-r--r--drivers/misc/mei/main.c1
-rw-r--r--drivers/misc/mei/mei_dev.h101
-rw-r--r--drivers/misc/mei/pci-me.c256
-rw-r--r--drivers/misc/mei/pci-txe.c155
-rw-r--r--drivers/misc/mei/wd.c2
23 files changed, 1132 insertions, 166 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index d9663ef90ce8..a43d0c467274 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -54,6 +54,7 @@ config AD525X_DPOT_SPI
54config ATMEL_PWM 54config ATMEL_PWM
55 tristate "Atmel AT32/AT91 PWM support" 55 tristate "Atmel AT32/AT91 PWM support"
56 depends on HAVE_CLK 56 depends on HAVE_CLK
57 depends on AVR32 || AT91SAM9263 || AT91SAM9RL || AT91SAM9G45
57 help 58 help
58 This option enables device driver support for the PWM channels 59 This option enables device driver support for the PWM channels
59 on certain Atmel processors. Pulse Width Modulation is used for 60 on certain Atmel processors. Pulse Width Modulation is used for
@@ -200,7 +201,7 @@ config ICS932S401
200 201
201config ATMEL_SSC 202config ATMEL_SSC
202 tristate "Device driver for Atmel SSC peripheral" 203 tristate "Device driver for Atmel SSC peripheral"
203 depends on HAS_IOMEM 204 depends on HAS_IOMEM && (AVR32 || ARCH_AT91 || COMPILE_TEST)
204 ---help--- 205 ---help---
205 This option enables device driver support for Atmel Synchronized 206 This option enables device driver support for Atmel Synchronized
206 Serial Communication peripheral (SSC). 207 Serial Communication peripheral (SSC).
@@ -468,7 +469,7 @@ config BMP085_SPI
468config PCH_PHUB 469config PCH_PHUB
469 tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB" 470 tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB"
470 select GENERIC_NET_UTILS 471 select GENERIC_NET_UTILS
471 depends on PCI 472 depends on PCI && (X86_32 || COMPILE_TEST)
472 help 473 help
473 This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of 474 This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
474 Intel Topcliff which is an IOH(Input/Output Hub) for x86 embedded 475 Intel Topcliff which is an IOH(Input/Output Hub) for x86 embedded
diff --git a/drivers/misc/arm-charlcd.c b/drivers/misc/arm-charlcd.c
index b7ebf8021d99..c72e96b523ed 100644
--- a/drivers/misc/arm-charlcd.c
+++ b/drivers/misc/arm-charlcd.c
@@ -11,6 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/of.h>
14#include <linux/completion.h> 15#include <linux/completion.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
16#include <linux/io.h> 17#include <linux/io.h>
@@ -366,11 +367,17 @@ static const struct dev_pm_ops charlcd_pm_ops = {
366 .resume = charlcd_resume, 367 .resume = charlcd_resume,
367}; 368};
368 369
370static const struct of_device_id charlcd_match[] = {
371 { .compatible = "arm,versatile-lcd", },
372 {}
373};
374
369static struct platform_driver charlcd_driver = { 375static struct platform_driver charlcd_driver = {
370 .driver = { 376 .driver = {
371 .name = DRIVERNAME, 377 .name = DRIVERNAME,
372 .owner = THIS_MODULE, 378 .owner = THIS_MODULE,
373 .pm = &charlcd_pm_ops, 379 .pm = &charlcd_pm_ops,
380 .of_match_table = of_match_ptr(charlcd_match),
374 }, 381 },
375 .remove = __exit_p(charlcd_remove), 382 .remove = __exit_p(charlcd_remove),
376}; 383};
diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c
index 6a672f9ef522..b909fb30232a 100644
--- a/drivers/misc/ds1682.c
+++ b/drivers/misc/ds1682.c
@@ -85,7 +85,6 @@ static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr,
85{ 85{
86 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 86 struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
87 struct i2c_client *client = to_i2c_client(dev); 87 struct i2c_client *client = to_i2c_client(dev);
88 char *endp;
89 u64 val; 88 u64 val;
90 __le32 val_le; 89 __le32 val_le;
91 int rc; 90 int rc;
@@ -93,8 +92,8 @@ static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr,
93 dev_dbg(dev, "ds1682_store() called on %s\n", attr->attr.name); 92 dev_dbg(dev, "ds1682_store() called on %s\n", attr->attr.name);
94 93
95 /* Decode input */ 94 /* Decode input */
96 val = simple_strtoull(buf, &endp, 0); 95 rc = kstrtoull(buf, 0, &val);
97 if (buf == endp) { 96 if (rc < 0) {
98 dev_dbg(dev, "input string not a number\n"); 97 dev_dbg(dev, "input string not a number\n");
99 return -EINVAL; 98 return -EINVAL;
100 } 99 }
diff --git a/drivers/misc/genwqe/card_debugfs.c b/drivers/misc/genwqe/card_debugfs.c
index 50d2096ea1c7..0a33ade64109 100644
--- a/drivers/misc/genwqe/card_debugfs.c
+++ b/drivers/misc/genwqe/card_debugfs.c
@@ -348,7 +348,7 @@ int genwqe_init_debugfs(struct genwqe_dev *cd)
348 char name[64]; 348 char name[64];
349 unsigned int i; 349 unsigned int i;
350 350
351 sprintf(card_name, "%s%u_card", GENWQE_DEVNAME, cd->card_idx); 351 sprintf(card_name, "%s%d_card", GENWQE_DEVNAME, cd->card_idx);
352 352
353 root = debugfs_create_dir(card_name, cd->debugfs_genwqe); 353 root = debugfs_create_dir(card_name, cd->debugfs_genwqe);
354 if (!root) { 354 if (!root) {
@@ -454,7 +454,7 @@ int genwqe_init_debugfs(struct genwqe_dev *cd)
454 } 454 }
455 455
456 for (i = 0; i < GENWQE_MAX_VFS; i++) { 456 for (i = 0; i < GENWQE_MAX_VFS; i++) {
457 sprintf(name, "vf%d_jobtimeout_msec", i); 457 sprintf(name, "vf%u_jobtimeout_msec", i);
458 458
459 file = debugfs_create_u32(name, 0666, root, 459 file = debugfs_create_u32(name, 0666, root,
460 &cd->vf_jobtimeout_msec[i]); 460 &cd->vf_jobtimeout_msec[i]);
diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c
index c00adfaa6279..62cc6bb3f62e 100644
--- a/drivers/misc/genwqe/card_utils.c
+++ b/drivers/misc/genwqe/card_utils.c
@@ -454,7 +454,7 @@ int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
454 */ 454 */
455int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl) 455int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl)
456{ 456{
457 int rc; 457 int rc = 0;
458 struct pci_dev *pci_dev = cd->pci_dev; 458 struct pci_dev *pci_dev = cd->pci_dev;
459 459
460 if (sgl->fpage) { 460 if (sgl->fpage) {
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index b8deb3455480..0d6234db00fa 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -111,8 +111,6 @@ int mei_amthif_host_init(struct mei_device *dev)
111 return ret; 111 return ret;
112 } 112 }
113 113
114 cl->state = MEI_FILE_CONNECTING;
115
116 ret = mei_cl_connect(cl, NULL); 114 ret = mei_cl_connect(cl, NULL);
117 115
118 dev->iamthif_state = MEI_IAMTHIF_IDLE; 116 dev->iamthif_state = MEI_IAMTHIF_IDLE;
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index ddc5ac92a200..0e993ef28b94 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -247,7 +247,7 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
247 return id; 247 return id;
248 248
249 if (length > dev->me_clients[id].props.max_msg_length) 249 if (length > dev->me_clients[id].props.max_msg_length)
250 return -EINVAL; 250 return -EFBIG;
251 251
252 cb = mei_io_cb_init(cl, NULL); 252 cb = mei_io_cb_init(cl, NULL);
253 if (!cb) 253 if (!cb)
@@ -427,8 +427,6 @@ int mei_cl_enable_device(struct mei_cl_device *device)
427 427
428 mutex_lock(&dev->device_lock); 428 mutex_lock(&dev->device_lock);
429 429
430 cl->state = MEI_FILE_CONNECTING;
431
432 err = mei_cl_connect(cl, NULL); 430 err = mei_cl_connect(cl, NULL);
433 if (err < 0) { 431 if (err < 0) {
434 mutex_unlock(&dev->device_lock); 432 mutex_unlock(&dev->device_lock);
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 8c078b808cd3..59d20c599b16 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -18,6 +18,7 @@
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/wait.h> 19#include <linux/wait.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/pm_runtime.h>
21 22
22#include <linux/mei.h> 23#include <linux/mei.h>
23 24
@@ -415,6 +416,10 @@ void mei_host_client_init(struct work_struct *work)
415 dev->reset_count = 0; 416 dev->reset_count = 0;
416 417
417 mutex_unlock(&dev->device_lock); 418 mutex_unlock(&dev->device_lock);
419
420 pm_runtime_mark_last_busy(&dev->pdev->dev);
421 dev_dbg(&dev->pdev->dev, "rpm: autosuspend\n");
422 pm_runtime_autosuspend(&dev->pdev->dev);
418} 423}
419 424
420/** 425/**
@@ -425,6 +430,12 @@ void mei_host_client_init(struct work_struct *work)
425 */ 430 */
426bool mei_hbuf_acquire(struct mei_device *dev) 431bool mei_hbuf_acquire(struct mei_device *dev)
427{ 432{
433 if (mei_pg_state(dev) == MEI_PG_ON ||
434 dev->pg_event == MEI_PG_EVENT_WAIT) {
435 dev_dbg(&dev->pdev->dev, "device is in pg\n");
436 return false;
437 }
438
428 if (!dev->hbuf_is_ready) { 439 if (!dev->hbuf_is_ready) {
429 dev_dbg(&dev->pdev->dev, "hbuf is not ready\n"); 440 dev_dbg(&dev->pdev->dev, "hbuf is not ready\n");
430 return false; 441 return false;
@@ -460,9 +471,18 @@ int mei_cl_disconnect(struct mei_cl *cl)
460 if (cl->state != MEI_FILE_DISCONNECTING) 471 if (cl->state != MEI_FILE_DISCONNECTING)
461 return 0; 472 return 0;
462 473
474 rets = pm_runtime_get(&dev->pdev->dev);
475 if (rets < 0 && rets != -EINPROGRESS) {
476 pm_runtime_put_noidle(&dev->pdev->dev);
477 cl_err(dev, cl, "rpm: get failed %d\n", rets);
478 return rets;
479 }
480
463 cb = mei_io_cb_init(cl, NULL); 481 cb = mei_io_cb_init(cl, NULL);
464 if (!cb) 482 if (!cb) {
465 return -ENOMEM; 483 rets = -ENOMEM;
484 goto free;
485 }
466 486
467 cb->fop_type = MEI_FOP_CLOSE; 487 cb->fop_type = MEI_FOP_CLOSE;
468 if (mei_hbuf_acquire(dev)) { 488 if (mei_hbuf_acquire(dev)) {
@@ -494,8 +514,7 @@ int mei_cl_disconnect(struct mei_cl *cl)
494 cl_err(dev, cl, "wrong status client disconnect.\n"); 514 cl_err(dev, cl, "wrong status client disconnect.\n");
495 515
496 if (err) 516 if (err)
497 cl_dbg(dev, cl, "wait failed disconnect err=%08x\n", 517 cl_dbg(dev, cl, "wait failed disconnect err=%d\n", err);
498 err);
499 518
500 cl_err(dev, cl, "failed to disconnect from FW client.\n"); 519 cl_err(dev, cl, "failed to disconnect from FW client.\n");
501 } 520 }
@@ -503,6 +522,10 @@ int mei_cl_disconnect(struct mei_cl *cl)
503 mei_io_list_flush(&dev->ctrl_rd_list, cl); 522 mei_io_list_flush(&dev->ctrl_rd_list, cl);
504 mei_io_list_flush(&dev->ctrl_wr_list, cl); 523 mei_io_list_flush(&dev->ctrl_wr_list, cl);
505free: 524free:
525 cl_dbg(dev, cl, "rpm: autosuspend\n");
526 pm_runtime_mark_last_busy(&dev->pdev->dev);
527 pm_runtime_put_autosuspend(&dev->pdev->dev);
528
506 mei_io_cb_free(cb); 529 mei_io_cb_free(cb);
507 return rets; 530 return rets;
508} 531}
@@ -557,6 +580,13 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
557 580
558 dev = cl->dev; 581 dev = cl->dev;
559 582
583 rets = pm_runtime_get(&dev->pdev->dev);
584 if (rets < 0 && rets != -EINPROGRESS) {
585 pm_runtime_put_noidle(&dev->pdev->dev);
586 cl_err(dev, cl, "rpm: get failed %d\n", rets);
587 return rets;
588 }
589
560 cb = mei_io_cb_init(cl, file); 590 cb = mei_io_cb_init(cl, file);
561 if (!cb) { 591 if (!cb) {
562 rets = -ENOMEM; 592 rets = -ENOMEM;
@@ -567,6 +597,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
567 597
568 /* run hbuf acquire last so we don't have to undo */ 598 /* run hbuf acquire last so we don't have to undo */
569 if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) { 599 if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) {
600 cl->state = MEI_FILE_CONNECTING;
570 if (mei_hbm_cl_connect_req(dev, cl)) { 601 if (mei_hbm_cl_connect_req(dev, cl)) {
571 rets = -ENODEV; 602 rets = -ENODEV;
572 goto out; 603 goto out;
@@ -596,6 +627,10 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
596 rets = cl->status; 627 rets = cl->status;
597 628
598out: 629out:
630 cl_dbg(dev, cl, "rpm: autosuspend\n");
631 pm_runtime_mark_last_busy(&dev->pdev->dev);
632 pm_runtime_put_autosuspend(&dev->pdev->dev);
633
599 mei_io_cb_free(cb); 634 mei_io_cb_free(cb);
600 return rets; 635 return rets;
601} 636}
@@ -713,23 +748,31 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
713 return -ENOTTY; 748 return -ENOTTY;
714 } 749 }
715 750
751 rets = pm_runtime_get(&dev->pdev->dev);
752 if (rets < 0 && rets != -EINPROGRESS) {
753 pm_runtime_put_noidle(&dev->pdev->dev);
754 cl_err(dev, cl, "rpm: get failed %d\n", rets);
755 return rets;
756 }
757
716 cb = mei_io_cb_init(cl, NULL); 758 cb = mei_io_cb_init(cl, NULL);
717 if (!cb) 759 if (!cb) {
718 return -ENOMEM; 760 rets = -ENOMEM;
761 goto out;
762 }
719 763
720 /* always allocate at least client max message */ 764 /* always allocate at least client max message */
721 length = max_t(size_t, length, dev->me_clients[i].props.max_msg_length); 765 length = max_t(size_t, length, dev->me_clients[i].props.max_msg_length);
722 rets = mei_io_cb_alloc_resp_buf(cb, length); 766 rets = mei_io_cb_alloc_resp_buf(cb, length);
723 if (rets) 767 if (rets)
724 goto err; 768 goto out;
725 769
726 cb->fop_type = MEI_FOP_READ; 770 cb->fop_type = MEI_FOP_READ;
727 if (mei_hbuf_acquire(dev)) { 771 if (mei_hbuf_acquire(dev)) {
728 if (mei_hbm_cl_flow_control_req(dev, cl)) { 772 rets = mei_hbm_cl_flow_control_req(dev, cl);
729 cl_err(dev, cl, "flow control send failed\n"); 773 if (rets < 0)
730 rets = -ENODEV; 774 goto out;
731 goto err; 775
732 }
733 list_add_tail(&cb->list, &dev->read_list.list); 776 list_add_tail(&cb->list, &dev->read_list.list);
734 } else { 777 } else {
735 list_add_tail(&cb->list, &dev->ctrl_wr_list.list); 778 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
@@ -737,9 +780,14 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
737 780
738 cl->read_cb = cb; 781 cl->read_cb = cb;
739 782
740 return rets; 783out:
741err: 784 cl_dbg(dev, cl, "rpm: autosuspend\n");
742 mei_io_cb_free(cb); 785 pm_runtime_mark_last_busy(&dev->pdev->dev);
786 pm_runtime_put_autosuspend(&dev->pdev->dev);
787
788 if (rets)
789 mei_io_cb_free(cb);
790
743 return rets; 791 return rets;
744} 792}
745 793
@@ -776,7 +824,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
776 return rets; 824 return rets;
777 825
778 if (rets == 0) { 826 if (rets == 0) {
779 cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); 827 cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
780 return 0; 828 return 0;
781 } 829 }
782 830
@@ -856,6 +904,12 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
856 904
857 cl_dbg(dev, cl, "mei_cl_write %d\n", buf->size); 905 cl_dbg(dev, cl, "mei_cl_write %d\n", buf->size);
858 906
907 rets = pm_runtime_get(&dev->pdev->dev);
908 if (rets < 0 && rets != -EINPROGRESS) {
909 pm_runtime_put_noidle(&dev->pdev->dev);
910 cl_err(dev, cl, "rpm: get failed %d\n", rets);
911 return rets;
912 }
859 913
860 cb->fop_type = MEI_FOP_WRITE; 914 cb->fop_type = MEI_FOP_WRITE;
861 cb->buf_idx = 0; 915 cb->buf_idx = 0;
@@ -926,6 +980,10 @@ out:
926 980
927 rets = buf->size; 981 rets = buf->size;
928err: 982err:
983 cl_dbg(dev, cl, "rpm: autosuspend\n");
984 pm_runtime_mark_last_busy(&dev->pdev->dev);
985 pm_runtime_put_autosuspend(&dev->pdev->dev);
986
929 return rets; 987 return rets;
930} 988}
931 989
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 4960288e543a..804106209d76 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -14,10 +14,12 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/export.h>
17#include <linux/pci.h> 18#include <linux/pci.h>
18#include <linux/sched.h> 19#include <linux/sched.h>
19#include <linux/wait.h> 20#include <linux/wait.h>
20#include <linux/mei.h> 21#include <linux/mei.h>
22#include <linux/pm_runtime.h>
21 23
22#include "mei_dev.h" 24#include "mei_dev.h"
23#include "hbm.h" 25#include "hbm.h"
@@ -58,6 +60,34 @@ static int mei_cl_conn_status_to_errno(enum mei_cl_connect_status status)
58} 60}
59 61
60/** 62/**
63 * mei_hbm_idle - set hbm to idle state
64 *
65 * @dev: the device structure
66 */
67void mei_hbm_idle(struct mei_device *dev)
68{
69 dev->init_clients_timer = 0;
70 dev->hbm_state = MEI_HBM_IDLE;
71}
72
73/**
74 * mei_hbm_reset - reset hbm counters and book keeping data structurs
75 *
76 * @dev: the device structure
77 */
78void mei_hbm_reset(struct mei_device *dev)
79{
80 dev->me_clients_num = 0;
81 dev->me_client_presentation_num = 0;
82 dev->me_client_index = 0;
83
84 kfree(dev->me_clients);
85 dev->me_clients = NULL;
86
87 mei_hbm_idle(dev);
88}
89
90/**
61 * mei_hbm_me_cl_allocate - allocates storage for me clients 91 * mei_hbm_me_cl_allocate - allocates storage for me clients
62 * 92 *
63 * @dev: the device structure 93 * @dev: the device structure
@@ -69,9 +99,7 @@ static int mei_hbm_me_cl_allocate(struct mei_device *dev)
69 struct mei_me_client *clients; 99 struct mei_me_client *clients;
70 int b; 100 int b;
71 101
72 dev->me_clients_num = 0; 102 mei_hbm_reset(dev);
73 dev->me_client_presentation_num = 0;
74 dev->me_client_index = 0;
75 103
76 /* count how many ME clients we have */ 104 /* count how many ME clients we have */
77 for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX) 105 for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX)
@@ -80,9 +108,6 @@ static int mei_hbm_me_cl_allocate(struct mei_device *dev)
80 if (dev->me_clients_num == 0) 108 if (dev->me_clients_num == 0)
81 return 0; 109 return 0;
82 110
83 kfree(dev->me_clients);
84 dev->me_clients = NULL;
85
86 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n", 111 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n",
87 dev->me_clients_num * sizeof(struct mei_me_client)); 112 dev->me_clients_num * sizeof(struct mei_me_client));
88 /* allocate storage for ME clients representation */ 113 /* allocate storage for ME clients representation */
@@ -133,17 +158,6 @@ bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf)
133} 158}
134 159
135 160
136/**
137 * mei_hbm_idle - set hbm to idle state
138 *
139 * @dev: the device structure
140 */
141void mei_hbm_idle(struct mei_device *dev)
142{
143 dev->init_clients_timer = 0;
144 dev->hbm_state = MEI_HBM_IDLE;
145}
146
147int mei_hbm_start_wait(struct mei_device *dev) 161int mei_hbm_start_wait(struct mei_device *dev)
148{ 162{
149 int ret; 163 int ret;
@@ -289,6 +303,34 @@ static int mei_hbm_prop_req(struct mei_device *dev)
289 return 0; 303 return 0;
290} 304}
291 305
306/*
307 * mei_hbm_pg - sends pg command
308 *
309 * @dev: the device structure
310 * @pg_cmd: the pg command code
311 *
312 * This function returns -EIO on write failure
313 */
314int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd)
315{
316 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
317 struct hbm_power_gate *req;
318 const size_t len = sizeof(struct hbm_power_gate);
319 int ret;
320
321 mei_hbm_hdr(mei_hdr, len);
322
323 req = (struct hbm_power_gate *)dev->wr_msg.data;
324 memset(req, 0, len);
325 req->hbm_cmd = pg_cmd;
326
327 ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data);
328 if (ret)
329 dev_err(&dev->pdev->dev, "power gate command write failed.\n");
330 return ret;
331}
332EXPORT_SYMBOL_GPL(mei_hbm_pg);
333
292/** 334/**
293 * mei_hbm_stop_req - send stop request message 335 * mei_hbm_stop_req - send stop request message
294 * 336 *
@@ -701,6 +743,27 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
701 mei_hbm_cl_flow_control_res(dev, flow_control); 743 mei_hbm_cl_flow_control_res(dev, flow_control);
702 break; 744 break;
703 745
746 case MEI_PG_ISOLATION_ENTRY_RES_CMD:
747 dev_dbg(&dev->pdev->dev, "power gate isolation entry response received\n");
748 dev->pg_event = MEI_PG_EVENT_RECEIVED;
749 if (waitqueue_active(&dev->wait_pg))
750 wake_up(&dev->wait_pg);
751 break;
752
753 case MEI_PG_ISOLATION_EXIT_REQ_CMD:
754 dev_dbg(&dev->pdev->dev, "power gate isolation exit request received\n");
755 dev->pg_event = MEI_PG_EVENT_RECEIVED;
756 if (waitqueue_active(&dev->wait_pg))
757 wake_up(&dev->wait_pg);
758 else
759 /*
760 * If the driver is not waiting on this then
761 * this is HW initiated exit from PG.
762 * Start runtime pm resume sequence to exit from PG.
763 */
764 pm_request_resume(&dev->pdev->dev);
765 break;
766
704 case HOST_CLIENT_PROPERTIES_RES_CMD: 767 case HOST_CLIENT_PROPERTIES_RES_CMD:
705 dev_dbg(&dev->pdev->dev, "hbm: properties response: message received.\n"); 768 dev_dbg(&dev->pdev->dev, "hbm: properties response: message received.\n");
706 769
diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h
index 20e8782711c0..683eb2835cec 100644
--- a/drivers/misc/mei/hbm.h
+++ b/drivers/misc/mei/hbm.h
@@ -50,6 +50,7 @@ static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length)
50} 50}
51 51
52void mei_hbm_idle(struct mei_device *dev); 52void mei_hbm_idle(struct mei_device *dev);
53void mei_hbm_reset(struct mei_device *dev);
53int mei_hbm_start_req(struct mei_device *dev); 54int mei_hbm_start_req(struct mei_device *dev);
54int mei_hbm_start_wait(struct mei_device *dev); 55int mei_hbm_start_wait(struct mei_device *dev);
55int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl); 56int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl);
@@ -57,6 +58,7 @@ int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl);
57int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl); 58int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl);
58int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl); 59int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl);
59bool mei_hbm_version_is_supported(struct mei_device *dev); 60bool mei_hbm_version_is_supported(struct mei_device *dev);
61int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd);
60 62
61#endif /* _MEI_HBM_H_ */ 63#endif /* _MEI_HBM_H_ */
62 64
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
index cabc04383685..a7856c0ac576 100644
--- a/drivers/misc/mei/hw-me-regs.h
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -133,6 +133,8 @@
133#define ME_CB_RW 8 133#define ME_CB_RW 8
134/* ME_CSR_HA - ME Control Status Host Access register (read only) */ 134/* ME_CSR_HA - ME Control Status Host Access register (read only) */
135#define ME_CSR_HA 0xC 135#define ME_CSR_HA 0xC
136/* H_HGC_CSR - PGI register */
137#define H_HPG_CSR 0x10
136 138
137 139
138/* register bits of H_CSR (Host Control Status register) */ 140/* register bits of H_CSR (Host Control Status register) */
@@ -162,6 +164,8 @@ access to ME_CBD */
162#define ME_CBWP_HRA 0x00FF0000 164#define ME_CBWP_HRA 0x00FF0000
163/* ME CB Read Pointer HRA - host read only access to ME_CBRP */ 165/* ME CB Read Pointer HRA - host read only access to ME_CBRP */
164#define ME_CBRP_HRA 0x0000FF00 166#define ME_CBRP_HRA 0x0000FF00
167/* ME Power Gate Isolation Capability HRA - host ready only access */
168#define ME_PGIC_HRA 0x00000040
165/* ME Reset HRA - host read only access to ME_RST */ 169/* ME Reset HRA - host read only access to ME_RST */
166#define ME_RST_HRA 0x00000010 170#define ME_RST_HRA 0x00000010
167/* ME Ready HRA - host read only access to ME_RDY */ 171/* ME Ready HRA - host read only access to ME_RDY */
@@ -173,4 +177,9 @@ access to ME_CBD */
173/* ME Interrupt Enable HRA - host read only access to ME_IE */ 177/* ME Interrupt Enable HRA - host read only access to ME_IE */
174#define ME_IE_HRA 0x00000001 178#define ME_IE_HRA 0x00000001
175 179
180
181/* register bits - H_HPG_CSR */
182#define H_HPG_CSR_PGIHEXR 0x00000001
183#define H_HPG_CSR_PGI 0x00000002
184
176#endif /* _MEI_HW_MEI_REGS_H_ */ 185#endif /* _MEI_HW_MEI_REGS_H_ */
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 8dbdaaef1af5..6a2d272cea43 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -109,10 +109,27 @@ static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr)
109 */ 109 */
110static void mei_me_hw_config(struct mei_device *dev) 110static void mei_me_hw_config(struct mei_device *dev)
111{ 111{
112 struct mei_me_hw *hw = to_me_hw(dev);
112 u32 hcsr = mei_hcsr_read(to_me_hw(dev)); 113 u32 hcsr = mei_hcsr_read(to_me_hw(dev));
113 /* Doesn't change in runtime */ 114 /* Doesn't change in runtime */
114 dev->hbuf_depth = (hcsr & H_CBD) >> 24; 115 dev->hbuf_depth = (hcsr & H_CBD) >> 24;
116
117 hw->pg_state = MEI_PG_OFF;
118}
119
120/**
121 * mei_me_pg_state - translate internal pg state
122 * to the mei power gating state
123 *
124 * @hw - me hardware
125 * returns: MEI_PG_OFF if aliveness is on and MEI_PG_ON otherwise
126 */
127static inline enum mei_pg_state mei_me_pg_state(struct mei_device *dev)
128{
129 struct mei_me_hw *hw = to_me_hw(dev);
130 return hw->pg_state;
115} 131}
132
116/** 133/**
117 * mei_clear_interrupts - clear and stop interrupts 134 * mei_clear_interrupts - clear and stop interrupts
118 * 135 *
@@ -164,6 +181,9 @@ static void mei_me_hw_reset_release(struct mei_device *dev)
164 hcsr |= H_IG; 181 hcsr |= H_IG;
165 hcsr &= ~H_RST; 182 hcsr &= ~H_RST;
166 mei_hcsr_set(hw, hcsr); 183 mei_hcsr_set(hw, hcsr);
184
185 /* complete this write before we set host ready on another CPU */
186 mmiowb();
167} 187}
168/** 188/**
169 * mei_me_hw_reset - resets fw via mei csr register. 189 * mei_me_hw_reset - resets fw via mei csr register.
@@ -183,8 +203,21 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
183 else 203 else
184 hcsr &= ~H_IE; 204 hcsr &= ~H_IE;
185 205
206 dev->recvd_hw_ready = false;
186 mei_me_reg_write(hw, H_CSR, hcsr); 207 mei_me_reg_write(hw, H_CSR, hcsr);
187 208
209 /*
210 * Host reads the H_CSR once to ensure that the
211 * posted write to H_CSR completes.
212 */
213 hcsr = mei_hcsr_read(hw);
214
215 if ((hcsr & H_RST) == 0)
216 dev_warn(&dev->pdev->dev, "H_RST is not set = 0x%08X", hcsr);
217
218 if ((hcsr & H_RDY) == H_RDY)
219 dev_warn(&dev->pdev->dev, "H_RDY is not cleared 0x%08X", hcsr);
220
188 if (intr_enable == false) 221 if (intr_enable == false)
189 mei_me_hw_reset_release(dev); 222 mei_me_hw_reset_release(dev);
190 223
@@ -201,6 +234,7 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
201static void mei_me_host_set_ready(struct mei_device *dev) 234static void mei_me_host_set_ready(struct mei_device *dev)
202{ 235{
203 struct mei_me_hw *hw = to_me_hw(dev); 236 struct mei_me_hw *hw = to_me_hw(dev);
237 hw->host_hw_state = mei_hcsr_read(hw);
204 hw->host_hw_state |= H_IE | H_IG | H_RDY; 238 hw->host_hw_state |= H_IE | H_IG | H_RDY;
205 mei_hcsr_set(hw, hw->host_hw_state); 239 mei_hcsr_set(hw, hw->host_hw_state);
206} 240}
@@ -233,10 +267,7 @@ static bool mei_me_hw_is_ready(struct mei_device *dev)
233static int mei_me_hw_ready_wait(struct mei_device *dev) 267static int mei_me_hw_ready_wait(struct mei_device *dev)
234{ 268{
235 int err; 269 int err;
236 if (mei_me_hw_is_ready(dev))
237 return 0;
238 270
239 dev->recvd_hw_ready = false;
240 mutex_unlock(&dev->device_lock); 271 mutex_unlock(&dev->device_lock);
241 err = wait_event_interruptible_timeout(dev->wait_hw_ready, 272 err = wait_event_interruptible_timeout(dev->wait_hw_ready,
242 dev->recvd_hw_ready, 273 dev->recvd_hw_ready,
@@ -431,6 +462,144 @@ static int mei_me_read_slots(struct mei_device *dev, unsigned char *buffer,
431} 462}
432 463
433/** 464/**
465 * mei_me_pg_enter - write pg enter register to mei device.
466 *
467 * @dev: the device structure
468 */
469static void mei_me_pg_enter(struct mei_device *dev)
470{
471 struct mei_me_hw *hw = to_me_hw(dev);
472 u32 reg = mei_me_reg_read(hw, H_HPG_CSR);
473 reg |= H_HPG_CSR_PGI;
474 mei_me_reg_write(hw, H_HPG_CSR, reg);
475}
476
477/**
478 * mei_me_pg_enter - write pg enter register to mei device.
479 *
480 * @dev: the device structure
481 */
482static void mei_me_pg_exit(struct mei_device *dev)
483{
484 struct mei_me_hw *hw = to_me_hw(dev);
485 u32 reg = mei_me_reg_read(hw, H_HPG_CSR);
486
487 WARN(!(reg & H_HPG_CSR_PGI), "PGI is not set\n");
488
489 reg |= H_HPG_CSR_PGIHEXR;
490 mei_me_reg_write(hw, H_HPG_CSR, reg);
491}
492
493/**
494 * mei_me_pg_set_sync - perform pg entry procedure
495 *
496 * @dev: the device structure
497 *
498 * returns 0 on success an error code otherwise
499 */
500int mei_me_pg_set_sync(struct mei_device *dev)
501{
502 struct mei_me_hw *hw = to_me_hw(dev);
503 unsigned long timeout = mei_secs_to_jiffies(MEI_PGI_TIMEOUT);
504 int ret;
505
506 dev->pg_event = MEI_PG_EVENT_WAIT;
507
508 ret = mei_hbm_pg(dev, MEI_PG_ISOLATION_ENTRY_REQ_CMD);
509 if (ret)
510 return ret;
511
512 mutex_unlock(&dev->device_lock);
513 wait_event_timeout(dev->wait_pg,
514 dev->pg_event == MEI_PG_EVENT_RECEIVED, timeout);
515 mutex_lock(&dev->device_lock);
516
517 if (dev->pg_event == MEI_PG_EVENT_RECEIVED) {
518 mei_me_pg_enter(dev);
519 ret = 0;
520 } else {
521 ret = -ETIME;
522 }
523
524 dev->pg_event = MEI_PG_EVENT_IDLE;
525 hw->pg_state = MEI_PG_ON;
526
527 return ret;
528}
529
530/**
531 * mei_me_pg_unset_sync - perform pg exit procedure
532 *
533 * @dev: the device structure
534 *
535 * returns 0 on success an error code otherwise
536 */
537int mei_me_pg_unset_sync(struct mei_device *dev)
538{
539 struct mei_me_hw *hw = to_me_hw(dev);
540 unsigned long timeout = mei_secs_to_jiffies(MEI_PGI_TIMEOUT);
541 int ret;
542
543 if (dev->pg_event == MEI_PG_EVENT_RECEIVED)
544 goto reply;
545
546 dev->pg_event = MEI_PG_EVENT_WAIT;
547
548 mei_me_pg_exit(dev);
549
550 mutex_unlock(&dev->device_lock);
551 wait_event_timeout(dev->wait_pg,
552 dev->pg_event == MEI_PG_EVENT_RECEIVED, timeout);
553 mutex_lock(&dev->device_lock);
554
555reply:
556 if (dev->pg_event == MEI_PG_EVENT_RECEIVED)
557 ret = mei_hbm_pg(dev, MEI_PG_ISOLATION_EXIT_RES_CMD);
558 else
559 ret = -ETIME;
560
561 dev->pg_event = MEI_PG_EVENT_IDLE;
562 hw->pg_state = MEI_PG_OFF;
563
564 return ret;
565}
566
567/**
568 * mei_me_pg_is_enabled - detect if PG is supported by HW
569 *
570 * @dev: the device structure
571 *
572 * returns: true is pg supported, false otherwise
573 */
574static bool mei_me_pg_is_enabled(struct mei_device *dev)
575{
576 struct mei_me_hw *hw = to_me_hw(dev);
577 u32 reg = mei_me_reg_read(hw, ME_CSR_HA);
578
579 if ((reg & ME_PGIC_HRA) == 0)
580 goto notsupported;
581
582 if (dev->version.major_version < HBM_MAJOR_VERSION_PGI)
583 goto notsupported;
584
585 if (dev->version.major_version == HBM_MAJOR_VERSION_PGI &&
586 dev->version.minor_version < HBM_MINOR_VERSION_PGI)
587 goto notsupported;
588
589 return true;
590
591notsupported:
592 dev_dbg(&dev->pdev->dev, "pg: not supported: HGP = %d hbm version %d.%d ?= %d.%d\n",
593 !!(reg & ME_PGIC_HRA),
594 dev->version.major_version,
595 dev->version.minor_version,
596 HBM_MAJOR_VERSION_PGI,
597 HBM_MINOR_VERSION_PGI);
598
599 return false;
600}
601
602/**
434 * mei_me_irq_quick_handler - The ISR of the MEI device 603 * mei_me_irq_quick_handler - The ISR of the MEI device
435 * 604 *
436 * @irq: The irq number 605 * @irq: The irq number
@@ -491,14 +660,13 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
491 /* check if we need to start the dev */ 660 /* check if we need to start the dev */
492 if (!mei_host_is_ready(dev)) { 661 if (!mei_host_is_ready(dev)) {
493 if (mei_hw_is_ready(dev)) { 662 if (mei_hw_is_ready(dev)) {
663 mei_me_hw_reset_release(dev);
494 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); 664 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
495 665
496 dev->recvd_hw_ready = true; 666 dev->recvd_hw_ready = true;
497 wake_up_interruptible(&dev->wait_hw_ready); 667 wake_up_interruptible(&dev->wait_hw_ready);
498 } else { 668 } else {
499 669 dev_dbg(&dev->pdev->dev, "Spurious Interrupt\n");
500 dev_dbg(&dev->pdev->dev, "Reset Completed.\n");
501 mei_me_hw_reset_release(dev);
502 } 670 }
503 goto end; 671 goto end;
504 } 672 }
@@ -524,9 +692,15 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
524 692
525 dev->hbuf_is_ready = mei_hbuf_is_ready(dev); 693 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
526 694
527 rets = mei_irq_write_handler(dev, &complete_list); 695 /*
528 696 * During PG handshake only allowed write is the replay to the
529 dev->hbuf_is_ready = mei_hbuf_is_ready(dev); 697 * PG exit message, so block calling write function
698 * if the pg state is not idle
699 */
700 if (dev->pg_event == MEI_PG_EVENT_IDLE) {
701 rets = mei_irq_write_handler(dev, &complete_list);
702 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
703 }
530 704
531 mei_irq_compl_handler(dev, &complete_list); 705 mei_irq_compl_handler(dev, &complete_list);
532 706
@@ -535,8 +709,65 @@ end:
535 mutex_unlock(&dev->device_lock); 709 mutex_unlock(&dev->device_lock);
536 return IRQ_HANDLED; 710 return IRQ_HANDLED;
537} 711}
712
713/**
714 * mei_me_fw_status - retrieve fw status from the pci config space
715 *
716 * @dev: the device structure
717 * @fw_status: fw status registers storage
718 *
719 * returns 0 on success an error code otherwise
720 */
721static int mei_me_fw_status(struct mei_device *dev,
722 struct mei_fw_status *fw_status)
723{
724 const u32 pci_cfg_reg[] = {PCI_CFG_HFS_1, PCI_CFG_HFS_2};
725 int i;
726
727 if (!fw_status)
728 return -EINVAL;
729
730 switch (dev->pdev->device) {
731 case MEI_DEV_ID_IBXPK_1:
732 case MEI_DEV_ID_IBXPK_2:
733 case MEI_DEV_ID_CPT_1:
734 case MEI_DEV_ID_PBG_1:
735 case MEI_DEV_ID_PPT_1:
736 case MEI_DEV_ID_PPT_2:
737 case MEI_DEV_ID_PPT_3:
738 case MEI_DEV_ID_LPT_H:
739 case MEI_DEV_ID_LPT_W:
740 case MEI_DEV_ID_LPT_LP:
741 case MEI_DEV_ID_LPT_HR:
742 case MEI_DEV_ID_WPT_LP:
743 fw_status->count = 2;
744 break;
745 case MEI_DEV_ID_ICH10_1:
746 case MEI_DEV_ID_ICH10_2:
747 case MEI_DEV_ID_ICH10_3:
748 case MEI_DEV_ID_ICH10_4:
749 fw_status->count = 1;
750 break;
751 default:
752 fw_status->count = 0;
753 break;
754 }
755
756 for (i = 0; i < fw_status->count && i < MEI_FW_STATUS_MAX; i++) {
757 int ret;
758 ret = pci_read_config_dword(dev->pdev,
759 pci_cfg_reg[i], &fw_status->status[i]);
760 if (ret)
761 return ret;
762 }
763 return 0;
764}
765
538static const struct mei_hw_ops mei_me_hw_ops = { 766static const struct mei_hw_ops mei_me_hw_ops = {
539 767
768 .pg_state = mei_me_pg_state,
769
770 .fw_status = mei_me_fw_status,
540 .host_is_ready = mei_me_host_is_ready, 771 .host_is_ready = mei_me_host_is_ready,
541 772
542 .hw_is_ready = mei_me_hw_is_ready, 773 .hw_is_ready = mei_me_hw_is_ready,
@@ -544,6 +775,8 @@ static const struct mei_hw_ops mei_me_hw_ops = {
544 .hw_config = mei_me_hw_config, 775 .hw_config = mei_me_hw_config,
545 .hw_start = mei_me_hw_start, 776 .hw_start = mei_me_hw_start,
546 777
778 .pg_is_enabled = mei_me_pg_is_enabled,
779
547 .intr_clear = mei_me_intr_clear, 780 .intr_clear = mei_me_intr_clear,
548 .intr_enable = mei_me_intr_enable, 781 .intr_enable = mei_me_intr_enable,
549 .intr_disable = mei_me_intr_disable, 782 .intr_disable = mei_me_intr_disable,
@@ -559,14 +792,81 @@ static const struct mei_hw_ops mei_me_hw_ops = {
559 .read = mei_me_read_slots 792 .read = mei_me_read_slots
560}; 793};
561 794
795static bool mei_me_fw_type_nm(struct pci_dev *pdev)
796{
797 u32 reg;
798 pci_read_config_dword(pdev, PCI_CFG_HFS_2, &reg);
799 /* make sure that bit 9 (NM) is up and bit 10 (DM) is down */
800 return (reg & 0x600) == 0x200;
801}
802
803#define MEI_CFG_FW_NM \
804 .quirk_probe = mei_me_fw_type_nm
805
806static bool mei_me_fw_type_sps(struct pci_dev *pdev)
807{
808 u32 reg;
809 /* Read ME FW Status check for SPS Firmware */
810 pci_read_config_dword(pdev, PCI_CFG_HFS_1, &reg);
811 /* if bits [19:16] = 15, running SPS Firmware */
812 return (reg & 0xf0000) == 0xf0000;
813}
814
815#define MEI_CFG_FW_SPS \
816 .quirk_probe = mei_me_fw_type_sps
817
818
819#define MEI_CFG_LEGACY_HFS \
820 .fw_status.count = 0
821
822#define MEI_CFG_ICH_HFS \
823 .fw_status.count = 1, \
824 .fw_status.status[0] = PCI_CFG_HFS_1
825
826#define MEI_CFG_PCH_HFS \
827 .fw_status.count = 2, \
828 .fw_status.status[0] = PCI_CFG_HFS_1, \
829 .fw_status.status[1] = PCI_CFG_HFS_2
830
831
832/* ICH Legacy devices */
833const struct mei_cfg mei_me_legacy_cfg = {
834 MEI_CFG_LEGACY_HFS,
835};
836
837/* ICH devices */
838const struct mei_cfg mei_me_ich_cfg = {
839 MEI_CFG_ICH_HFS,
840};
841
842/* PCH devices */
843const struct mei_cfg mei_me_pch_cfg = {
844 MEI_CFG_PCH_HFS,
845};
846
847
848/* PCH Cougar Point and Patsburg with quirk for Node Manager exclusion */
849const struct mei_cfg mei_me_pch_cpt_pbg_cfg = {
850 MEI_CFG_PCH_HFS,
851 MEI_CFG_FW_NM,
852};
853
854/* PCH Lynx Point with quirk for SPS Firmware exclusion */
855const struct mei_cfg mei_me_lpt_cfg = {
856 MEI_CFG_PCH_HFS,
857 MEI_CFG_FW_SPS,
858};
859
562/** 860/**
563 * mei_me_dev_init - allocates and initializes the mei device structure 861 * mei_me_dev_init - allocates and initializes the mei device structure
564 * 862 *
565 * @pdev: The pci device structure 863 * @pdev: The pci device structure
864 * @cfg: per device generation config
566 * 865 *
567 * returns The mei_device_device pointer on success, NULL on failure. 866 * returns The mei_device_device pointer on success, NULL on failure.
568 */ 867 */
569struct mei_device *mei_me_dev_init(struct pci_dev *pdev) 868struct mei_device *mei_me_dev_init(struct pci_dev *pdev,
869 const struct mei_cfg *cfg)
570{ 870{
571 struct mei_device *dev; 871 struct mei_device *dev;
572 872
@@ -575,7 +875,7 @@ struct mei_device *mei_me_dev_init(struct pci_dev *pdev)
575 if (!dev) 875 if (!dev)
576 return NULL; 876 return NULL;
577 877
578 mei_device_init(dev); 878 mei_device_init(dev, cfg);
579 879
580 dev->ops = &mei_me_hw_ops; 880 dev->ops = &mei_me_hw_ops;
581 881
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
index 893d5119fa9b..12b0f4bbe1f1 100644
--- a/drivers/misc/mei/hw-me.h
+++ b/drivers/misc/mei/hw-me.h
@@ -24,6 +24,8 @@
24#include "mei_dev.h" 24#include "mei_dev.h"
25#include "client.h" 25#include "client.h"
26 26
27#define MEI_ME_RPM_TIMEOUT 500 /* ms */
28
27struct mei_me_hw { 29struct mei_me_hw {
28 void __iomem *mem_addr; 30 void __iomem *mem_addr;
29 /* 31 /*
@@ -31,11 +33,22 @@ struct mei_me_hw {
31 */ 33 */
32 u32 host_hw_state; 34 u32 host_hw_state;
33 u32 me_hw_state; 35 u32 me_hw_state;
36 enum mei_pg_state pg_state;
34}; 37};
35 38
36#define to_me_hw(dev) (struct mei_me_hw *)((dev)->hw) 39#define to_me_hw(dev) (struct mei_me_hw *)((dev)->hw)
37 40
38struct mei_device *mei_me_dev_init(struct pci_dev *pdev); 41extern const struct mei_cfg mei_me_legacy_cfg;
42extern const struct mei_cfg mei_me_ich_cfg;
43extern const struct mei_cfg mei_me_pch_cfg;
44extern const struct mei_cfg mei_me_pch_cpt_pbg_cfg;
45extern const struct mei_cfg mei_me_lpt_cfg;
46
47struct mei_device *mei_me_dev_init(struct pci_dev *pdev,
48 const struct mei_cfg *cfg);
49
50int mei_me_pg_set_sync(struct mei_device *dev);
51int mei_me_pg_unset_sync(struct mei_device *dev);
39 52
40irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id); 53irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id);
41irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id); 54irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id);
diff --git a/drivers/misc/mei/hw-txe-regs.h b/drivers/misc/mei/hw-txe-regs.h
index 7283c24c1af1..f19229c4e655 100644
--- a/drivers/misc/mei/hw-txe-regs.h
+++ b/drivers/misc/mei/hw-txe-regs.h
@@ -89,7 +89,7 @@ enum {
89# define PCI_CFG_TXE_FW_STS0_ERR_CODE_MSK 0x0000F000 89# define PCI_CFG_TXE_FW_STS0_ERR_CODE_MSK 0x0000F000
90# define PCI_CFG_TXE_FW_STS0_OP_MODE_MSK 0x000F0000 90# define PCI_CFG_TXE_FW_STS0_OP_MODE_MSK 0x000F0000
91# define PCI_CFG_TXE_FW_STS0_RST_CNT_MSK 0x00F00000 91# define PCI_CFG_TXE_FW_STS0_RST_CNT_MSK 0x00F00000
92 92#define PCI_CFG_TXE_FW_STS1 0x48
93 93
94#define IPC_BASE_ADDR 0x80400 /* SeC IPC Base Address */ 94#define IPC_BASE_ADDR 0x80400 /* SeC IPC Base Address */
95 95
diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c
index f60182a52f96..93273783dec5 100644
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -158,7 +158,7 @@ static bool mei_txe_aliveness_set(struct mei_device *dev, u32 req)
158 dev_dbg(&dev->pdev->dev, "Aliveness current=%d request=%d\n", 158 dev_dbg(&dev->pdev->dev, "Aliveness current=%d request=%d\n",
159 hw->aliveness, req); 159 hw->aliveness, req);
160 if (do_req) { 160 if (do_req) {
161 hw->recvd_aliveness = false; 161 dev->pg_event = MEI_PG_EVENT_WAIT;
162 mei_txe_br_reg_write(hw, SICR_HOST_ALIVENESS_REQ_REG, req); 162 mei_txe_br_reg_write(hw, SICR_HOST_ALIVENESS_REQ_REG, req);
163 } 163 }
164 return do_req; 164 return do_req;
@@ -213,6 +213,7 @@ static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected)
213 do { 213 do {
214 hw->aliveness = mei_txe_aliveness_get(dev); 214 hw->aliveness = mei_txe_aliveness_get(dev);
215 if (hw->aliveness == expected) { 215 if (hw->aliveness == expected) {
216 dev->pg_event = MEI_PG_EVENT_IDLE;
216 dev_dbg(&dev->pdev->dev, 217 dev_dbg(&dev->pdev->dev,
217 "aliveness settled after %d msecs\n", t); 218 "aliveness settled after %d msecs\n", t);
218 return t; 219 return t;
@@ -223,6 +224,7 @@ static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected)
223 t += MSEC_PER_SEC / 5; 224 t += MSEC_PER_SEC / 5;
224 } while (t < SEC_ALIVENESS_WAIT_TIMEOUT); 225 } while (t < SEC_ALIVENESS_WAIT_TIMEOUT);
225 226
227 dev->pg_event = MEI_PG_EVENT_IDLE;
226 dev_err(&dev->pdev->dev, "aliveness timed out\n"); 228 dev_err(&dev->pdev->dev, "aliveness timed out\n");
227 return -ETIME; 229 return -ETIME;
228} 230}
@@ -249,19 +251,22 @@ static int mei_txe_aliveness_wait(struct mei_device *dev, u32 expected)
249 return 0; 251 return 0;
250 252
251 mutex_unlock(&dev->device_lock); 253 mutex_unlock(&dev->device_lock);
252 err = wait_event_timeout(hw->wait_aliveness, 254 err = wait_event_timeout(hw->wait_aliveness_resp,
253 hw->recvd_aliveness, timeout); 255 dev->pg_event == MEI_PG_EVENT_RECEIVED, timeout);
254 mutex_lock(&dev->device_lock); 256 mutex_lock(&dev->device_lock);
255 257
256 hw->aliveness = mei_txe_aliveness_get(dev); 258 hw->aliveness = mei_txe_aliveness_get(dev);
257 ret = hw->aliveness == expected ? 0 : -ETIME; 259 ret = hw->aliveness == expected ? 0 : -ETIME;
258 260
259 if (ret) 261 if (ret)
260 dev_err(&dev->pdev->dev, "aliveness timed out"); 262 dev_warn(&dev->pdev->dev, "aliveness timed out = %ld aliveness = %d event = %d\n",
263 err, hw->aliveness, dev->pg_event);
261 else 264 else
262 dev_dbg(&dev->pdev->dev, "aliveness settled after %d msecs\n", 265 dev_dbg(&dev->pdev->dev, "aliveness settled after = %d msec aliveness = %d event = %d\n",
263 jiffies_to_msecs(timeout - err)); 266 jiffies_to_msecs(timeout - err),
264 hw->recvd_aliveness = false; 267 hw->aliveness, dev->pg_event);
268
269 dev->pg_event = MEI_PG_EVENT_IDLE;
265 return ret; 270 return ret;
266} 271}
267 272
@@ -280,6 +285,32 @@ int mei_txe_aliveness_set_sync(struct mei_device *dev, u32 req)
280} 285}
281 286
282/** 287/**
288 * mei_txe_pg_is_enabled - detect if PG is supported by HW
289 *
290 * @dev: the device structure
291 *
292 * returns: true is pg supported, false otherwise
293 */
294static bool mei_txe_pg_is_enabled(struct mei_device *dev)
295{
296 return true;
297}
298
299/**
300 * mei_txe_pg_state - translate aliveness register value
301 * to the mei power gating state
302 *
303 * @dev: the device structure
304 *
305 * returns: MEI_PG_OFF if aliveness is on and MEI_PG_ON otherwise
306 */
307static inline enum mei_pg_state mei_txe_pg_state(struct mei_device *dev)
308{
309 struct mei_txe_hw *hw = to_txe_hw(dev);
310 return hw->aliveness ? MEI_PG_OFF : MEI_PG_ON;
311}
312
313/**
283 * mei_txe_input_ready_interrupt_enable - sets the Input Ready Interrupt 314 * mei_txe_input_ready_interrupt_enable - sets the Input Ready Interrupt
284 * 315 *
285 * @dev: the device structure 316 * @dev: the device structure
@@ -589,7 +620,10 @@ static int mei_txe_write(struct mei_device *dev,
589 mei_txe_input_ready_interrupt_enable(dev); 620 mei_txe_input_ready_interrupt_enable(dev);
590 621
591 if (!mei_txe_is_input_ready(dev)) { 622 if (!mei_txe_is_input_ready(dev)) {
592 dev_err(&dev->pdev->dev, "Input is not ready"); 623 struct mei_fw_status fw_status;
624 mei_fw_status(dev, &fw_status);
625 dev_err(&dev->pdev->dev, "Input is not ready " FW_STS_FMT "\n",
626 FW_STS_PRM(fw_status));
593 return -EAGAIN; 627 return -EAGAIN;
594 } 628 }
595 629
@@ -960,9 +994,9 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id)
960 /* Clear the interrupt cause */ 994 /* Clear the interrupt cause */
961 dev_dbg(&dev->pdev->dev, 995 dev_dbg(&dev->pdev->dev,
962 "Aliveness Interrupt: Status: %d\n", hw->aliveness); 996 "Aliveness Interrupt: Status: %d\n", hw->aliveness);
963 hw->recvd_aliveness = true; 997 dev->pg_event = MEI_PG_EVENT_RECEIVED;
964 if (waitqueue_active(&hw->wait_aliveness)) 998 if (waitqueue_active(&hw->wait_aliveness_resp))
965 wake_up(&hw->wait_aliveness); 999 wake_up(&hw->wait_aliveness_resp);
966 } 1000 }
967 1001
968 1002
@@ -1008,15 +1042,51 @@ end:
1008 return IRQ_HANDLED; 1042 return IRQ_HANDLED;
1009} 1043}
1010 1044
1045
1046/**
1047 * mei_txe_fw_status - retrieve fw status from the pci config space
1048 *
1049 * @dev: the device structure
1050 * @fw_status: fw status registers storage
1051 *
1052 * returns: 0 on success an error code otherwise
1053 */
1054static int mei_txe_fw_status(struct mei_device *dev,
1055 struct mei_fw_status *fw_status)
1056{
1057 const u32 pci_cfg_reg[] = {PCI_CFG_TXE_FW_STS0, PCI_CFG_TXE_FW_STS1};
1058 int i;
1059
1060 if (!fw_status)
1061 return -EINVAL;
1062
1063 fw_status->count = 2;
1064
1065 for (i = 0; i < fw_status->count && i < MEI_FW_STATUS_MAX; i++) {
1066 int ret;
1067 ret = pci_read_config_dword(dev->pdev,
1068 pci_cfg_reg[i], &fw_status->status[i]);
1069 if (ret)
1070 return ret;
1071 }
1072
1073 return 0;
1074}
1075
1011static const struct mei_hw_ops mei_txe_hw_ops = { 1076static const struct mei_hw_ops mei_txe_hw_ops = {
1012 1077
1078 .fw_status = mei_txe_fw_status,
1013 .host_is_ready = mei_txe_host_is_ready, 1079 .host_is_ready = mei_txe_host_is_ready,
1014 1080
1081 .pg_state = mei_txe_pg_state,
1082
1015 .hw_is_ready = mei_txe_hw_is_ready, 1083 .hw_is_ready = mei_txe_hw_is_ready,
1016 .hw_reset = mei_txe_hw_reset, 1084 .hw_reset = mei_txe_hw_reset,
1017 .hw_config = mei_txe_hw_config, 1085 .hw_config = mei_txe_hw_config,
1018 .hw_start = mei_txe_hw_start, 1086 .hw_start = mei_txe_hw_start,
1019 1087
1088 .pg_is_enabled = mei_txe_pg_is_enabled,
1089
1020 .intr_clear = mei_txe_intr_clear, 1090 .intr_clear = mei_txe_intr_clear,
1021 .intr_enable = mei_txe_intr_enable, 1091 .intr_enable = mei_txe_intr_enable,
1022 .intr_disable = mei_txe_intr_disable, 1092 .intr_disable = mei_txe_intr_disable,
@@ -1034,14 +1104,27 @@ static const struct mei_hw_ops mei_txe_hw_ops = {
1034 1104
1035}; 1105};
1036 1106
1107#define MEI_CFG_TXE_FW_STS \
1108 .fw_status.count = 2, \
1109 .fw_status.status[0] = PCI_CFG_TXE_FW_STS0, \
1110 .fw_status.status[1] = PCI_CFG_TXE_FW_STS1
1111
1112const struct mei_cfg mei_txe_cfg = {
1113 MEI_CFG_TXE_FW_STS,
1114};
1115
1116
1037/** 1117/**
1038 * mei_txe_dev_init - allocates and initializes txe hardware specific structure 1118 * mei_txe_dev_init - allocates and initializes txe hardware specific structure
1039 * 1119 *
1040 * @pdev - pci device 1120 * @pdev - pci device
1121 * @cfg - per device generation config
1122 *
1041 * returns struct mei_device * on success or NULL; 1123 * returns struct mei_device * on success or NULL;
1042 * 1124 *
1043 */ 1125 */
1044struct mei_device *mei_txe_dev_init(struct pci_dev *pdev) 1126struct mei_device *mei_txe_dev_init(struct pci_dev *pdev,
1127 const struct mei_cfg *cfg)
1045{ 1128{
1046 struct mei_device *dev; 1129 struct mei_device *dev;
1047 struct mei_txe_hw *hw; 1130 struct mei_txe_hw *hw;
@@ -1051,11 +1134,11 @@ struct mei_device *mei_txe_dev_init(struct pci_dev *pdev)
1051 if (!dev) 1134 if (!dev)
1052 return NULL; 1135 return NULL;
1053 1136
1054 mei_device_init(dev); 1137 mei_device_init(dev, cfg);
1055 1138
1056 hw = to_txe_hw(dev); 1139 hw = to_txe_hw(dev);
1057 1140
1058 init_waitqueue_head(&hw->wait_aliveness); 1141 init_waitqueue_head(&hw->wait_aliveness_resp);
1059 1142
1060 dev->ops = &mei_txe_hw_ops; 1143 dev->ops = &mei_txe_hw_ops;
1061 1144
diff --git a/drivers/misc/mei/hw-txe.h b/drivers/misc/mei/hw-txe.h
index 0812d98633a4..e244af79167f 100644
--- a/drivers/misc/mei/hw-txe.h
+++ b/drivers/misc/mei/hw-txe.h
@@ -22,6 +22,8 @@
22#include "hw.h" 22#include "hw.h"
23#include "hw-txe-regs.h" 23#include "hw-txe-regs.h"
24 24
25#define MEI_TXI_RPM_TIMEOUT 500 /* ms */
26
25/* Flatten Hierarchy interrupt cause */ 27/* Flatten Hierarchy interrupt cause */
26#define TXE_INTR_READINESS_BIT 0 /* HISR_INT_0_STS */ 28#define TXE_INTR_READINESS_BIT 0 /* HISR_INT_0_STS */
27#define TXE_INTR_READINESS HISR_INT_0_STS 29#define TXE_INTR_READINESS HISR_INT_0_STS
@@ -35,12 +37,11 @@
35/** 37/**
36 * struct mei_txe_hw - txe hardware specifics 38 * struct mei_txe_hw - txe hardware specifics
37 * 39 *
38 * @mem_addr: SeC and BRIDGE bars 40 * @mem_addr: SeC and BRIDGE bars
39 * @aliveness: aliveness (power gating) state of the hardware 41 * @aliveness: aliveness (power gating) state of the hardware
40 * @readiness: readiness state of the hardware 42 * @readiness: readiness state of the hardware
41 * @wait_aliveness: aliveness wait queue 43 * @wait_aliveness_resp: aliveness wait queue
42 * @recvd_aliveness: aliveness interrupt was recived 44 * @intr_cause: translated interrupt cause
43 * @intr_cause: translated interrupt cause
44 */ 45 */
45struct mei_txe_hw { 46struct mei_txe_hw {
46 void __iomem *mem_addr[NUM_OF_MEM_BARS]; 47 void __iomem *mem_addr[NUM_OF_MEM_BARS];
@@ -48,8 +49,7 @@ struct mei_txe_hw {
48 u32 readiness; 49 u32 readiness;
49 u32 slots; 50 u32 slots;
50 51
51 wait_queue_head_t wait_aliveness; 52 wait_queue_head_t wait_aliveness_resp;
52 bool recvd_aliveness;
53 53
54 unsigned long intr_cause; 54 unsigned long intr_cause;
55}; 55};
@@ -61,7 +61,10 @@ static inline struct mei_device *hw_txe_to_mei(struct mei_txe_hw *hw)
61 return container_of((void *)hw, struct mei_device, hw); 61 return container_of((void *)hw, struct mei_device, hw);
62} 62}
63 63
64struct mei_device *mei_txe_dev_init(struct pci_dev *pdev); 64extern const struct mei_cfg mei_txe_cfg;
65
66struct mei_device *mei_txe_dev_init(struct pci_dev *pdev,
67 const struct mei_cfg *cfg);
65 68
66irqreturn_t mei_txe_irq_quick_handler(int irq, void *dev_id); 69irqreturn_t mei_txe_irq_quick_handler(int irq, void *dev_id);
67irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id); 70irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id);
diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h
index 6b476ab49b2e..dd448e58cc87 100644
--- a/drivers/misc/mei/hw.h
+++ b/drivers/misc/mei/hw.h
@@ -31,14 +31,21 @@
31#define MEI_IAMTHIF_STALL_TIMER 12 /* HPS */ 31#define MEI_IAMTHIF_STALL_TIMER 12 /* HPS */
32#define MEI_IAMTHIF_READ_TIMER 10 /* HPS */ 32#define MEI_IAMTHIF_READ_TIMER 10 /* HPS */
33 33
34#define MEI_PGI_TIMEOUT 1 /* PG Isolation time response 1 sec */
34#define MEI_HBM_TIMEOUT 1 /* 1 second */ 35#define MEI_HBM_TIMEOUT 1 /* 1 second */
35 36
36/* 37/*
37 * MEI Version 38 * MEI Version
38 */ 39 */
39#define HBM_MINOR_VERSION 0 40#define HBM_MINOR_VERSION 1
40#define HBM_MAJOR_VERSION 1 41#define HBM_MAJOR_VERSION 1
41 42
43/*
44 * MEI version with PGI support
45 */
46#define HBM_MINOR_VERSION_PGI 1
47#define HBM_MAJOR_VERSION_PGI 1
48
42/* Host bus message command opcode */ 49/* Host bus message command opcode */
43#define MEI_HBM_CMD_OP_MSK 0x7f 50#define MEI_HBM_CMD_OP_MSK 0x7f
44/* Host bus message command RESPONSE */ 51/* Host bus message command RESPONSE */
@@ -69,6 +76,11 @@
69 76
70#define MEI_FLOW_CONTROL_CMD 0x08 77#define MEI_FLOW_CONTROL_CMD 0x08
71 78
79#define MEI_PG_ISOLATION_ENTRY_REQ_CMD 0x0a
80#define MEI_PG_ISOLATION_ENTRY_RES_CMD 0x8a
81#define MEI_PG_ISOLATION_EXIT_REQ_CMD 0x0b
82#define MEI_PG_ISOLATION_EXIT_RES_CMD 0x8b
83
72/* 84/*
73 * MEI Stop Reason 85 * MEI Stop Reason
74 * used by hbm_host_stop_request.reason 86 * used by hbm_host_stop_request.reason
@@ -208,6 +220,17 @@ struct hbm_props_response {
208} __packed; 220} __packed;
209 221
210/** 222/**
223 * struct hbm_power_gate - power gate request/response
224 *
225 * @hbm_cmd - bus message command header
226 * @reserved[3]
227 */
228struct hbm_power_gate {
229 u8 hbm_cmd;
230 u8 reserved[3];
231} __packed;
232
233/**
211 * struct hbm_client_connect_request - connect/disconnect request 234 * struct hbm_client_connect_request - connect/disconnect request
212 * 235 *
213 * @hbm_cmd - bus message command header 236 * @hbm_cmd - bus message command header
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 4460975c0eef..006929222481 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -74,9 +74,13 @@ int mei_reset(struct mei_device *dev)
74 if (state != MEI_DEV_INITIALIZING && 74 if (state != MEI_DEV_INITIALIZING &&
75 state != MEI_DEV_DISABLED && 75 state != MEI_DEV_DISABLED &&
76 state != MEI_DEV_POWER_DOWN && 76 state != MEI_DEV_POWER_DOWN &&
77 state != MEI_DEV_POWER_UP) 77 state != MEI_DEV_POWER_UP) {
78 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n", 78 struct mei_fw_status fw_status;
79 mei_dev_state_str(state)); 79 mei_fw_status(dev, &fw_status);
80 dev_warn(&dev->pdev->dev,
81 "unexpected reset: dev_state = %s " FW_STS_FMT "\n",
82 mei_dev_state_str(state), FW_STS_PRM(fw_status));
83 }
80 84
81 /* we're already in reset, cancel the init timer 85 /* we're already in reset, cancel the init timer
82 * if the reset was called due the hbm protocol error 86 * if the reset was called due the hbm protocol error
@@ -118,8 +122,8 @@ int mei_reset(struct mei_device *dev)
118 mei_amthif_reset_params(dev); 122 mei_amthif_reset_params(dev);
119 } 123 }
120 124
125 mei_hbm_reset(dev);
121 126
122 dev->me_clients_num = 0;
123 dev->rd_msg_hdr = 0; 127 dev->rd_msg_hdr = 0;
124 dev->wd_pending = false; 128 dev->wd_pending = false;
125 129
@@ -303,15 +307,58 @@ void mei_stop(struct mei_device *dev)
303} 307}
304EXPORT_SYMBOL_GPL(mei_stop); 308EXPORT_SYMBOL_GPL(mei_stop);
305 309
310/**
311 * mei_write_is_idle - check if the write queues are idle
312 *
313 * @dev: the device structure
314 *
315 * returns true of there is no pending write
316 */
317bool mei_write_is_idle(struct mei_device *dev)
318{
319 bool idle = (dev->dev_state == MEI_DEV_ENABLED &&
320 list_empty(&dev->ctrl_wr_list.list) &&
321 list_empty(&dev->write_list.list));
306 322
323 dev_dbg(&dev->pdev->dev, "write pg: is idle[%d] state=%s ctrl=%d write=%d\n",
324 idle,
325 mei_dev_state_str(dev->dev_state),
326 list_empty(&dev->ctrl_wr_list.list),
327 list_empty(&dev->write_list.list));
307 328
308void mei_device_init(struct mei_device *dev) 329 return idle;
330}
331EXPORT_SYMBOL_GPL(mei_write_is_idle);
332
333int mei_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status)
334{
335 int i;
336 const struct mei_fw_status *fw_src = &dev->cfg->fw_status;
337
338 if (!fw_status)
339 return -EINVAL;
340
341 fw_status->count = fw_src->count;
342 for (i = 0; i < fw_src->count && i < MEI_FW_STATUS_MAX; i++) {
343 int ret;
344 ret = pci_read_config_dword(dev->pdev,
345 fw_src->status[i], &fw_status->status[i]);
346 if (ret)
347 return ret;
348 }
349
350 return 0;
351}
352EXPORT_SYMBOL_GPL(mei_fw_status);
353
354void mei_device_init(struct mei_device *dev, const struct mei_cfg *cfg)
309{ 355{
310 /* setup our list array */ 356 /* setup our list array */
311 INIT_LIST_HEAD(&dev->file_list); 357 INIT_LIST_HEAD(&dev->file_list);
312 INIT_LIST_HEAD(&dev->device_list); 358 INIT_LIST_HEAD(&dev->device_list);
313 mutex_init(&dev->device_lock); 359 mutex_init(&dev->device_lock);
314 init_waitqueue_head(&dev->wait_hw_ready); 360 init_waitqueue_head(&dev->wait_hw_ready);
361 init_waitqueue_head(&dev->wait_pg);
315 init_waitqueue_head(&dev->wait_recvd_msg); 362 init_waitqueue_head(&dev->wait_recvd_msg);
316 init_waitqueue_head(&dev->wait_stop_wd); 363 init_waitqueue_head(&dev->wait_stop_wd);
317 dev->dev_state = MEI_DEV_INITIALIZING; 364 dev->dev_state = MEI_DEV_INITIALIZING;
@@ -340,6 +387,9 @@ void mei_device_init(struct mei_device *dev)
340 * 0: Reserved for MEI Bus Message communications 387 * 0: Reserved for MEI Bus Message communications
341 */ 388 */
342 bitmap_set(dev->host_clients_map, 0, 1); 389 bitmap_set(dev->host_clients_map, 0, 1);
390
391 dev->pg_event = MEI_PG_EVENT_IDLE;
392 dev->cfg = cfg;
343} 393}
344EXPORT_SYMBOL_GPL(mei_device_init); 394EXPORT_SYMBOL_GPL(mei_device_init);
345 395
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 147413145c97..66f0a1a06451 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -467,7 +467,6 @@ static int mei_ioctl_connect_client(struct file *file,
467 } 467 }
468 468
469 cl->me_client_id = dev->me_clients[i].client_id; 469 cl->me_client_id = dev->me_clients[i].client_id;
470 cl->state = MEI_FILE_CONNECTING;
471 470
472 dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n", 471 dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
473 cl->me_client_id); 472 cl->me_client_id);
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 94a516716d22..5c7e990e2f22 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -153,6 +153,20 @@ struct mei_msg_data {
153 unsigned char *data; 153 unsigned char *data;
154}; 154};
155 155
156/* Maximum number of processed FW status registers */
157#define MEI_FW_STATUS_MAX 2
158
159/*
160 * struct mei_fw_status - storage of FW status data
161 *
162 * @count - number of actually available elements in array
163 * @status - FW status registers
164 */
165struct mei_fw_status {
166 int count;
167 u32 status[MEI_FW_STATUS_MAX];
168};
169
156/** 170/**
157 * struct mei_me_client - representation of me (fw) client 171 * struct mei_me_client - representation of me (fw) client
158 * 172 *
@@ -213,6 +227,7 @@ struct mei_cl {
213 227
214/** struct mei_hw_ops 228/** struct mei_hw_ops
215 * 229 *
230 * @fw_status - read FW status from PCI config space
216 * @host_is_ready - query for host readiness 231 * @host_is_ready - query for host readiness
217 232
218 * @hw_is_ready - query if hw is ready 233 * @hw_is_ready - query if hw is ready
@@ -220,6 +235,9 @@ struct mei_cl {
220 * @hw_start - start hw after reset 235 * @hw_start - start hw after reset
221 * @hw_config - configure hw 236 * @hw_config - configure hw
222 237
238 * @pg_state - power gating state of the device
239 * @pg_is_enabled - is power gating enabled
240
223 * @intr_clear - clear pending interrupts 241 * @intr_clear - clear pending interrupts
224 * @intr_enable - enable interrupts 242 * @intr_enable - enable interrupts
225 * @intr_disable - disable interrupts 243 * @intr_disable - disable interrupts
@@ -237,6 +255,8 @@ struct mei_cl {
237 */ 255 */
238struct mei_hw_ops { 256struct mei_hw_ops {
239 257
258 int (*fw_status)(struct mei_device *dev,
259 struct mei_fw_status *fw_status);
240 bool (*host_is_ready)(struct mei_device *dev); 260 bool (*host_is_ready)(struct mei_device *dev);
241 261
242 bool (*hw_is_ready)(struct mei_device *dev); 262 bool (*hw_is_ready)(struct mei_device *dev);
@@ -244,6 +264,9 @@ struct mei_hw_ops {
244 int (*hw_start)(struct mei_device *dev); 264 int (*hw_start)(struct mei_device *dev);
245 void (*hw_config)(struct mei_device *dev); 265 void (*hw_config)(struct mei_device *dev);
246 266
267 enum mei_pg_state (*pg_state)(struct mei_device *dev);
268 bool (*pg_is_enabled)(struct mei_device *dev);
269
247 void (*intr_clear)(struct mei_device *dev); 270 void (*intr_clear)(struct mei_device *dev);
248 void (*intr_enable)(struct mei_device *dev); 271 void (*intr_enable)(struct mei_device *dev);
249 void (*intr_disable)(struct mei_device *dev); 272 void (*intr_disable)(struct mei_device *dev);
@@ -331,16 +354,61 @@ struct mei_cl_device {
331 void *priv_data; 354 void *priv_data;
332}; 355};
333 356
357
358 /**
359 * enum mei_pg_event - power gating transition events
360 *
361 * @MEI_PG_EVENT_IDLE: the driver is not in power gating transition
362 * @MEI_PG_EVENT_WAIT: the driver is waiting for a pg event to complete
363 * @MEI_PG_EVENT_RECEIVED: the driver received pg event
364 */
365enum mei_pg_event {
366 MEI_PG_EVENT_IDLE,
367 MEI_PG_EVENT_WAIT,
368 MEI_PG_EVENT_RECEIVED,
369};
370
371/**
372 * enum mei_pg_state - device internal power gating state
373 *
374 * @MEI_PG_OFF: device is not power gated - it is active
375 * @MEI_PG_ON: device is power gated - it is in lower power state
376 */
377enum mei_pg_state {
378 MEI_PG_OFF = 0,
379 MEI_PG_ON = 1,
380};
381
382/*
383 * mei_cfg
384 *
385 * @fw_status - FW status
386 * @quirk_probe - device exclusion quirk
387 */
388struct mei_cfg {
389 const struct mei_fw_status fw_status;
390 bool (*quirk_probe)(struct pci_dev *pdev);
391};
392
393
394#define MEI_PCI_DEVICE(dev, cfg) \
395 .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
396 .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, \
397 .driver_data = (kernel_ulong_t)&(cfg)
398
399
334/** 400/**
335 * struct mei_device - MEI private device struct 401 * struct mei_device - MEI private device struct
336 402
337 * @reset_count - limits the number of consecutive resets 403 * @reset_count - limits the number of consecutive resets
338 * @hbm_state - state of host bus message protocol 404 * @hbm_state - state of host bus message protocol
405 * @pg_event - power gating event
339 * @mem_addr - mem mapped base register address 406 * @mem_addr - mem mapped base register address
340 407
341 * @hbuf_depth - depth of hardware host/write buffer is slots 408 * @hbuf_depth - depth of hardware host/write buffer is slots
342 * @hbuf_is_ready - query if the host host/write buffer is ready 409 * @hbuf_is_ready - query if the host host/write buffer is ready
343 * @wr_msg - the buffer for hbm control messages 410 * @wr_msg - the buffer for hbm control messages
411 * @cfg - per device generation config and ops
344 */ 412 */
345struct mei_device { 413struct mei_device {
346 struct pci_dev *pdev; /* pointer to pci device struct */ 414 struct pci_dev *pdev; /* pointer to pci device struct */
@@ -371,6 +439,7 @@ struct mei_device {
371 * waiting queue for receive message from FW 439 * waiting queue for receive message from FW
372 */ 440 */
373 wait_queue_head_t wait_hw_ready; 441 wait_queue_head_t wait_hw_ready;
442 wait_queue_head_t wait_pg;
374 wait_queue_head_t wait_recvd_msg; 443 wait_queue_head_t wait_recvd_msg;
375 wait_queue_head_t wait_stop_wd; 444 wait_queue_head_t wait_stop_wd;
376 445
@@ -382,6 +451,14 @@ struct mei_device {
382 enum mei_hbm_state hbm_state; 451 enum mei_hbm_state hbm_state;
383 u16 init_clients_timer; 452 u16 init_clients_timer;
384 453
454 /*
455 * Power Gating support
456 */
457 enum mei_pg_event pg_event;
458#ifdef CONFIG_PM_RUNTIME
459 struct dev_pm_domain pg_domain;
460#endif /* CONFIG_PM_RUNTIME */
461
385 unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ 462 unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */
386 u32 rd_msg_hdr; 463 u32 rd_msg_hdr;
387 464
@@ -442,6 +519,7 @@ struct mei_device {
442 519
443 520
444 const struct mei_hw_ops *ops; 521 const struct mei_hw_ops *ops;
522 const struct mei_cfg *cfg;
445 char hw[0] __aligned(sizeof(void *)); 523 char hw[0] __aligned(sizeof(void *));
446}; 524};
447 525
@@ -474,7 +552,7 @@ static inline u32 mei_slots2data(int slots)
474/* 552/*
475 * mei init function prototypes 553 * mei init function prototypes
476 */ 554 */
477void mei_device_init(struct mei_device *dev); 555void mei_device_init(struct mei_device *dev, const struct mei_cfg *cfg);
478int mei_reset(struct mei_device *dev); 556int mei_reset(struct mei_device *dev);
479int mei_start(struct mei_device *dev); 557int mei_start(struct mei_device *dev);
480int mei_restart(struct mei_device *dev); 558int mei_restart(struct mei_device *dev);
@@ -553,10 +631,22 @@ void mei_watchdog_unregister(struct mei_device *dev);
553 * Register Access Function 631 * Register Access Function
554 */ 632 */
555 633
634
556static inline void mei_hw_config(struct mei_device *dev) 635static inline void mei_hw_config(struct mei_device *dev)
557{ 636{
558 dev->ops->hw_config(dev); 637 dev->ops->hw_config(dev);
559} 638}
639
640static inline enum mei_pg_state mei_pg_state(struct mei_device *dev)
641{
642 return dev->ops->pg_state(dev);
643}
644
645static inline bool mei_pg_is_enabled(struct mei_device *dev)
646{
647 return dev->ops->pg_is_enabled(dev);
648}
649
560static inline int mei_hw_reset(struct mei_device *dev, bool enable) 650static inline int mei_hw_reset(struct mei_device *dev, bool enable)
561{ 651{
562 return dev->ops->hw_reset(dev, enable); 652 return dev->ops->hw_reset(dev, enable);
@@ -629,8 +719,17 @@ static inline int mei_count_full_read_slots(struct mei_device *dev)
629 return dev->ops->rdbuf_full_slots(dev); 719 return dev->ops->rdbuf_full_slots(dev);
630} 720}
631 721
722int mei_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status);
723
724#define FW_STS_FMT "%08X %08X"
725#define FW_STS_PRM(fw_status) \
726 (fw_status).count > 0 ? (fw_status).status[0] : 0xDEADBEEF, \
727 (fw_status).count > 1 ? (fw_status).status[1] : 0xDEADBEEF
728
632bool mei_hbuf_acquire(struct mei_device *dev); 729bool mei_hbuf_acquire(struct mei_device *dev);
633 730
731bool mei_write_is_idle(struct mei_device *dev);
732
634#if IS_ENABLED(CONFIG_DEBUG_FS) 733#if IS_ENABLED(CONFIG_DEBUG_FS)
635int mei_dbgfs_register(struct mei_device *dev, const char *name); 734int mei_dbgfs_register(struct mei_device *dev, const char *name);
636void mei_dbgfs_deregister(struct mei_device *dev); 735void mei_dbgfs_deregister(struct mei_device *dev);
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index 95889e2e31ff..1b46c64a649f 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -33,6 +33,8 @@
33#include <linux/interrupt.h> 33#include <linux/interrupt.h>
34#include <linux/miscdevice.h> 34#include <linux/miscdevice.h>
35 35
36#include <linux/pm_runtime.h>
37
36#include <linux/mei.h> 38#include <linux/mei.h>
37 39
38#include "mei_dev.h" 40#include "mei_dev.h"
@@ -42,42 +44,44 @@
42 44
43/* mei_pci_tbl - PCI Device ID Table */ 45/* mei_pci_tbl - PCI Device ID Table */
44static const struct pci_device_id mei_me_pci_tbl[] = { 46static const struct pci_device_id mei_me_pci_tbl[] = {
45 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)}, 47 {MEI_PCI_DEVICE(MEI_DEV_ID_82946GZ, mei_me_legacy_cfg)},
46 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)}, 48 {MEI_PCI_DEVICE(MEI_DEV_ID_82G35, mei_me_legacy_cfg)},
47 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)}, 49 {MEI_PCI_DEVICE(MEI_DEV_ID_82Q965, mei_me_legacy_cfg)},
48 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)}, 50 {MEI_PCI_DEVICE(MEI_DEV_ID_82G965, mei_me_legacy_cfg)},
49 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)}, 51 {MEI_PCI_DEVICE(MEI_DEV_ID_82GM965, mei_me_legacy_cfg)},
50 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)}, 52 {MEI_PCI_DEVICE(MEI_DEV_ID_82GME965, mei_me_legacy_cfg)},
51 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)}, 53 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82Q35, mei_me_legacy_cfg)},
52 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)}, 54 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82G33, mei_me_legacy_cfg)},
53 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q33)}, 55 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82Q33, mei_me_legacy_cfg)},
54 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82X38)}, 56 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82X38, mei_me_legacy_cfg)},
55 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_3200)}, 57 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_3200, mei_me_legacy_cfg)},
56 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_6)}, 58
57 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_7)}, 59 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_6, mei_me_legacy_cfg)},
58 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_8)}, 60 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_7, mei_me_legacy_cfg)},
59 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_9)}, 61 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_8, mei_me_legacy_cfg)},
60 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_10)}, 62 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_9, mei_me_legacy_cfg)},
61 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_1)}, 63 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_10, mei_me_legacy_cfg)},
62 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_2)}, 64 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_1, mei_me_legacy_cfg)},
63 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_3)}, 65 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_2, mei_me_legacy_cfg)},
64 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_4)}, 66 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_3, mei_me_legacy_cfg)},
65 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_1)}, 67 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_4, mei_me_legacy_cfg)},
66 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_2)}, 68 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_1, mei_me_ich_cfg)},
67 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_3)}, 69 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_2, mei_me_ich_cfg)},
68 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_4)}, 70 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_3, mei_me_ich_cfg)},
69 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_1)}, 71 {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_4, mei_me_ich_cfg)},
70 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_2)}, 72
71 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_CPT_1)}, 73 {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_1, mei_me_pch_cfg)},
72 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PBG_1)}, 74 {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_2, mei_me_pch_cfg)},
73 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)}, 75 {MEI_PCI_DEVICE(MEI_DEV_ID_CPT_1, mei_me_pch_cpt_pbg_cfg)},
74 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)}, 76 {MEI_PCI_DEVICE(MEI_DEV_ID_PBG_1, mei_me_pch_cpt_pbg_cfg)},
75 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)}, 77 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, mei_me_pch_cfg)},
76 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_H)}, 78 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, mei_me_pch_cfg)},
77 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_W)}, 79 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, mei_me_pch_cfg)},
78 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)}, 80 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, mei_me_lpt_cfg)},
79 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_HR)}, 81 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, mei_me_lpt_cfg)},
80 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_WPT_LP)}, 82 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, mei_me_pch_cfg)},
83 {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_lpt_cfg)},
84 {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, mei_me_pch_cfg)},
81 85
82 /* required last entry */ 86 /* required last entry */
83 {0, } 87 {0, }
@@ -85,44 +89,33 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
85 89
86MODULE_DEVICE_TABLE(pci, mei_me_pci_tbl); 90MODULE_DEVICE_TABLE(pci, mei_me_pci_tbl);
87 91
92#ifdef CONFIG_PM_RUNTIME
93static inline void mei_me_set_pm_domain(struct mei_device *dev);
94static inline void mei_me_unset_pm_domain(struct mei_device *dev);
95#else
96static inline void mei_me_set_pm_domain(struct mei_device *dev) {}
97static inline void mei_me_unset_pm_domain(struct mei_device *dev) {}
98#endif /* CONFIG_PM_RUNTIME */
99
88/** 100/**
89 * mei_quirk_probe - probe for devices that doesn't valid ME interface 101 * mei_quirk_probe - probe for devices that doesn't valid ME interface
90 * 102 *
91 * @pdev: PCI device structure 103 * @pdev: PCI device structure
92 * @ent: entry into pci_device_table 104 * @cfg: per generation config
93 * 105 *
94 * returns true if ME Interface is valid, false otherwise 106 * returns true if ME Interface is valid, false otherwise
95 */ 107 */
96static bool mei_me_quirk_probe(struct pci_dev *pdev, 108static bool mei_me_quirk_probe(struct pci_dev *pdev,
97 const struct pci_device_id *ent) 109 const struct mei_cfg *cfg)
98{ 110{
99 u32 reg; 111 if (cfg->quirk_probe && cfg->quirk_probe(pdev)) {
100 /* Cougar Point || Patsburg */ 112 dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
101 if (ent->device == MEI_DEV_ID_CPT_1 || 113 return false;
102 ent->device == MEI_DEV_ID_PBG_1) {
103 pci_read_config_dword(pdev, PCI_CFG_HFS_2, &reg);
104 /* make sure that bit 9 (NM) is up and bit 10 (DM) is down */
105 if ((reg & 0x600) == 0x200)
106 goto no_mei;
107 }
108
109 /* Lynx Point */
110 if (ent->device == MEI_DEV_ID_LPT_H ||
111 ent->device == MEI_DEV_ID_LPT_W ||
112 ent->device == MEI_DEV_ID_LPT_HR) {
113 /* Read ME FW Status check for SPS Firmware */
114 pci_read_config_dword(pdev, PCI_CFG_HFS_1, &reg);
115 /* if bits [19:16] = 15, running SPS Firmware */
116 if ((reg & 0xf0000) == 0xf0000)
117 goto no_mei;
118 } 114 }
119 115
120 return true; 116 return true;
121
122no_mei:
123 dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
124 return false;
125} 117}
118
126/** 119/**
127 * mei_probe - Device Initialization Routine 120 * mei_probe - Device Initialization Routine
128 * 121 *
@@ -133,15 +126,14 @@ no_mei:
133 */ 126 */
134static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 127static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
135{ 128{
129 const struct mei_cfg *cfg = (struct mei_cfg *)(ent->driver_data);
136 struct mei_device *dev; 130 struct mei_device *dev;
137 struct mei_me_hw *hw; 131 struct mei_me_hw *hw;
138 int err; 132 int err;
139 133
140 134
141 if (!mei_me_quirk_probe(pdev, ent)) { 135 if (!mei_me_quirk_probe(pdev, cfg))
142 err = -ENODEV; 136 return -ENODEV;
143 goto end;
144 }
145 137
146 /* enable pci dev */ 138 /* enable pci dev */
147 err = pci_enable_device(pdev); 139 err = pci_enable_device(pdev);
@@ -173,7 +165,7 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
173 165
174 166
175 /* allocates and initializes the mei dev structure */ 167 /* allocates and initializes the mei dev structure */
176 dev = mei_me_dev_init(pdev); 168 dev = mei_me_dev_init(pdev, cfg);
177 if (!dev) { 169 if (!dev) {
178 err = -ENOMEM; 170 err = -ENOMEM;
179 goto release_regions; 171 goto release_regions;
@@ -212,6 +204,9 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
212 goto release_irq; 204 goto release_irq;
213 } 205 }
214 206
207 pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_ME_RPM_TIMEOUT);
208 pm_runtime_use_autosuspend(&pdev->dev);
209
215 err = mei_register(dev); 210 err = mei_register(dev);
216 if (err) 211 if (err)
217 goto release_irq; 212 goto release_irq;
@@ -220,6 +215,17 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
220 215
221 schedule_delayed_work(&dev->timer_work, HZ); 216 schedule_delayed_work(&dev->timer_work, HZ);
222 217
218 /*
219 * For not wake-able HW runtime pm framework
220 * can't be used on pci device level.
221 * Use domain runtime pm callbacks instead.
222 */
223 if (!pci_dev_run_wake(pdev))
224 mei_me_set_pm_domain(dev);
225
226 if (mei_pg_is_enabled(dev))
227 pm_runtime_put_noidle(&pdev->dev);
228
223 dev_dbg(&pdev->dev, "initialization successful.\n"); 229 dev_dbg(&pdev->dev, "initialization successful.\n");
224 230
225 return 0; 231 return 0;
@@ -259,12 +265,18 @@ static void mei_me_remove(struct pci_dev *pdev)
259 if (!dev) 265 if (!dev)
260 return; 266 return;
261 267
268 if (mei_pg_is_enabled(dev))
269 pm_runtime_get_noresume(&pdev->dev);
270
262 hw = to_me_hw(dev); 271 hw = to_me_hw(dev);
263 272
264 273
265 dev_dbg(&pdev->dev, "stop\n"); 274 dev_dbg(&pdev->dev, "stop\n");
266 mei_stop(dev); 275 mei_stop(dev);
267 276
277 if (!pci_dev_run_wake(pdev))
278 mei_me_unset_pm_domain(dev);
279
268 /* disable interrupts */ 280 /* disable interrupts */
269 mei_disable_interrupts(dev); 281 mei_disable_interrupts(dev);
270 282
@@ -343,12 +355,120 @@ static int mei_me_pci_resume(struct device *device)
343 355
344 return 0; 356 return 0;
345} 357}
358#endif /* CONFIG_PM_SLEEP */
359
360#ifdef CONFIG_PM_RUNTIME
361static int mei_me_pm_runtime_idle(struct device *device)
362{
363 struct pci_dev *pdev = to_pci_dev(device);
364 struct mei_device *dev;
365
366 dev_dbg(&pdev->dev, "rpm: me: runtime_idle\n");
367
368 dev = pci_get_drvdata(pdev);
369 if (!dev)
370 return -ENODEV;
371 if (mei_write_is_idle(dev))
372 pm_schedule_suspend(device, MEI_ME_RPM_TIMEOUT * 2);
373
374 return -EBUSY;
375}
376
377static int mei_me_pm_runtime_suspend(struct device *device)
378{
379 struct pci_dev *pdev = to_pci_dev(device);
380 struct mei_device *dev;
381 int ret;
382
383 dev_dbg(&pdev->dev, "rpm: me: runtime suspend\n");
384
385 dev = pci_get_drvdata(pdev);
386 if (!dev)
387 return -ENODEV;
388
389 mutex_lock(&dev->device_lock);
390
391 if (mei_write_is_idle(dev))
392 ret = mei_me_pg_set_sync(dev);
393 else
394 ret = -EAGAIN;
395
396 mutex_unlock(&dev->device_lock);
397
398 dev_dbg(&pdev->dev, "rpm: me: runtime suspend ret=%d\n", ret);
399
400 return ret;
401}
402
403static int mei_me_pm_runtime_resume(struct device *device)
404{
405 struct pci_dev *pdev = to_pci_dev(device);
406 struct mei_device *dev;
407 int ret;
408
409 dev_dbg(&pdev->dev, "rpm: me: runtime resume\n");
410
411 dev = pci_get_drvdata(pdev);
412 if (!dev)
413 return -ENODEV;
414
415 mutex_lock(&dev->device_lock);
416
417 ret = mei_me_pg_unset_sync(dev);
418
419 mutex_unlock(&dev->device_lock);
420
421 dev_dbg(&pdev->dev, "rpm: me: runtime resume ret = %d\n", ret);
422
423 return ret;
424}
425
426/**
427 * mei_me_set_pm_domain - fill and set pm domian stucture for device
428 *
429 * @dev: mei_device
430 */
431static inline void mei_me_set_pm_domain(struct mei_device *dev)
432{
433 struct pci_dev *pdev = dev->pdev;
434
435 if (pdev->dev.bus && pdev->dev.bus->pm) {
436 dev->pg_domain.ops = *pdev->dev.bus->pm;
437
438 dev->pg_domain.ops.runtime_suspend = mei_me_pm_runtime_suspend;
439 dev->pg_domain.ops.runtime_resume = mei_me_pm_runtime_resume;
440 dev->pg_domain.ops.runtime_idle = mei_me_pm_runtime_idle;
441
442 pdev->dev.pm_domain = &dev->pg_domain;
443 }
444}
445
446/**
447 * mei_me_unset_pm_domain - clean pm domian stucture for device
448 *
449 * @dev: mei_device
450 */
451static inline void mei_me_unset_pm_domain(struct mei_device *dev)
452{
453 /* stop using pm callbacks if any */
454 dev->pdev->dev.pm_domain = NULL;
455}
456#endif /* CONFIG_PM_RUNTIME */
457
458#ifdef CONFIG_PM
459static const struct dev_pm_ops mei_me_pm_ops = {
460 SET_SYSTEM_SLEEP_PM_OPS(mei_me_pci_suspend,
461 mei_me_pci_resume)
462 SET_RUNTIME_PM_OPS(
463 mei_me_pm_runtime_suspend,
464 mei_me_pm_runtime_resume,
465 mei_me_pm_runtime_idle)
466};
346 467
347static SIMPLE_DEV_PM_OPS(mei_me_pm_ops, mei_me_pci_suspend, mei_me_pci_resume);
348#define MEI_ME_PM_OPS (&mei_me_pm_ops) 468#define MEI_ME_PM_OPS (&mei_me_pm_ops)
349#else 469#else
350#define MEI_ME_PM_OPS NULL 470#define MEI_ME_PM_OPS NULL
351#endif /* CONFIG_PM_SLEEP */ 471#endif /* CONFIG_PM */
352/* 472/*
353 * PCI driver structure 473 * PCI driver structure
354 */ 474 */
diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c
index ad3adb009a1e..2343c6236df9 100644
--- a/drivers/misc/mei/pci-txe.c
+++ b/drivers/misc/mei/pci-txe.c
@@ -27,6 +27,7 @@
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/workqueue.h> 29#include <linux/workqueue.h>
30#include <linux/pm_runtime.h>
30 31
31#include <linux/mei.h> 32#include <linux/mei.h>
32 33
@@ -35,11 +36,18 @@
35#include "hw-txe.h" 36#include "hw-txe.h"
36 37
37static const struct pci_device_id mei_txe_pci_tbl[] = { 38static const struct pci_device_id mei_txe_pci_tbl[] = {
38 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0F18)}, /* Baytrail */ 39 {MEI_PCI_DEVICE(0x0F18, mei_txe_cfg)}, /* Baytrail */
39 {0, } 40 {0, }
40}; 41};
41MODULE_DEVICE_TABLE(pci, mei_txe_pci_tbl); 42MODULE_DEVICE_TABLE(pci, mei_txe_pci_tbl);
42 43
44#ifdef CONFIG_PM_RUNTIME
45static inline void mei_txe_set_pm_domain(struct mei_device *dev);
46static inline void mei_txe_unset_pm_domain(struct mei_device *dev);
47#else
48static inline void mei_txe_set_pm_domain(struct mei_device *dev) {}
49static inline void mei_txe_unset_pm_domain(struct mei_device *dev) {}
50#endif /* CONFIG_PM_RUNTIME */
43 51
44static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw) 52static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw)
45{ 53{
@@ -61,6 +69,7 @@ static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw)
61 */ 69 */
62static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 70static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
63{ 71{
72 const struct mei_cfg *cfg = (struct mei_cfg *)(ent->driver_data);
64 struct mei_device *dev; 73 struct mei_device *dev;
65 struct mei_txe_hw *hw; 74 struct mei_txe_hw *hw;
66 int err; 75 int err;
@@ -91,7 +100,7 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
91 } 100 }
92 101
93 /* allocates and initializes the mei dev structure */ 102 /* allocates and initializes the mei dev structure */
94 dev = mei_txe_dev_init(pdev); 103 dev = mei_txe_dev_init(pdev, cfg);
95 if (!dev) { 104 if (!dev) {
96 err = -ENOMEM; 105 err = -ENOMEM;
97 goto release_regions; 106 goto release_regions;
@@ -137,12 +146,25 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
137 goto release_irq; 146 goto release_irq;
138 } 147 }
139 148
149 pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_TXI_RPM_TIMEOUT);
150 pm_runtime_use_autosuspend(&pdev->dev);
151
140 err = mei_register(dev); 152 err = mei_register(dev);
141 if (err) 153 if (err)
142 goto release_irq; 154 goto release_irq;
143 155
144 pci_set_drvdata(pdev, dev); 156 pci_set_drvdata(pdev, dev);
145 157
158 /*
159 * For not wake-able HW runtime pm framework
160 * can't be used on pci device level.
161 * Use domain runtime pm callbacks instead.
162 */
163 if (!pci_dev_run_wake(pdev))
164 mei_txe_set_pm_domain(dev);
165
166 pm_runtime_put_noidle(&pdev->dev);
167
146 return 0; 168 return 0;
147 169
148release_irq: 170release_irq:
@@ -187,10 +209,15 @@ static void mei_txe_remove(struct pci_dev *pdev)
187 return; 209 return;
188 } 210 }
189 211
212 pm_runtime_get_noresume(&pdev->dev);
213
190 hw = to_txe_hw(dev); 214 hw = to_txe_hw(dev);
191 215
192 mei_stop(dev); 216 mei_stop(dev);
193 217
218 if (!pci_dev_run_wake(pdev))
219 mei_txe_unset_pm_domain(dev);
220
194 /* disable interrupts */ 221 /* disable interrupts */
195 mei_disable_interrupts(dev); 222 mei_disable_interrupts(dev);
196 free_irq(pdev->irq, dev); 223 free_irq(pdev->irq, dev);
@@ -265,15 +292,131 @@ static int mei_txe_pci_resume(struct device *device)
265 292
266 return err; 293 return err;
267} 294}
295#endif /* CONFIG_PM_SLEEP */
296
297#ifdef CONFIG_PM_RUNTIME
298static int mei_txe_pm_runtime_idle(struct device *device)
299{
300 struct pci_dev *pdev = to_pci_dev(device);
301 struct mei_device *dev;
302
303 dev_dbg(&pdev->dev, "rpm: txe: runtime_idle\n");
304
305 dev = pci_get_drvdata(pdev);
306 if (!dev)
307 return -ENODEV;
308 if (mei_write_is_idle(dev))
309 pm_schedule_suspend(device, MEI_TXI_RPM_TIMEOUT * 2);
310
311 return -EBUSY;
312}
313static int mei_txe_pm_runtime_suspend(struct device *device)
314{
315 struct pci_dev *pdev = to_pci_dev(device);
316 struct mei_device *dev;
317 int ret;
318
319 dev_dbg(&pdev->dev, "rpm: txe: runtime suspend\n");
320
321 dev = pci_get_drvdata(pdev);
322 if (!dev)
323 return -ENODEV;
324
325 mutex_lock(&dev->device_lock);
326
327 if (mei_write_is_idle(dev))
328 ret = mei_txe_aliveness_set_sync(dev, 0);
329 else
330 ret = -EAGAIN;
331
332 /*
333 * If everything is okay we're about to enter PCI low
334 * power state (D3) therefor we need to disable the
335 * interrupts towards host.
336 * However if device is not wakeable we do not enter
337 * D-low state and we need to keep the interrupt kicking
338 */
339 if (!ret && pci_dev_run_wake(pdev))
340 mei_disable_interrupts(dev);
341
342 dev_dbg(&pdev->dev, "rpm: txe: runtime suspend ret=%d\n", ret);
343
344 mutex_unlock(&dev->device_lock);
345 return ret;
346}
347
348static int mei_txe_pm_runtime_resume(struct device *device)
349{
350 struct pci_dev *pdev = to_pci_dev(device);
351 struct mei_device *dev;
352 int ret;
353
354 dev_dbg(&pdev->dev, "rpm: txe: runtime resume\n");
355
356 dev = pci_get_drvdata(pdev);
357 if (!dev)
358 return -ENODEV;
359
360 mutex_lock(&dev->device_lock);
361
362 mei_enable_interrupts(dev);
363
364 ret = mei_txe_aliveness_set_sync(dev, 1);
365
366 mutex_unlock(&dev->device_lock);
367
368 dev_dbg(&pdev->dev, "rpm: txe: runtime resume ret = %d\n", ret);
369
370 return ret;
371}
372
373/**
374 * mei_txe_set_pm_domain - fill and set pm domian stucture for device
375 *
376 * @dev: mei_device
377 */
378static inline void mei_txe_set_pm_domain(struct mei_device *dev)
379{
380 struct pci_dev *pdev = dev->pdev;
381
382 if (pdev->dev.bus && pdev->dev.bus->pm) {
383 dev->pg_domain.ops = *pdev->dev.bus->pm;
384
385 dev->pg_domain.ops.runtime_suspend = mei_txe_pm_runtime_suspend;
386 dev->pg_domain.ops.runtime_resume = mei_txe_pm_runtime_resume;
387 dev->pg_domain.ops.runtime_idle = mei_txe_pm_runtime_idle;
388
389 pdev->dev.pm_domain = &dev->pg_domain;
390 }
391}
268 392
269static SIMPLE_DEV_PM_OPS(mei_txe_pm_ops, 393/**
270 mei_txe_pci_suspend, 394 * mei_txe_unset_pm_domain - clean pm domian stucture for device
271 mei_txe_pci_resume); 395 *
396 * @dev: mei_device
397 */
398static inline void mei_txe_unset_pm_domain(struct mei_device *dev)
399{
400 /* stop using pm callbacks if any */
401 dev->pdev->dev.pm_domain = NULL;
402}
403#endif /* CONFIG_PM_RUNTIME */
404
405#ifdef CONFIG_PM
406static const struct dev_pm_ops mei_txe_pm_ops = {
407 SET_SYSTEM_SLEEP_PM_OPS(mei_txe_pci_suspend,
408 mei_txe_pci_resume)
409 SET_RUNTIME_PM_OPS(
410 mei_txe_pm_runtime_suspend,
411 mei_txe_pm_runtime_resume,
412 mei_txe_pm_runtime_idle)
413};
272 414
273#define MEI_TXE_PM_OPS (&mei_txe_pm_ops) 415#define MEI_TXE_PM_OPS (&mei_txe_pm_ops)
274#else 416#else
275#define MEI_TXE_PM_OPS NULL 417#define MEI_TXE_PM_OPS NULL
276#endif /* CONFIG_PM_SLEEP */ 418#endif /* CONFIG_PM */
419
277/* 420/*
278 * PCI driver structure 421 * PCI driver structure
279 */ 422 */
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index ebf1cbc198fd..a84a664dfccb 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -84,8 +84,6 @@ int mei_wd_host_init(struct mei_device *dev)
84 return ret; 84 return ret;
85 } 85 }
86 86
87 cl->state = MEI_FILE_CONNECTING;
88
89 ret = mei_cl_connect(cl, NULL); 87 ret = mei_cl_connect(cl, NULL);
90 88
91 if (ret) { 89 if (ret) {