fpga: add FPGA DFL PCIe device driver
[linux-block.git] / drivers / fpga / dfl-pci.c
CommitLineData
72ddd9f3
ZY
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Driver for FPGA Device Feature List (DFL) PCIe device
4 *
5 * Copyright (C) 2017-2018 Intel Corporation, Inc.
6 *
7 * Authors:
8 * Zhang Yi <Yi.Z.Zhang@intel.com>
9 * Xiao Guangrong <guangrong.xiao@linux.intel.com>
10 * Joseph Grecco <joe.grecco@intel.com>
11 * Enno Luebbers <enno.luebbers@intel.com>
12 * Tim Whisonant <tim.whisonant@intel.com>
13 * Ananda Ravuri <ananda.ravuri@intel.com>
14 * Henry Mitchel <henry.mitchel@intel.com>
15 */
16
17#include <linux/pci.h>
18#include <linux/types.h>
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/stddef.h>
22#include <linux/errno.h>
23#include <linux/aer.h>
24
25#define DRV_VERSION "0.8"
26#define DRV_NAME "dfl-pci"
27
28/* PCI Device ID */
29#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
30#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
31#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
32/* VF Device */
33#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
34#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
35#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
36
37static struct pci_device_id cci_pcie_id_tbl[] = {
38 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),},
39 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_5_X),},
40 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_6_X),},
41 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X),},
42 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X),},
43 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X),},
44 {0,}
45};
46MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
47
48static
49int cci_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *pcidevid)
50{
51 int ret;
52
53 ret = pcim_enable_device(pcidev);
54 if (ret < 0) {
55 dev_err(&pcidev->dev, "Failed to enable device %d.\n", ret);
56 return ret;
57 }
58
59 ret = pci_enable_pcie_error_reporting(pcidev);
60 if (ret && ret != -EINVAL)
61 dev_info(&pcidev->dev, "PCIE AER unavailable %d.\n", ret);
62
63 pci_set_master(pcidev);
64
65 if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) {
66 ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64));
67 if (ret)
68 goto disable_error_report_exit;
69 } else if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(32))) {
70 ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
71 if (ret)
72 goto disable_error_report_exit;
73 } else {
74 ret = -EIO;
75 dev_err(&pcidev->dev, "No suitable DMA support available.\n");
76 goto disable_error_report_exit;
77 }
78
79 /* TODO: create and add the platform device per feature list */
80 return 0;
81
82disable_error_report_exit:
83 pci_disable_pcie_error_reporting(pcidev);
84 return ret;
85}
86
87static void cci_pci_remove(struct pci_dev *pcidev)
88{
89 pci_disable_pcie_error_reporting(pcidev);
90}
91
92static struct pci_driver cci_pci_driver = {
93 .name = DRV_NAME,
94 .id_table = cci_pcie_id_tbl,
95 .probe = cci_pci_probe,
96 .remove = cci_pci_remove,
97};
98
99module_pci_driver(cci_pci_driver);
100
101MODULE_DESCRIPTION("FPGA DFL PCIe Device Driver");
102MODULE_AUTHOR("Intel Corporation");
103MODULE_LICENSE("GPL v2");