1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2013-2017, Intel Corporation. All rights reserved. 4 * Intel Management Engine Interface (Intel MEI) Linux driver 5 */ 6 7 #include <linux/module.h> 8 #include <linux/kernel.h> 9 #include <linux/device.h> 10 #include <linux/fs.h> 11 #include <linux/errno.h> 12 #include <linux/types.h> 13 #include <linux/pci.h> 14 #include <linux/init.h> 15 #include <linux/sched.h> 16 #include <linux/uuid.h> 17 #include <linux/jiffies.h> 18 #include <linux/interrupt.h> 19 #include <linux/workqueue.h> 20 #include <linux/pm_domain.h> 21 #include <linux/pm_runtime.h> 22 23 #include <linux/mei.h> 24 25 26 #include "mei_dev.h" 27 #include "hw-txe.h" 28 29 static const struct pci_device_id mei_txe_pci_tbl[] = { 30 {PCI_VDEVICE(INTEL, 0x0F18)}, /* Baytrail */ 31 {PCI_VDEVICE(INTEL, 0x2298)}, /* Cherrytrail */ 32 33 {0, } 34 }; 35 MODULE_DEVICE_TABLE(pci, mei_txe_pci_tbl); 36 37 #ifdef CONFIG_PM 38 static inline void mei_txe_set_pm_domain(struct mei_device *dev); 39 static inline void mei_txe_unset_pm_domain(struct mei_device *dev); 40 #else 41 static inline void mei_txe_set_pm_domain(struct mei_device *dev) {} 42 static inline void mei_txe_unset_pm_domain(struct mei_device *dev) {} 43 #endif /* CONFIG_PM */ 44 45 /** 46 * mei_txe_probe - Device Initialization Routine 47 * 48 * @pdev: PCI device structure 49 * @ent: entry in mei_txe_pci_tbl 50 * 51 * Return: 0 on success, <0 on failure. 52 */ 53 static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 54 { 55 struct mei_device *dev; 56 struct mei_txe_hw *hw; 57 const int mask = BIT(SEC_BAR) | BIT(BRIDGE_BAR); 58 int err; 59 60 /* enable pci dev */ 61 err = pcim_enable_device(pdev); 62 if (err) { 63 dev_err(&pdev->dev, "failed to enable pci device.\n"); 64 goto end; 65 } 66 /* set PCI host mastering */ 67 pci_set_master(pdev); 68 /* pci request regions and mapping IO device memory for mei driver */ 69 err = pcim_iomap_regions(pdev, mask, KBUILD_MODNAME); 70 if (err) { 71 dev_err(&pdev->dev, "failed to get pci regions.\n"); 72 goto end; 73 } 74 75 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); 76 if (err) { 77 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 78 if (err) { 79 dev_err(&pdev->dev, "No suitable DMA available.\n"); 80 goto end; 81 } 82 } 83 84 /* allocates and initializes the mei dev structure */ 85 dev = mei_txe_dev_init(pdev); 86 if (!dev) { 87 err = -ENOMEM; 88 goto end; 89 } 90 hw = to_txe_hw(dev); 91 hw->mem_addr = pcim_iomap_table(pdev); 92 93 pci_enable_msi(pdev); 94 95 /* clear spurious interrupts */ 96 mei_clear_interrupts(dev); 97 98 /* request and enable interrupt */ 99 if (pci_dev_msi_enabled(pdev)) 100 err = request_threaded_irq(pdev->irq, 101 NULL, 102 mei_txe_irq_thread_handler, 103 IRQF_ONESHOT, KBUILD_MODNAME, dev); 104 else 105 err = request_threaded_irq(pdev->irq, 106 mei_txe_irq_quick_handler, 107 mei_txe_irq_thread_handler, 108 IRQF_SHARED, KBUILD_MODNAME, dev); 109 if (err) { 110 dev_err(&pdev->dev, "mei: request_threaded_irq failure. irq = %d\n", 111 pdev->irq); 112 goto end; 113 } 114 115 if (mei_start(dev)) { 116 dev_err(&pdev->dev, "init hw failure.\n"); 117 err = -ENODEV; 118 goto release_irq; 119 } 120 121 pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_TXI_RPM_TIMEOUT); 122 pm_runtime_use_autosuspend(&pdev->dev); 123 124 err = mei_register(dev, &pdev->dev); 125 if (err) 126 goto stop; 127 128 pci_set_drvdata(pdev, dev); 129 130 /* 131 * MEI requires to resume from runtime suspend mode 132 * in order to perform link reset flow upon system suspend. 133 */ 134 dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP); 135 136 /* 137 * TXE maps runtime suspend/resume to own power gating states, 138 * hence we need to go around native PCI runtime service which 139 * eventually brings the device into D3cold/hot state. 140 * But the TXE device cannot wake up from D3 unlike from own 141 * power gating. To get around PCI device native runtime pm, 142 * TXE uses runtime pm domain handlers which take precedence. 143 */ 144 mei_txe_set_pm_domain(dev); 145 146 pm_runtime_put_noidle(&pdev->dev); 147 148 return 0; 149 150 stop: 151 mei_stop(dev); 152 release_irq: 153 mei_cancel_work(dev); 154 mei_disable_interrupts(dev); 155 free_irq(pdev->irq, dev); 156 end: 157 dev_err(&pdev->dev, "initialization failed.\n"); 158 return err; 159 } 160 161 /** 162 * mei_txe_remove - Device Shutdown Routine 163 * 164 * @pdev: PCI device structure 165 * 166 * mei_txe_shutdown is called from the reboot notifier 167 * it's a simplified version of remove so we go down 168 * faster. 169 */ 170 static void mei_txe_shutdown(struct pci_dev *pdev) 171 { 172 struct mei_device *dev; 173 174 dev = pci_get_drvdata(pdev); 175 if (!dev) 176 return; 177 178 dev_dbg(&pdev->dev, "shutdown\n"); 179 mei_stop(dev); 180 181 mei_txe_unset_pm_domain(dev); 182 183 mei_disable_interrupts(dev); 184 free_irq(pdev->irq, dev); 185 } 186 187 /** 188 * mei_txe_remove - Device Removal Routine 189 * 190 * @pdev: PCI device structure 191 * 192 * mei_remove is called by the PCI subsystem to alert the driver 193 * that it should release a PCI device. 194 */ 195 static void mei_txe_remove(struct pci_dev *pdev) 196 { 197 struct mei_device *dev; 198 199 dev = pci_get_drvdata(pdev); 200 if (!dev) { 201 dev_err(&pdev->dev, "mei: dev == NULL\n"); 202 return; 203 } 204 205 pm_runtime_get_noresume(&pdev->dev); 206 207 mei_stop(dev); 208 209 mei_txe_unset_pm_domain(dev); 210 211 mei_disable_interrupts(dev); 212 free_irq(pdev->irq, dev); 213 214 mei_deregister(dev); 215 } 216 217 218 #ifdef CONFIG_PM_SLEEP 219 static int mei_txe_pci_suspend(struct device *device) 220 { 221 struct pci_dev *pdev = to_pci_dev(device); 222 struct mei_device *dev = pci_get_drvdata(pdev); 223 224 if (!dev) 225 return -ENODEV; 226 227 dev_dbg(&pdev->dev, "suspend\n"); 228 229 mei_stop(dev); 230 231 mei_disable_interrupts(dev); 232 233 free_irq(pdev->irq, dev); 234 pci_disable_msi(pdev); 235 236 return 0; 237 } 238 239 static int mei_txe_pci_resume(struct device *device) 240 { 241 struct pci_dev *pdev = to_pci_dev(device); 242 struct mei_device *dev; 243 int err; 244 245 dev = pci_get_drvdata(pdev); 246 if (!dev) 247 return -ENODEV; 248 249 pci_enable_msi(pdev); 250 251 mei_clear_interrupts(dev); 252 253 /* request and enable interrupt */ 254 if (pci_dev_msi_enabled(pdev)) 255 err = request_threaded_irq(pdev->irq, 256 NULL, 257 mei_txe_irq_thread_handler, 258 IRQF_ONESHOT, KBUILD_MODNAME, dev); 259 else 260 err = request_threaded_irq(pdev->irq, 261 mei_txe_irq_quick_handler, 262 mei_txe_irq_thread_handler, 263 IRQF_SHARED, KBUILD_MODNAME, dev); 264 if (err) { 265 dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n", 266 pdev->irq); 267 return err; 268 } 269 270 err = mei_restart(dev); 271 272 return err; 273 } 274 #endif /* CONFIG_PM_SLEEP */ 275 276 #ifdef CONFIG_PM 277 static int mei_txe_pm_runtime_idle(struct device *device) 278 { 279 struct pci_dev *pdev = to_pci_dev(device); 280 struct mei_device *dev; 281 282 dev_dbg(&pdev->dev, "rpm: txe: runtime_idle\n"); 283 284 dev = pci_get_drvdata(pdev); 285 if (!dev) 286 return -ENODEV; 287 if (mei_write_is_idle(dev)) 288 pm_runtime_autosuspend(device); 289 290 return -EBUSY; 291 } 292 static int mei_txe_pm_runtime_suspend(struct device *device) 293 { 294 struct pci_dev *pdev = to_pci_dev(device); 295 struct mei_device *dev; 296 int ret; 297 298 dev_dbg(&pdev->dev, "rpm: txe: runtime suspend\n"); 299 300 dev = pci_get_drvdata(pdev); 301 if (!dev) 302 return -ENODEV; 303 304 mutex_lock(&dev->device_lock); 305 306 if (mei_write_is_idle(dev)) 307 ret = mei_txe_aliveness_set_sync(dev, 0); 308 else 309 ret = -EAGAIN; 310 311 /* keep irq on we are staying in D0 */ 312 313 dev_dbg(&pdev->dev, "rpm: txe: runtime suspend ret=%d\n", ret); 314 315 mutex_unlock(&dev->device_lock); 316 317 if (ret && ret != -EAGAIN) 318 schedule_work(&dev->reset_work); 319 320 return ret; 321 } 322 323 static int mei_txe_pm_runtime_resume(struct device *device) 324 { 325 struct pci_dev *pdev = to_pci_dev(device); 326 struct mei_device *dev; 327 int ret; 328 329 dev_dbg(&pdev->dev, "rpm: txe: runtime resume\n"); 330 331 dev = pci_get_drvdata(pdev); 332 if (!dev) 333 return -ENODEV; 334 335 mutex_lock(&dev->device_lock); 336 337 mei_enable_interrupts(dev); 338 339 ret = mei_txe_aliveness_set_sync(dev, 1); 340 341 mutex_unlock(&dev->device_lock); 342 343 dev_dbg(&pdev->dev, "rpm: txe: runtime resume ret = %d\n", ret); 344 345 if (ret) 346 schedule_work(&dev->reset_work); 347 348 return ret; 349 } 350 351 /** 352 * mei_txe_set_pm_domain - fill and set pm domain structure for device 353 * 354 * @dev: mei_device 355 */ 356 static inline void mei_txe_set_pm_domain(struct mei_device *dev) 357 { 358 struct pci_dev *pdev = to_pci_dev(dev->dev); 359 360 if (pdev->dev.bus && pdev->dev.bus->pm) { 361 dev->pg_domain.ops = *pdev->dev.bus->pm; 362 363 dev->pg_domain.ops.runtime_suspend = mei_txe_pm_runtime_suspend; 364 dev->pg_domain.ops.runtime_resume = mei_txe_pm_runtime_resume; 365 dev->pg_domain.ops.runtime_idle = mei_txe_pm_runtime_idle; 366 367 dev_pm_domain_set(&pdev->dev, &dev->pg_domain); 368 } 369 } 370 371 /** 372 * mei_txe_unset_pm_domain - clean pm domain structure for device 373 * 374 * @dev: mei_device 375 */ 376 static inline void mei_txe_unset_pm_domain(struct mei_device *dev) 377 { 378 /* stop using pm callbacks if any */ 379 dev_pm_domain_set(dev->dev, NULL); 380 } 381 382 static const struct dev_pm_ops mei_txe_pm_ops = { 383 SET_SYSTEM_SLEEP_PM_OPS(mei_txe_pci_suspend, 384 mei_txe_pci_resume) 385 SET_RUNTIME_PM_OPS( 386 mei_txe_pm_runtime_suspend, 387 mei_txe_pm_runtime_resume, 388 mei_txe_pm_runtime_idle) 389 }; 390 391 #define MEI_TXE_PM_OPS (&mei_txe_pm_ops) 392 #else 393 #define MEI_TXE_PM_OPS NULL 394 #endif /* CONFIG_PM */ 395 396 /* 397 * PCI driver structure 398 */ 399 static struct pci_driver mei_txe_driver = { 400 .name = KBUILD_MODNAME, 401 .id_table = mei_txe_pci_tbl, 402 .probe = mei_txe_probe, 403 .remove = mei_txe_remove, 404 .shutdown = mei_txe_shutdown, 405 .driver.pm = MEI_TXE_PM_OPS, 406 }; 407 408 module_pci_driver(mei_txe_driver); 409 410 MODULE_AUTHOR("Intel Corporation"); 411 MODULE_DESCRIPTION("Intel(R) Trusted Execution Environment Interface"); 412 MODULE_LICENSE("GPL v2"); 413