diff options
Diffstat (limited to 'drivers/misc/mei/pci-me.c')
| -rw-r--r-- | drivers/misc/mei/pci-me.c | 114 |
1 files changed, 58 insertions, 56 deletions
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index c3393b383e59..73cad914be9f 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2003-2020, Intel Corporation. All rights reserved. + * Copyright (c) 2003-2022, Intel Corporation. All rights reserved. * Intel Management Engine Interface (Intel MEI) Linux driver */ @@ -10,6 +10,7 @@ #include <linux/errno.h> #include <linux/types.h> #include <linux/pci.h> +#include <linux/dma-mapping.h> #include <linux/sched.h> #include <linux/interrupt.h> @@ -96,6 +97,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = { {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H_3, MEI_ME_PCH8_ITOUCH_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_N, MEI_ME_PCH12_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH15_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_H, MEI_ME_PCH15_SPS_CFG)}, @@ -112,6 +114,20 @@ static const struct pci_device_id mei_me_pci_tbl[] = { {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_S, MEI_ME_PCH15_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_LP, MEI_ME_PCH15_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_P, MEI_ME_PCH15_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_N, MEI_ME_PCH15_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_SPS_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_MTL_M, MEI_ME_PCH15_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ARL_H, MEI_ME_PCH15_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_PTL_H, MEI_ME_PCH15_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_WCL_P, MEI_ME_PCH15_CFG)}, /* required last entry */ {0, } @@ -129,7 +145,7 @@ static inline void mei_me_unset_pm_domain(struct mei_device *dev) {} static int mei_me_read_fws(const struct mei_device *dev, int where, u32 *val) { - struct pci_dev *pdev = to_pci_dev(dev->dev); + struct pci_dev *pdev = to_pci_dev(dev->parent); return pci_read_config_dword(pdev, where, val); } @@ -191,21 +207,14 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto end; } - if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) || - dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) { - - err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (err) - err = dma_set_coherent_mask(&pdev->dev, - DMA_BIT_MASK(32)); - } + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); if (err) { dev_err(&pdev->dev, "No usable DMA configuration, aborting\n"); goto end; } /* allocates and initializes the mei dev structure */ - dev = mei_me_dev_init(&pdev->dev, cfg); + dev = mei_me_dev_init(&pdev->dev, cfg, false); if (!dev) { err = -ENOMEM; goto end; @@ -214,6 +223,10 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) hw->mem_addr = pcim_iomap_table(pdev)[0]; hw->read_fws = mei_me_read_fws; + err = mei_register(dev, &pdev->dev); + if (err) + goto end; + pci_enable_msi(pdev); hw->irq = pdev->irq; @@ -228,22 +241,18 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) { dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", pdev->irq); - goto end; + goto deregister; } if (mei_start(dev)) { dev_err(&pdev->dev, "init hw failure.\n"); err = -ENODEV; - goto release_irq; + goto deregister; } pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_ME_RPM_TIMEOUT); pm_runtime_use_autosuspend(&pdev->dev); - err = mei_register(dev, &pdev->dev); - if (err) - goto stop; - pci_set_drvdata(pdev, dev); /* @@ -273,12 +282,11 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; -stop: - mei_stop(dev); -release_irq: +deregister: mei_cancel_work(dev); mei_disable_interrupts(dev); free_irq(pdev->irq, dev); + mei_deregister(dev); end: dev_err(&pdev->dev, "initialization failed.\n"); return err; @@ -295,11 +303,7 @@ end: */ static void mei_me_shutdown(struct pci_dev *pdev) { - struct mei_device *dev; - - dev = pci_get_drvdata(pdev); - if (!dev) - return; + struct mei_device *dev = pci_get_drvdata(pdev); dev_dbg(&pdev->dev, "shutdown\n"); mei_stop(dev); @@ -320,11 +324,7 @@ static void mei_me_shutdown(struct pci_dev *pdev) */ static void mei_me_remove(struct pci_dev *pdev) { - struct mei_device *dev; - - dev = pci_get_drvdata(pdev); - if (!dev) - return; + struct mei_device *dev = pci_get_drvdata(pdev); if (mei_pg_is_enabled(dev)) pm_runtime_get_noresume(&pdev->dev); @@ -342,14 +342,17 @@ static void mei_me_remove(struct pci_dev *pdev) } #ifdef CONFIG_PM_SLEEP +static int mei_me_pci_prepare(struct device *device) +{ + pm_runtime_resume(device); + return 0; +} + static int mei_me_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct mei_device *dev = pci_get_drvdata(pdev); - if (!dev) - return -ENODEV; - dev_dbg(&pdev->dev, "suspend\n"); mei_stop(dev); @@ -365,14 +368,10 @@ static int mei_me_pci_suspend(struct device *device) static int mei_me_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct mei_device *dev; + struct mei_device *dev = pci_get_drvdata(pdev); unsigned int irqflags; int err; - dev = pci_get_drvdata(pdev); - if (!dev) - return -ENODEV; - pci_enable_msi(pdev); irqflags = pci_dev_msi_enabled(pdev) ? IRQF_ONESHOT : IRQF_SHARED; @@ -390,26 +389,35 @@ static int mei_me_pci_resume(struct device *device) } err = mei_restart(dev); - if (err) + if (err) { + free_irq(pdev->irq, dev); return err; + } /* Start timer if stopped in suspend */ schedule_delayed_work(&dev->timer_work, HZ); return 0; } -#endif /* CONFIG_PM_SLEEP */ + +static void mei_me_pci_complete(struct device *device) +{ + pm_runtime_suspend(device); +} +#else /* CONFIG_PM_SLEEP */ + +#define mei_me_pci_prepare NULL +#define mei_me_pci_complete NULL + +#endif /* !CONFIG_PM_SLEEP */ #ifdef CONFIG_PM static int mei_me_pm_runtime_idle(struct device *device) { - struct mei_device *dev; + struct mei_device *dev = dev_get_drvdata(device); dev_dbg(device, "rpm: me: runtime_idle\n"); - dev = dev_get_drvdata(device); - if (!dev) - return -ENODEV; if (mei_write_is_idle(dev)) pm_runtime_autosuspend(device); @@ -418,15 +426,11 @@ static int mei_me_pm_runtime_idle(struct device *device) static int mei_me_pm_runtime_suspend(struct device *device) { - struct mei_device *dev; + struct mei_device *dev = dev_get_drvdata(device); int ret; dev_dbg(device, "rpm: me: runtime suspend\n"); - dev = dev_get_drvdata(device); - if (!dev) - return -ENODEV; - mutex_lock(&dev->device_lock); if (mei_write_is_idle(dev)) @@ -446,15 +450,11 @@ static int mei_me_pm_runtime_suspend(struct device *device) static int mei_me_pm_runtime_resume(struct device *device) { - struct mei_device *dev; + struct mei_device *dev = dev_get_drvdata(device); int ret; dev_dbg(device, "rpm: me: runtime resume\n"); - dev = dev_get_drvdata(device); - if (!dev) - return -ENODEV; - mutex_lock(&dev->device_lock); ret = mei_me_pg_exit_sync(dev); @@ -476,7 +476,7 @@ static int mei_me_pm_runtime_resume(struct device *device) */ static inline void mei_me_set_pm_domain(struct mei_device *dev) { - struct pci_dev *pdev = to_pci_dev(dev->dev); + struct pci_dev *pdev = to_pci_dev(dev->parent); if (pdev->dev.bus && pdev->dev.bus->pm) { dev->pg_domain.ops = *pdev->dev.bus->pm; @@ -497,10 +497,12 @@ static inline void mei_me_set_pm_domain(struct mei_device *dev) static inline void mei_me_unset_pm_domain(struct mei_device *dev) { /* stop using pm callbacks if any */ - dev_pm_domain_set(dev->dev, NULL); + dev_pm_domain_set(dev->parent, NULL); } static const struct dev_pm_ops mei_me_pm_ops = { + .prepare = mei_me_pci_prepare, + .complete = mei_me_pci_complete, SET_SYSTEM_SLEEP_PM_OPS(mei_me_pci_suspend, mei_me_pci_resume) SET_RUNTIME_PM_OPS( |
