| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | | - * |
|---|
| 3 | + * Copyright (c) 2003-2020, Intel Corporation. All rights reserved. |
|---|
| 3 | 4 | * Intel Management Engine Interface (Intel MEI) Linux driver |
|---|
| 4 | | - * Copyright (c) 2003-2012, Intel Corporation. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 8 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | | - * |
|---|
| 15 | 5 | */ |
|---|
| 6 | + |
|---|
| 16 | 7 | #include <linux/module.h> |
|---|
| 17 | | -#include <linux/moduleparam.h> |
|---|
| 18 | 8 | #include <linux/kernel.h> |
|---|
| 19 | 9 | #include <linux/device.h> |
|---|
| 20 | | -#include <linux/fs.h> |
|---|
| 21 | 10 | #include <linux/errno.h> |
|---|
| 22 | 11 | #include <linux/types.h> |
|---|
| 23 | | -#include <linux/fcntl.h> |
|---|
| 24 | 12 | #include <linux/pci.h> |
|---|
| 25 | | -#include <linux/poll.h> |
|---|
| 26 | | -#include <linux/ioctl.h> |
|---|
| 27 | | -#include <linux/cdev.h> |
|---|
| 28 | 13 | #include <linux/sched.h> |
|---|
| 29 | | -#include <linux/uuid.h> |
|---|
| 30 | | -#include <linux/compat.h> |
|---|
| 31 | | -#include <linux/jiffies.h> |
|---|
| 32 | 14 | #include <linux/interrupt.h> |
|---|
| 33 | 15 | |
|---|
| 34 | 16 | #include <linux/pm_domain.h> |
|---|
| .. | .. |
|---|
| 77 | 59 | {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, MEI_ME_PCH7_CFG)}, |
|---|
| 78 | 60 | {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, MEI_ME_PCH7_CFG)}, |
|---|
| 79 | 61 | {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, MEI_ME_PCH7_CFG)}, |
|---|
| 80 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, MEI_ME_PCH8_SPS_CFG)}, |
|---|
| 81 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, MEI_ME_PCH8_SPS_CFG)}, |
|---|
| 62 | + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, MEI_ME_PCH8_SPS_4_CFG)}, |
|---|
| 63 | + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, MEI_ME_PCH8_SPS_4_CFG)}, |
|---|
| 82 | 64 | {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, MEI_ME_PCH8_CFG)}, |
|---|
| 83 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, MEI_ME_PCH8_SPS_CFG)}, |
|---|
| 65 | + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, MEI_ME_PCH8_SPS_4_CFG)}, |
|---|
| 84 | 66 | {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, MEI_ME_PCH8_CFG)}, |
|---|
| 85 | 67 | {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, MEI_ME_PCH8_CFG)}, |
|---|
| 86 | 68 | |
|---|
| 87 | 69 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, MEI_ME_PCH8_CFG)}, |
|---|
| 88 | 70 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, MEI_ME_PCH8_CFG)}, |
|---|
| 89 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, MEI_ME_PCH8_SPS_CFG)}, |
|---|
| 90 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, MEI_ME_PCH8_SPS_CFG)}, |
|---|
| 91 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH12_CFG)}, |
|---|
| 71 | + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_3, MEI_ME_PCH8_ITOUCH_CFG)}, |
|---|
| 72 | + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, MEI_ME_PCH8_SPS_4_CFG)}, |
|---|
| 73 | + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, MEI_ME_PCH8_SPS_4_CFG)}, |
|---|
| 74 | + {MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH12_SPS_4_CFG)}, |
|---|
| 92 | 75 | |
|---|
| 93 | 76 | {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, MEI_ME_PCH8_CFG)}, |
|---|
| 94 | 77 | {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, MEI_ME_PCH8_CFG)}, |
|---|
| .. | .. |
|---|
| 99 | 82 | |
|---|
| 100 | 83 | {MEI_PCI_DEVICE(MEI_DEV_ID_KBP, MEI_ME_PCH8_CFG)}, |
|---|
| 101 | 84 | {MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, MEI_ME_PCH8_CFG)}, |
|---|
| 85 | + {MEI_PCI_DEVICE(MEI_DEV_ID_KBP_3, MEI_ME_PCH8_CFG)}, |
|---|
| 102 | 86 | |
|---|
| 103 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP, MEI_ME_PCH8_CFG)}, |
|---|
| 104 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP_4, MEI_ME_PCH8_CFG)}, |
|---|
| 105 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH8_CFG)}, |
|---|
| 106 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_4, MEI_ME_PCH8_CFG)}, |
|---|
| 87 | + {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP, MEI_ME_PCH12_CFG)}, |
|---|
| 88 | + {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP_3, MEI_ME_PCH8_ITOUCH_CFG)}, |
|---|
| 89 | + {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH12_SPS_CFG)}, |
|---|
| 90 | + {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_3, MEI_ME_PCH12_SPS_ITOUCH_CFG)}, |
|---|
| 107 | 91 | |
|---|
| 108 | 92 | {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP, MEI_ME_PCH12_CFG)}, |
|---|
| 109 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP_3, MEI_ME_PCH8_CFG)}, |
|---|
| 93 | + {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP_3, MEI_ME_PCH8_ITOUCH_CFG)}, |
|---|
| 110 | 94 | {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_V, MEI_ME_PCH12_CFG)}, |
|---|
| 111 | 95 | {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H, MEI_ME_PCH12_CFG)}, |
|---|
| 112 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H_3, MEI_ME_PCH8_CFG)}, |
|---|
| 96 | + {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H_3, MEI_ME_PCH8_ITOUCH_CFG)}, |
|---|
| 113 | 97 | |
|---|
| 114 | 98 | {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)}, |
|---|
| 115 | 99 | {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_N, MEI_ME_PCH12_CFG)}, |
|---|
| 116 | 100 | |
|---|
| 117 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH12_CFG)}, |
|---|
| 101 | + {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH15_CFG)}, |
|---|
| 102 | + {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_H, MEI_ME_PCH15_SPS_CFG)}, |
|---|
| 118 | 103 | |
|---|
| 119 | | - {MEI_PCI_DEVICE(MEI_DEV_ID_MCC, MEI_ME_PCH12_CFG)}, |
|---|
| 104 | + {MEI_PCI_DEVICE(MEI_DEV_ID_JSP_N, MEI_ME_PCH15_CFG)}, |
|---|
| 105 | + |
|---|
| 106 | + {MEI_PCI_DEVICE(MEI_DEV_ID_MCC, MEI_ME_PCH15_CFG)}, |
|---|
| 120 | 107 | {MEI_PCI_DEVICE(MEI_DEV_ID_MCC_4, MEI_ME_PCH8_CFG)}, |
|---|
| 121 | 108 | |
|---|
| 122 | 109 | {MEI_PCI_DEVICE(MEI_DEV_ID_CDF, MEI_ME_PCH8_CFG)}, |
|---|
| 110 | + |
|---|
| 111 | + {MEI_PCI_DEVICE(MEI_DEV_ID_EBG, MEI_ME_PCH15_SPS_CFG)}, |
|---|
| 112 | + |
|---|
| 113 | + {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_S, MEI_ME_PCH15_CFG)}, |
|---|
| 114 | + {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_LP, MEI_ME_PCH15_CFG)}, |
|---|
| 115 | + {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_P, MEI_ME_PCH15_CFG)}, |
|---|
| 116 | + {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_N, MEI_ME_PCH15_CFG)}, |
|---|
| 117 | + |
|---|
| 118 | + {MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_CFG)}, |
|---|
| 123 | 119 | |
|---|
| 124 | 120 | /* required last entry */ |
|---|
| 125 | 121 | {0, } |
|---|
| .. | .. |
|---|
| 134 | 130 | static inline void mei_me_set_pm_domain(struct mei_device *dev) {} |
|---|
| 135 | 131 | static inline void mei_me_unset_pm_domain(struct mei_device *dev) {} |
|---|
| 136 | 132 | #endif /* CONFIG_PM */ |
|---|
| 133 | + |
|---|
| 134 | +static int mei_me_read_fws(const struct mei_device *dev, int where, u32 *val) |
|---|
| 135 | +{ |
|---|
| 136 | + struct pci_dev *pdev = to_pci_dev(dev->dev); |
|---|
| 137 | + |
|---|
| 138 | + return pci_read_config_dword(pdev, where, val); |
|---|
| 139 | +} |
|---|
| 137 | 140 | |
|---|
| 138 | 141 | /** |
|---|
| 139 | 142 | * mei_me_quirk_probe - probe for devices that doesn't valid ME interface |
|---|
| .. | .. |
|---|
| 206 | 209 | } |
|---|
| 207 | 210 | |
|---|
| 208 | 211 | /* allocates and initializes the mei dev structure */ |
|---|
| 209 | | - dev = mei_me_dev_init(pdev, cfg); |
|---|
| 212 | + dev = mei_me_dev_init(&pdev->dev, cfg); |
|---|
| 210 | 213 | if (!dev) { |
|---|
| 211 | 214 | err = -ENOMEM; |
|---|
| 212 | 215 | goto end; |
|---|
| 213 | 216 | } |
|---|
| 214 | 217 | hw = to_me_hw(dev); |
|---|
| 215 | 218 | hw->mem_addr = pcim_iomap_table(pdev)[0]; |
|---|
| 219 | + hw->read_fws = mei_me_read_fws; |
|---|
| 216 | 220 | |
|---|
| 217 | 221 | pci_enable_msi(pdev); |
|---|
| 222 | + |
|---|
| 223 | + hw->irq = pdev->irq; |
|---|
| 218 | 224 | |
|---|
| 219 | 225 | /* request and enable interrupt */ |
|---|
| 220 | 226 | irqflags = pci_dev_msi_enabled(pdev) ? IRQF_ONESHOT : IRQF_SHARED; |
|---|
| .. | .. |
|---|
| 248 | 254 | * MEI requires to resume from runtime suspend mode |
|---|
| 249 | 255 | * in order to perform link reset flow upon system suspend. |
|---|
| 250 | 256 | */ |
|---|
| 251 | | - dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP); |
|---|
| 257 | + dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NO_DIRECT_COMPLETE); |
|---|
| 252 | 258 | |
|---|
| 253 | 259 | /* |
|---|
| 254 | 260 | * ME maps runtime suspend/resume to D0i states, |
|---|
| .. | .. |
|---|
| 401 | 407 | #ifdef CONFIG_PM |
|---|
| 402 | 408 | static int mei_me_pm_runtime_idle(struct device *device) |
|---|
| 403 | 409 | { |
|---|
| 404 | | - struct pci_dev *pdev = to_pci_dev(device); |
|---|
| 405 | 410 | struct mei_device *dev; |
|---|
| 406 | 411 | |
|---|
| 407 | | - dev_dbg(&pdev->dev, "rpm: me: runtime_idle\n"); |
|---|
| 412 | + dev_dbg(device, "rpm: me: runtime_idle\n"); |
|---|
| 408 | 413 | |
|---|
| 409 | | - dev = pci_get_drvdata(pdev); |
|---|
| 414 | + dev = dev_get_drvdata(device); |
|---|
| 410 | 415 | if (!dev) |
|---|
| 411 | 416 | return -ENODEV; |
|---|
| 412 | 417 | if (mei_write_is_idle(dev)) |
|---|
| .. | .. |
|---|
| 417 | 422 | |
|---|
| 418 | 423 | static int mei_me_pm_runtime_suspend(struct device *device) |
|---|
| 419 | 424 | { |
|---|
| 420 | | - struct pci_dev *pdev = to_pci_dev(device); |
|---|
| 421 | 425 | struct mei_device *dev; |
|---|
| 422 | 426 | int ret; |
|---|
| 423 | 427 | |
|---|
| 424 | | - dev_dbg(&pdev->dev, "rpm: me: runtime suspend\n"); |
|---|
| 428 | + dev_dbg(device, "rpm: me: runtime suspend\n"); |
|---|
| 425 | 429 | |
|---|
| 426 | | - dev = pci_get_drvdata(pdev); |
|---|
| 430 | + dev = dev_get_drvdata(device); |
|---|
| 427 | 431 | if (!dev) |
|---|
| 428 | 432 | return -ENODEV; |
|---|
| 429 | 433 | |
|---|
| .. | .. |
|---|
| 436 | 440 | |
|---|
| 437 | 441 | mutex_unlock(&dev->device_lock); |
|---|
| 438 | 442 | |
|---|
| 439 | | - dev_dbg(&pdev->dev, "rpm: me: runtime suspend ret=%d\n", ret); |
|---|
| 443 | + dev_dbg(device, "rpm: me: runtime suspend ret=%d\n", ret); |
|---|
| 440 | 444 | |
|---|
| 441 | 445 | if (ret && ret != -EAGAIN) |
|---|
| 442 | 446 | schedule_work(&dev->reset_work); |
|---|
| .. | .. |
|---|
| 446 | 450 | |
|---|
| 447 | 451 | static int mei_me_pm_runtime_resume(struct device *device) |
|---|
| 448 | 452 | { |
|---|
| 449 | | - struct pci_dev *pdev = to_pci_dev(device); |
|---|
| 450 | 453 | struct mei_device *dev; |
|---|
| 451 | 454 | int ret; |
|---|
| 452 | 455 | |
|---|
| 453 | | - dev_dbg(&pdev->dev, "rpm: me: runtime resume\n"); |
|---|
| 456 | + dev_dbg(device, "rpm: me: runtime resume\n"); |
|---|
| 454 | 457 | |
|---|
| 455 | | - dev = pci_get_drvdata(pdev); |
|---|
| 458 | + dev = dev_get_drvdata(device); |
|---|
| 456 | 459 | if (!dev) |
|---|
| 457 | 460 | return -ENODEV; |
|---|
| 458 | 461 | |
|---|
| .. | .. |
|---|
| 462 | 465 | |
|---|
| 463 | 466 | mutex_unlock(&dev->device_lock); |
|---|
| 464 | 467 | |
|---|
| 465 | | - dev_dbg(&pdev->dev, "rpm: me: runtime resume ret = %d\n", ret); |
|---|
| 468 | + dev_dbg(device, "rpm: me: runtime resume ret = %d\n", ret); |
|---|
| 466 | 469 | |
|---|
| 467 | 470 | if (ret) |
|---|
| 468 | 471 | schedule_work(&dev->reset_work); |
|---|