Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2013-2020, Intel Corporation. All rights reserved.
0004  * Intel Management Engine Interface (Intel MEI) Linux driver
0005  */
0006 
0007 #include <linux/module.h>
0008 #include <linux/kernel.h>
0009 #include <linux/device.h>
0010 #include <linux/errno.h>
0011 #include <linux/types.h>
0012 #include <linux/pci.h>
0013 #include <linux/init.h>
0014 #include <linux/sched.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/workqueue.h>
0017 #include <linux/pm_domain.h>
0018 #include <linux/pm_runtime.h>
0019 
0020 #include <linux/mei.h>
0021 
0022 
0023 #include "mei_dev.h"
0024 #include "hw-txe.h"
0025 
0026 static const struct pci_device_id mei_txe_pci_tbl[] = {
0027     {PCI_VDEVICE(INTEL, 0x0F18)}, /* Baytrail */
0028     {PCI_VDEVICE(INTEL, 0x2298)}, /* Cherrytrail */
0029 
0030     {0, }
0031 };
0032 MODULE_DEVICE_TABLE(pci, mei_txe_pci_tbl);
0033 
0034 #ifdef CONFIG_PM
0035 static inline void mei_txe_set_pm_domain(struct mei_device *dev);
0036 static inline void mei_txe_unset_pm_domain(struct mei_device *dev);
0037 #else
0038 static inline void mei_txe_set_pm_domain(struct mei_device *dev) {}
0039 static inline void mei_txe_unset_pm_domain(struct mei_device *dev) {}
0040 #endif /* CONFIG_PM */
0041 
0042 /**
0043  * mei_txe_probe - Device Initialization Routine
0044  *
0045  * @pdev: PCI device structure
0046  * @ent: entry in mei_txe_pci_tbl
0047  *
0048  * Return: 0 on success, <0 on failure.
0049  */
0050 static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
0051 {
0052     struct mei_device *dev;
0053     struct mei_txe_hw *hw;
0054     const int mask = BIT(SEC_BAR) | BIT(BRIDGE_BAR);
0055     int err;
0056 
0057     /* enable pci dev */
0058     err = pcim_enable_device(pdev);
0059     if (err) {
0060         dev_err(&pdev->dev, "failed to enable pci device.\n");
0061         goto end;
0062     }
0063     /* set PCI host mastering  */
0064     pci_set_master(pdev);
0065     /* pci request regions and mapping IO device memory for mei driver */
0066     err = pcim_iomap_regions(pdev, mask, KBUILD_MODNAME);
0067     if (err) {
0068         dev_err(&pdev->dev, "failed to get pci regions.\n");
0069         goto end;
0070     }
0071 
0072     err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36));
0073     if (err) {
0074         err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
0075         if (err) {
0076             dev_err(&pdev->dev, "No suitable DMA available.\n");
0077             goto end;
0078         }
0079     }
0080 
0081     /* allocates and initializes the mei dev structure */
0082     dev = mei_txe_dev_init(pdev);
0083     if (!dev) {
0084         err = -ENOMEM;
0085         goto end;
0086     }
0087     hw = to_txe_hw(dev);
0088     hw->mem_addr = pcim_iomap_table(pdev);
0089 
0090     pci_enable_msi(pdev);
0091 
0092     /* clear spurious interrupts */
0093     mei_clear_interrupts(dev);
0094 
0095     /* request and enable interrupt  */
0096     if (pci_dev_msi_enabled(pdev))
0097         err = request_threaded_irq(pdev->irq,
0098             NULL,
0099             mei_txe_irq_thread_handler,
0100             IRQF_ONESHOT, KBUILD_MODNAME, dev);
0101     else
0102         err = request_threaded_irq(pdev->irq,
0103             mei_txe_irq_quick_handler,
0104             mei_txe_irq_thread_handler,
0105             IRQF_SHARED, KBUILD_MODNAME, dev);
0106     if (err) {
0107         dev_err(&pdev->dev, "mei: request_threaded_irq failure. irq = %d\n",
0108             pdev->irq);
0109         goto end;
0110     }
0111 
0112     if (mei_start(dev)) {
0113         dev_err(&pdev->dev, "init hw failure.\n");
0114         err = -ENODEV;
0115         goto release_irq;
0116     }
0117 
0118     pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_TXI_RPM_TIMEOUT);
0119     pm_runtime_use_autosuspend(&pdev->dev);
0120 
0121     err = mei_register(dev, &pdev->dev);
0122     if (err)
0123         goto stop;
0124 
0125     pci_set_drvdata(pdev, dev);
0126 
0127     /*
0128      * MEI requires to resume from runtime suspend mode
0129      * in order to perform link reset flow upon system suspend.
0130      */
0131     dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);
0132 
0133     /*
0134      * TXE maps runtime suspend/resume to own power gating states,
0135      * hence we need to go around native PCI runtime service which
0136      * eventually brings the device into D3cold/hot state.
0137      * But the TXE device cannot wake up from D3 unlike from own
0138      * power gating. To get around PCI device native runtime pm,
0139      * TXE uses runtime pm domain handlers which take precedence.
0140      */
0141     mei_txe_set_pm_domain(dev);
0142 
0143     pm_runtime_put_noidle(&pdev->dev);
0144 
0145     return 0;
0146 
0147 stop:
0148     mei_stop(dev);
0149 release_irq:
0150     mei_cancel_work(dev);
0151     mei_disable_interrupts(dev);
0152     free_irq(pdev->irq, dev);
0153 end:
0154     dev_err(&pdev->dev, "initialization failed.\n");
0155     return err;
0156 }
0157 
0158 /**
0159  * mei_txe_shutdown- Device Shutdown Routine
0160  *
0161  * @pdev: PCI device structure
0162  *
0163  *  mei_txe_shutdown is called from the reboot notifier
0164  *  it's a simplified version of remove so we go down
0165  *  faster.
0166  */
0167 static void mei_txe_shutdown(struct pci_dev *pdev)
0168 {
0169     struct mei_device *dev;
0170 
0171     dev = pci_get_drvdata(pdev);
0172     if (!dev)
0173         return;
0174 
0175     dev_dbg(&pdev->dev, "shutdown\n");
0176     mei_stop(dev);
0177 
0178     mei_txe_unset_pm_domain(dev);
0179 
0180     mei_disable_interrupts(dev);
0181     free_irq(pdev->irq, dev);
0182 }
0183 
0184 /**
0185  * mei_txe_remove - Device Removal Routine
0186  *
0187  * @pdev: PCI device structure
0188  *
0189  * mei_remove is called by the PCI subsystem to alert the driver
0190  * that it should release a PCI device.
0191  */
0192 static void mei_txe_remove(struct pci_dev *pdev)
0193 {
0194     struct mei_device *dev;
0195 
0196     dev = pci_get_drvdata(pdev);
0197     if (!dev) {
0198         dev_err(&pdev->dev, "mei: dev == NULL\n");
0199         return;
0200     }
0201 
0202     pm_runtime_get_noresume(&pdev->dev);
0203 
0204     mei_stop(dev);
0205 
0206     mei_txe_unset_pm_domain(dev);
0207 
0208     mei_disable_interrupts(dev);
0209     free_irq(pdev->irq, dev);
0210 
0211     mei_deregister(dev);
0212 }
0213 
0214 
0215 #ifdef CONFIG_PM_SLEEP
0216 static int mei_txe_pci_suspend(struct device *device)
0217 {
0218     struct pci_dev *pdev = to_pci_dev(device);
0219     struct mei_device *dev = pci_get_drvdata(pdev);
0220 
0221     if (!dev)
0222         return -ENODEV;
0223 
0224     dev_dbg(&pdev->dev, "suspend\n");
0225 
0226     mei_stop(dev);
0227 
0228     mei_disable_interrupts(dev);
0229 
0230     free_irq(pdev->irq, dev);
0231     pci_disable_msi(pdev);
0232 
0233     return 0;
0234 }
0235 
0236 static int mei_txe_pci_resume(struct device *device)
0237 {
0238     struct pci_dev *pdev = to_pci_dev(device);
0239     struct mei_device *dev;
0240     int err;
0241 
0242     dev = pci_get_drvdata(pdev);
0243     if (!dev)
0244         return -ENODEV;
0245 
0246     pci_enable_msi(pdev);
0247 
0248     mei_clear_interrupts(dev);
0249 
0250     /* request and enable interrupt */
0251     if (pci_dev_msi_enabled(pdev))
0252         err = request_threaded_irq(pdev->irq,
0253             NULL,
0254             mei_txe_irq_thread_handler,
0255             IRQF_ONESHOT, KBUILD_MODNAME, dev);
0256     else
0257         err = request_threaded_irq(pdev->irq,
0258             mei_txe_irq_quick_handler,
0259             mei_txe_irq_thread_handler,
0260             IRQF_SHARED, KBUILD_MODNAME, dev);
0261     if (err) {
0262         dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n",
0263                 pdev->irq);
0264         return err;
0265     }
0266 
0267     err = mei_restart(dev);
0268 
0269     return err;
0270 }
0271 #endif /* CONFIG_PM_SLEEP */
0272 
0273 #ifdef CONFIG_PM
0274 static int mei_txe_pm_runtime_idle(struct device *device)
0275 {
0276     struct mei_device *dev;
0277 
0278     dev_dbg(device, "rpm: txe: runtime_idle\n");
0279 
0280     dev = dev_get_drvdata(device);
0281     if (!dev)
0282         return -ENODEV;
0283     if (mei_write_is_idle(dev))
0284         pm_runtime_autosuspend(device);
0285 
0286     return -EBUSY;
0287 }
0288 static int mei_txe_pm_runtime_suspend(struct device *device)
0289 {
0290     struct mei_device *dev;
0291     int ret;
0292 
0293     dev_dbg(device, "rpm: txe: runtime suspend\n");
0294 
0295     dev = dev_get_drvdata(device);
0296     if (!dev)
0297         return -ENODEV;
0298 
0299     mutex_lock(&dev->device_lock);
0300 
0301     if (mei_write_is_idle(dev))
0302         ret = mei_txe_aliveness_set_sync(dev, 0);
0303     else
0304         ret = -EAGAIN;
0305 
0306     /* keep irq on we are staying in D0 */
0307 
0308     dev_dbg(device, "rpm: txe: runtime suspend ret=%d\n", ret);
0309 
0310     mutex_unlock(&dev->device_lock);
0311 
0312     if (ret && ret != -EAGAIN)
0313         schedule_work(&dev->reset_work);
0314 
0315     return ret;
0316 }
0317 
0318 static int mei_txe_pm_runtime_resume(struct device *device)
0319 {
0320     struct mei_device *dev;
0321     int ret;
0322 
0323     dev_dbg(device, "rpm: txe: runtime resume\n");
0324 
0325     dev = dev_get_drvdata(device);
0326     if (!dev)
0327         return -ENODEV;
0328 
0329     mutex_lock(&dev->device_lock);
0330 
0331     mei_enable_interrupts(dev);
0332 
0333     ret = mei_txe_aliveness_set_sync(dev, 1);
0334 
0335     mutex_unlock(&dev->device_lock);
0336 
0337     dev_dbg(device, "rpm: txe: runtime resume ret = %d\n", ret);
0338 
0339     if (ret)
0340         schedule_work(&dev->reset_work);
0341 
0342     return ret;
0343 }
0344 
0345 /**
0346  * mei_txe_set_pm_domain - fill and set pm domain structure for device
0347  *
0348  * @dev: mei_device
0349  */
0350 static inline void mei_txe_set_pm_domain(struct mei_device *dev)
0351 {
0352     struct pci_dev *pdev  = to_pci_dev(dev->dev);
0353 
0354     if (pdev->dev.bus && pdev->dev.bus->pm) {
0355         dev->pg_domain.ops = *pdev->dev.bus->pm;
0356 
0357         dev->pg_domain.ops.runtime_suspend = mei_txe_pm_runtime_suspend;
0358         dev->pg_domain.ops.runtime_resume = mei_txe_pm_runtime_resume;
0359         dev->pg_domain.ops.runtime_idle = mei_txe_pm_runtime_idle;
0360 
0361         dev_pm_domain_set(&pdev->dev, &dev->pg_domain);
0362     }
0363 }
0364 
0365 /**
0366  * mei_txe_unset_pm_domain - clean pm domain structure for device
0367  *
0368  * @dev: mei_device
0369  */
0370 static inline void mei_txe_unset_pm_domain(struct mei_device *dev)
0371 {
0372     /* stop using pm callbacks if any */
0373     dev_pm_domain_set(dev->dev, NULL);
0374 }
0375 
0376 static const struct dev_pm_ops mei_txe_pm_ops = {
0377     SET_SYSTEM_SLEEP_PM_OPS(mei_txe_pci_suspend,
0378                 mei_txe_pci_resume)
0379     SET_RUNTIME_PM_OPS(
0380         mei_txe_pm_runtime_suspend,
0381         mei_txe_pm_runtime_resume,
0382         mei_txe_pm_runtime_idle)
0383 };
0384 
0385 #define MEI_TXE_PM_OPS  (&mei_txe_pm_ops)
0386 #else
0387 #define MEI_TXE_PM_OPS  NULL
0388 #endif /* CONFIG_PM */
0389 
0390 /*
0391  *  PCI driver structure
0392  */
0393 static struct pci_driver mei_txe_driver = {
0394     .name = KBUILD_MODNAME,
0395     .id_table = mei_txe_pci_tbl,
0396     .probe = mei_txe_probe,
0397     .remove = mei_txe_remove,
0398     .shutdown = mei_txe_shutdown,
0399     .driver.pm = MEI_TXE_PM_OPS,
0400 };
0401 
0402 module_pci_driver(mei_txe_driver);
0403 
0404 MODULE_AUTHOR("Intel Corporation");
0405 MODULE_DESCRIPTION("Intel(R) Trusted Execution Environment Interface");
0406 MODULE_LICENSE("GPL v2");