linux/drivers/dma/dw/pci.c
<<
>>
Prefs
   1/*
   2 * PCI driver for the Synopsys DesignWare DMA Controller
   3 *
   4 * Copyright (C) 2013 Intel Corporation
   5 * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/pci.h>
  14#include <linux/device.h>
  15
  16#include "internal.h"
  17
  18static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
  19{
  20        const struct dw_dma_platform_data *pdata = (void *)pid->driver_data;
  21        struct dw_dma_chip *chip;
  22        int ret;
  23
  24        ret = pcim_enable_device(pdev);
  25        if (ret)
  26                return ret;
  27
  28        ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
  29        if (ret) {
  30                dev_err(&pdev->dev, "I/O memory remapping failed\n");
  31                return ret;
  32        }
  33
  34        pci_set_master(pdev);
  35        pci_try_set_mwi(pdev);
  36
  37        ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
  38        if (ret)
  39                return ret;
  40
  41        ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
  42        if (ret)
  43                return ret;
  44
  45        chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
  46        if (!chip)
  47                return -ENOMEM;
  48
  49        chip->dev = &pdev->dev;
  50        chip->regs = pcim_iomap_table(pdev)[0];
  51        chip->irq = pdev->irq;
  52        chip->pdata = pdata;
  53
  54        ret = dw_dma_probe(chip);
  55        if (ret)
  56                return ret;
  57
  58        pci_set_drvdata(pdev, chip);
  59
  60        return 0;
  61}
  62
  63static void dw_pci_remove(struct pci_dev *pdev)
  64{
  65        struct dw_dma_chip *chip = pci_get_drvdata(pdev);
  66        int ret;
  67
  68        ret = dw_dma_remove(chip);
  69        if (ret)
  70                dev_warn(&pdev->dev, "can't remove device properly: %d\n", ret);
  71}
  72
  73#ifdef CONFIG_PM_SLEEP
  74
  75static int dw_pci_suspend_late(struct device *dev)
  76{
  77        struct pci_dev *pci = to_pci_dev(dev);
  78        struct dw_dma_chip *chip = pci_get_drvdata(pci);
  79
  80        return dw_dma_disable(chip);
  81};
  82
  83static int dw_pci_resume_early(struct device *dev)
  84{
  85        struct pci_dev *pci = to_pci_dev(dev);
  86        struct dw_dma_chip *chip = pci_get_drvdata(pci);
  87
  88        return dw_dma_enable(chip);
  89};
  90
  91#endif /* CONFIG_PM_SLEEP */
  92
  93static const struct dev_pm_ops dw_pci_dev_pm_ops = {
  94        SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_pci_suspend_late, dw_pci_resume_early)
  95};
  96
  97static const struct pci_device_id dw_pci_id_table[] = {
  98        /* Medfield */
  99        { PCI_VDEVICE(INTEL, 0x0827) },
 100        { PCI_VDEVICE(INTEL, 0x0830) },
 101
 102        /* BayTrail */
 103        { PCI_VDEVICE(INTEL, 0x0f06) },
 104        { PCI_VDEVICE(INTEL, 0x0f40) },
 105
 106        /* Braswell */
 107        { PCI_VDEVICE(INTEL, 0x2286) },
 108        { PCI_VDEVICE(INTEL, 0x22c0) },
 109
 110        /* Haswell */
 111        { PCI_VDEVICE(INTEL, 0x9c60) },
 112
 113        /* Broadwell */
 114        { PCI_VDEVICE(INTEL, 0x9ce0) },
 115
 116        { }
 117};
 118MODULE_DEVICE_TABLE(pci, dw_pci_id_table);
 119
 120static struct pci_driver dw_pci_driver = {
 121        .name           = "dw_dmac_pci",
 122        .id_table       = dw_pci_id_table,
 123        .probe          = dw_pci_probe,
 124        .remove         = dw_pci_remove,
 125        .driver = {
 126                .pm     = &dw_pci_dev_pm_ops,
 127        },
 128};
 129
 130module_pci_driver(dw_pci_driver);
 131
 132MODULE_LICENSE("GPL v2");
 133MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller PCI driver");
 134MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
 135