diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-05 11:43:47 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-05 11:43:47 -0700 |
| commit | 1785d116124fc33f2c265243f3f59da3dc2a2576 (patch) | |
| tree | 459394cef69ca6c4151606a8fe360be791a45f4a /drivers/fpga/dfl-pci.c | |
| parent | 060a72a268577cf27733d9e8eb03b3ca427f45e6 (diff) | |
| parent | 22362aa30bad6f03b5bcbbeee3cdc61950d40086 (diff) | |
Merge tag 'char-misc-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH:
"Here is the large set of char and misc and other driver subsystem
patches for 5.9-rc1. Lots of new driver submissions in here, and
cleanups and features for existing drivers.
Highlights are:
- habanalabs driver updates
- coresight driver updates
- nvmem driver updates
- huge number of "W=1" build warning cleanups from Lee Jones
- dyndbg updates
- virtbox driver fixes and updates
- soundwire driver updates
- mei driver updates
- phy driver updates
- fpga driver updates
- lots of smaller individual misc/char driver cleanups and fixes
Full details are in the shortlog.
All of these have been in linux-next with no reported issues"
* tag 'char-misc-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (322 commits)
habanalabs: remove unused but set variable 'ctx_asid'
nvmem: qcom-spmi-sdam: Enable multiple devices
dt-bindings: nvmem: SID: add binding for A100's SID controller
nvmem: update Kconfig description
nvmem: qfprom: Add fuse blowing support
dt-bindings: nvmem: Add properties needed for blowing fuses
dt-bindings: nvmem: qfprom: Convert to yaml
nvmem: qfprom: use NVMEM_DEVID_AUTO for multiple instances
nvmem: core: add support to auto devid
nvmem: core: Add nvmem_cell_read_u8()
nvmem: core: Grammar fixes for help text
nvmem: sc27xx: add sc2730 efuse support
nvmem: Enforce nvmem stride in the sysfs interface
MAINTAINERS: Add git tree for NVMEM FRAMEWORK
nvmem: sprd: Fix return value of sprd_efuse_probe()
drivers: android: Fix the SPDX comment style
drivers: android: Fix a variable declaration coding style issue
drivers: android: Remove braces for a single statement if-else block
drivers: android: Remove the use of else after return
drivers: android: Fix a variable declaration coding style issue
...
Diffstat (limited to 'drivers/fpga/dfl-pci.c')
| -rw-r--r-- | drivers/fpga/dfl-pci.c | 78 |
1 files changed, 69 insertions, 9 deletions
diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c index a78c409bf2c4..e220bec2927d 100644 --- a/drivers/fpga/dfl-pci.c +++ b/drivers/fpga/dfl-pci.c @@ -39,10 +39,32 @@ static void __iomem *cci_pci_ioremap_bar(struct pci_dev *pcidev, int bar) return pcim_iomap_table(pcidev)[bar]; } +static int cci_pci_alloc_irq(struct pci_dev *pcidev) +{ + int ret, nvec = pci_msix_vec_count(pcidev); + + if (nvec <= 0) { + dev_dbg(&pcidev->dev, "fpga interrupt not supported\n"); + return 0; + } + + ret = pci_alloc_irq_vectors(pcidev, nvec, nvec, PCI_IRQ_MSIX); + if (ret < 0) + return ret; + + return nvec; +} + +static void cci_pci_free_irq(struct pci_dev *pcidev) +{ + pci_free_irq_vectors(pcidev); +} + /* PCI Device ID */ #define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD #define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0 #define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4 +#define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30 /* VF Device */ #define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF #define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1 @@ -55,6 +77,7 @@ static struct pci_device_id cci_pcie_id_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X),}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X),}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X),}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_N3000),}, {0,} }; MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl); @@ -78,17 +101,34 @@ static void cci_remove_feature_devs(struct pci_dev *pcidev) /* remove all children feature devices */ dfl_fpga_feature_devs_remove(drvdata->cdev); + cci_pci_free_irq(pcidev); +} + +static int *cci_pci_create_irq_table(struct pci_dev *pcidev, unsigned int nvec) +{ + unsigned int i; + int *table; + + table = kcalloc(nvec, sizeof(int), GFP_KERNEL); + if (!table) + return table; + + for (i = 0; i < nvec; i++) + table[i] = pci_irq_vector(pcidev, i); + + return table; } /* enumerate feature devices under pci device */ static int cci_enumerate_feature_devs(struct pci_dev *pcidev) { struct cci_drvdata *drvdata = pci_get_drvdata(pcidev); + int port_num, bar, i, nvec, ret = 0; struct dfl_fpga_enum_info *info; struct dfl_fpga_cdev *cdev; resource_size_t start, len; - int port_num, bar, i, ret = 0; void __iomem *base; + int *irq_table; u32 offset; u64 v; @@ -97,11 +137,30 @@ static int cci_enumerate_feature_devs(struct pci_dev *pcidev) if (!info) return -ENOMEM; + /* add irq info for enumeration if the device support irq */ + nvec = cci_pci_alloc_irq(pcidev); + if (nvec < 0) { + dev_err(&pcidev->dev, "Fail to alloc irq %d.\n", nvec); + ret = nvec; + goto enum_info_free_exit; + } else if (nvec) { + irq_table = cci_pci_create_irq_table(pcidev, nvec); + if (!irq_table) { + ret = -ENOMEM; + goto irq_free_exit; + } + + ret = dfl_fpga_enum_info_add_irq(info, nvec, irq_table); + kfree(irq_table); + if (ret) + goto irq_free_exit; + } + /* start to find Device Feature List from Bar 0 */ base = cci_pci_ioremap_bar(pcidev, 0); if (!base) { ret = -ENOMEM; - goto enum_info_free_exit; + goto irq_free_exit; } /* @@ -154,7 +213,7 @@ static int cci_enumerate_feature_devs(struct pci_dev *pcidev) dfl_fpga_enum_info_add_dfl(info, start, len, base); } else { ret = -ENODEV; - goto enum_info_free_exit; + goto irq_free_exit; } /* start enumeration with prepared enumeration information */ @@ -162,11 +221,14 @@ static int cci_enumerate_feature_devs(struct pci_dev *pcidev) if (IS_ERR(cdev)) { dev_err(&pcidev->dev, "Enumeration failure\n"); ret = PTR_ERR(cdev); - goto enum_info_free_exit; + goto irq_free_exit; } drvdata->cdev = cdev; +irq_free_exit: + if (ret) + cci_pci_free_irq(pcidev); enum_info_free_exit: dfl_fpga_enum_info_free(info); @@ -211,12 +273,10 @@ int cci_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *pcidevid) } ret = cci_enumerate_feature_devs(pcidev); - if (ret) { - dev_err(&pcidev->dev, "enumeration failure %d.\n", ret); - goto disable_error_report_exit; - } + if (!ret) + return ret; - return ret; + dev_err(&pcidev->dev, "enumeration failure %d.\n", ret); disable_error_report_exit: pci_disable_pcie_error_reporting(pcidev); |
