diff options
Diffstat (limited to 'drivers/media/pci/ddbridge/ddbridge-main.c')
-rw-r--r-- | drivers/media/pci/ddbridge/ddbridge-main.c | 91 |
1 files changed, 33 insertions, 58 deletions
diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index 26497d6b1395..f4748cfd904b 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -55,34 +55,6 @@ MODULE_PARM_DESC(msi, "Control MSI interrupts: 0-disable (default), 1-enable"); #endif #endif -int ci_bitrate = 70000; -module_param(ci_bitrate, int, 0444); -MODULE_PARM_DESC(ci_bitrate, " Bitrate in KHz for output to CI."); - -int ts_loop = -1; -module_param(ts_loop, int, 0444); -MODULE_PARM_DESC(ts_loop, "TS in/out test loop on port ts_loop"); - -int xo2_speed = 2; -module_param(xo2_speed, int, 0444); -MODULE_PARM_DESC(xo2_speed, "default transfer speed for xo2 based duoflex, 0=55,1=75,2=90,3=104 MBit/s, default=2, use attribute to change for individual cards"); - -#ifdef __arm__ -int alt_dma = 1; -#else -int alt_dma; -#endif -module_param(alt_dma, int, 0444); -MODULE_PARM_DESC(alt_dma, "use alternative DMA buffer handling"); - -int no_init; -module_param(no_init, int, 0444); -MODULE_PARM_DESC(no_init, "do not initialize most devices"); - -int stv0910_single; -module_param(stv0910_single, int, 0444); -MODULE_PARM_DESC(stv0910_single, "use stv0910 cards as single demods"); - /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ @@ -93,18 +65,22 @@ static void ddb_irq_disable(struct ddb *dev) ddbwritel(dev, 0, MSI1_ENABLE); } -static void ddb_irq_exit(struct ddb *dev) +static void ddb_msi_exit(struct ddb *dev) { - ddb_irq_disable(dev); - if (dev->msi == 2) - free_irq(dev->pdev->irq + 1, dev); - free_irq(dev->pdev->irq, dev); #ifdef CONFIG_PCI_MSI if (dev->msi) - pci_disable_msi(dev->pdev); + pci_free_irq_vectors(dev->pdev); #endif } +static void ddb_irq_exit(struct ddb *dev) +{ + ddb_irq_disable(dev); + if (dev->msi == 2) + free_irq(pci_irq_vector(dev->pdev, 1), dev); + free_irq(pci_irq_vector(dev->pdev, 0), dev); +} + static void ddb_remove(struct pci_dev *pdev) { struct ddb *dev = (struct ddb *)pci_get_drvdata(pdev); @@ -114,6 +90,7 @@ static void ddb_remove(struct pci_dev *pdev) ddb_i2c_release(dev); ddb_irq_exit(dev); + ddb_msi_exit(dev); ddb_ports_release(dev); ddb_buffers_free(dev); @@ -128,7 +105,8 @@ static void ddb_irq_msi(struct ddb *dev, int nr) int stat; if (msi && pci_msi_enabled()) { - stat = pci_alloc_irq_vectors(dev->pdev, 1, nr, PCI_IRQ_MSI); + stat = pci_alloc_irq_vectors(dev->pdev, 1, nr, + PCI_IRQ_MSI | PCI_IRQ_MSIX); if (stat >= 1) { dev->msi = stat; dev_info(dev->dev, "using %d MSI interrupt(s)\n", @@ -160,21 +138,24 @@ static int ddb_irq_init(struct ddb *dev) if (dev->msi) irq_flag = 0; if (dev->msi == 2) { - stat = request_irq(dev->pdev->irq, ddb_irq_handler0, - irq_flag, "ddbridge", (void *)dev); + stat = request_irq(pci_irq_vector(dev->pdev, 0), + ddb_irq_handler0, irq_flag, "ddbridge", + (void *)dev); if (stat < 0) return stat; - stat = request_irq(dev->pdev->irq + 1, ddb_irq_handler1, - irq_flag, "ddbridge", (void *)dev); + stat = request_irq(pci_irq_vector(dev->pdev, 1), + ddb_irq_handler1, irq_flag, "ddbridge", + (void *)dev); if (stat < 0) { - free_irq(dev->pdev->irq, dev); + free_irq(pci_irq_vector(dev->pdev, 0), dev); return stat; } } else #endif { - stat = request_irq(dev->pdev->irq, ddb_irq_handler, - irq_flag, "ddbridge", (void *)dev); + stat = request_irq(pci_irq_vector(dev->pdev, 0), + ddb_irq_handler, irq_flag, "ddbridge", + (void *)dev); if (stat < 0) return stat; } @@ -217,6 +198,7 @@ static int ddb_probe(struct pci_dev *pdev, dev->link[0].ids.device = id->device; dev->link[0].ids.subvendor = id->subvendor; dev->link[0].ids.subdevice = pdev->subsystem_device; + dev->link[0].ids.devid = (id->device << 16) | id->vendor; dev->link[0].dev = dev; dev->link[0].info = get_ddb_info(id->vendor, id->device, @@ -258,8 +240,7 @@ static int ddb_probe(struct pci_dev *pdev, ddb_irq_exit(dev); fail0: dev_err(&pdev->dev, "fail0\n"); - if (dev->msi) - pci_disable_msi(dev->pdev); + ddb_msi_exit(dev); fail: dev_err(&pdev->dev, "fail\n"); @@ -283,6 +264,7 @@ static const struct pci_device_id ddb_id_table[] = { DDB_DEVICE_ANY(0x0006), DDB_DEVICE_ANY(0x0007), DDB_DEVICE_ANY(0x0008), + DDB_DEVICE_ANY(0x0009), DDB_DEVICE_ANY(0x0011), DDB_DEVICE_ANY(0x0012), DDB_DEVICE_ANY(0x0013), @@ -310,32 +292,25 @@ static struct pci_driver ddb_pci_driver = { static __init int module_init_ddbridge(void) { - int stat = -1; + int stat; pr_info("Digital Devices PCIE bridge driver " DDBRIDGE_VERSION ", Copyright (C) 2010-17 Digital Devices GmbH\n"); - if (ddb_class_create() < 0) - return -1; - ddb_wq = create_workqueue("ddbridge"); - if (!ddb_wq) - goto exit1; + stat = ddb_init_ddbridge(); + if (stat < 0) + return stat; stat = pci_register_driver(&ddb_pci_driver); if (stat < 0) - goto exit2; - return stat; -exit2: - destroy_workqueue(ddb_wq); -exit1: - ddb_class_destroy(); + ddb_exit_ddbridge(0, stat); + return stat; } static __exit void module_exit_ddbridge(void) { pci_unregister_driver(&ddb_pci_driver); - destroy_workqueue(ddb_wq); - ddb_class_destroy(); + ddb_exit_ddbridge(0, 0); } module_init(module_init_ddbridge); |