cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pci.c (3647B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * PCI driver for the Synopsys DesignWare DMA Controller
      4 *
      5 * Copyright (C) 2013 Intel Corporation
      6 * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
      7 */
      8
      9#include <linux/module.h>
     10#include <linux/pci.h>
     11#include <linux/device.h>
     12
     13#include "internal.h"
     14
     15static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
     16{
     17	const struct dw_dma_chip_pdata *drv_data = (void *)pid->driver_data;
     18	struct dw_dma_chip_pdata *data;
     19	struct dw_dma_chip *chip;
     20	int ret;
     21
     22	ret = pcim_enable_device(pdev);
     23	if (ret)
     24		return ret;
     25
     26	ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
     27	if (ret) {
     28		dev_err(&pdev->dev, "I/O memory remapping failed\n");
     29		return ret;
     30	}
     31
     32	pci_set_master(pdev);
     33	pci_try_set_mwi(pdev);
     34
     35	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
     36	if (ret)
     37		return ret;
     38
     39	data = devm_kmemdup(&pdev->dev, drv_data, sizeof(*drv_data), GFP_KERNEL);
     40	if (!data)
     41		return -ENOMEM;
     42
     43	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
     44	if (!chip)
     45		return -ENOMEM;
     46
     47	chip->dev = &pdev->dev;
     48	chip->id = pdev->devfn;
     49	chip->regs = pcim_iomap_table(pdev)[0];
     50	chip->irq = pdev->irq;
     51	chip->pdata = data->pdata;
     52
     53	data->chip = chip;
     54
     55	ret = data->probe(chip);
     56	if (ret)
     57		return ret;
     58
     59	dw_dma_acpi_controller_register(chip->dw);
     60
     61	pci_set_drvdata(pdev, data);
     62
     63	return 0;
     64}
     65
     66static void dw_pci_remove(struct pci_dev *pdev)
     67{
     68	struct dw_dma_chip_pdata *data = pci_get_drvdata(pdev);
     69	struct dw_dma_chip *chip = data->chip;
     70	int ret;
     71
     72	dw_dma_acpi_controller_free(chip->dw);
     73
     74	ret = data->remove(chip);
     75	if (ret)
     76		dev_warn(&pdev->dev, "can't remove device properly: %d\n", ret);
     77}
     78
     79#ifdef CONFIG_PM_SLEEP
     80
     81static int dw_pci_suspend_late(struct device *dev)
     82{
     83	struct dw_dma_chip_pdata *data = dev_get_drvdata(dev);
     84	struct dw_dma_chip *chip = data->chip;
     85
     86	return do_dw_dma_disable(chip);
     87};
     88
     89static int dw_pci_resume_early(struct device *dev)
     90{
     91	struct dw_dma_chip_pdata *data = dev_get_drvdata(dev);
     92	struct dw_dma_chip *chip = data->chip;
     93
     94	return do_dw_dma_enable(chip);
     95};
     96
     97#endif /* CONFIG_PM_SLEEP */
     98
     99static const struct dev_pm_ops dw_pci_dev_pm_ops = {
    100	SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_pci_suspend_late, dw_pci_resume_early)
    101};
    102
    103static const struct pci_device_id dw_pci_id_table[] = {
    104	/* Medfield (GPDMA) */
    105	{ PCI_VDEVICE(INTEL, 0x0827), (kernel_ulong_t)&dw_dma_chip_pdata },
    106
    107	/* BayTrail */
    108	{ PCI_VDEVICE(INTEL, 0x0f06), (kernel_ulong_t)&dw_dma_chip_pdata },
    109	{ PCI_VDEVICE(INTEL, 0x0f40), (kernel_ulong_t)&dw_dma_chip_pdata },
    110
    111	/* Merrifield */
    112	{ PCI_VDEVICE(INTEL, 0x11a2), (kernel_ulong_t)&idma32_chip_pdata },
    113
    114	/* Braswell */
    115	{ PCI_VDEVICE(INTEL, 0x2286), (kernel_ulong_t)&dw_dma_chip_pdata },
    116	{ PCI_VDEVICE(INTEL, 0x22c0), (kernel_ulong_t)&dw_dma_chip_pdata },
    117
    118	/* Elkhart Lake iDMA 32-bit (PSE DMA) */
    119	{ PCI_VDEVICE(INTEL, 0x4bb4), (kernel_ulong_t)&xbar_chip_pdata },
    120	{ PCI_VDEVICE(INTEL, 0x4bb5), (kernel_ulong_t)&xbar_chip_pdata },
    121	{ PCI_VDEVICE(INTEL, 0x4bb6), (kernel_ulong_t)&xbar_chip_pdata },
    122
    123	/* Haswell */
    124	{ PCI_VDEVICE(INTEL, 0x9c60), (kernel_ulong_t)&dw_dma_chip_pdata },
    125
    126	/* Broadwell */
    127	{ PCI_VDEVICE(INTEL, 0x9ce0), (kernel_ulong_t)&dw_dma_chip_pdata },
    128
    129	{ }
    130};
    131MODULE_DEVICE_TABLE(pci, dw_pci_id_table);
    132
    133static struct pci_driver dw_pci_driver = {
    134	.name		= "dw_dmac_pci",
    135	.id_table	= dw_pci_id_table,
    136	.probe		= dw_pci_probe,
    137	.remove		= dw_pci_remove,
    138	.driver	= {
    139		.pm	= &dw_pci_dev_pm_ops,
    140	},
    141};
    142
    143module_pci_driver(dw_pci_driver);
    144
    145MODULE_LICENSE("GPL v2");
    146MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller PCI driver");
    147MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");