V4L/DVB: ngene: Implement support for MSI
authorOliver Endriss <o.endriss@gmx.de>
Sun, 16 May 2010 08:29:14 +0000 (05:29 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 1 Jun 2010 04:20:12 +0000 (01:20 -0300)
Add MSI support, may be enabled with firmware version 18.

Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/ngene/ngene-core.c
drivers/media/dvb/ngene/ngene.h

index 46749d6..35bed60 100644 (file)
@@ -1299,11 +1299,14 @@ static void ngene_stop(struct ngene *dev)
        ngwritel(0, NGENE_EVENT);
        ngwritel(0, NGENE_EVENT_HI);
        free_irq(dev->pci_dev->irq, dev);
+       if (dev->msi_enabled)
+               pci_disable_msi(dev->pci_dev);
 }
 
 static int ngene_start(struct ngene *dev)
 {
        int stat;
+       unsigned long flags;
        int i;
 
        pci_set_master(dev->pci_dev);
@@ -1333,6 +1336,28 @@ static int ngene_start(struct ngene *dev)
        if (stat < 0)
                goto fail;
 
+#ifdef CONFIG_PCI_MSI
+       /* enable MSI if kernel and card support it */
+       if (dev->card_info->msi_supported) {
+               ngwritel(0, NGENE_INT_ENABLE);
+               free_irq(dev->pci_dev->irq, dev);
+               stat = pci_enable_msi(dev->pci_dev);
+               if (stat) {
+                       printk(KERN_INFO DEVICE_NAME
+                               ": MSI not available\n");
+                       flags = IRQF_SHARED;
+               } else {
+                       flags = 0;
+                       dev->msi_enabled = true;
+               }
+               stat = request_irq(dev->pci_dev->irq, irq_handler,
+                                       flags, "nGene", dev);
+               if (stat < 0)
+                       goto fail2;
+               ngwritel(1, NGENE_INT_ENABLE);
+       }
+#endif
+
        stat = ngene_i2c_init(dev, 0);
        if (stat < 0)
                goto fail;
@@ -1358,10 +1383,16 @@ static int ngene_start(struct ngene *dev)
                        bconf = BUFFER_CONFIG_3333;
                stat = ngene_command_config_buf(dev, bconf);
        }
-       return stat;
+       if (!stat)
+               return stat;
+
+       /* otherwise error: fall through */
 fail:
        ngwritel(0, NGENE_INT_ENABLE);
        free_irq(dev->pci_dev->irq, dev);
+fail2:
+       if (dev->msi_enabled)
+               pci_disable_msi(dev->pci_dev);
        return stat;
 }
 
index 676fcbb..b951d59 100644 (file)
@@ -725,6 +725,7 @@ struct ngene {
        u32                   device_version;
        u32                   fw_interface_version;
        u32                   icounts;
+       bool                  msi_enabled;
 
        u8                   *CmdDoneByte;
        int                   BootFirmware;
@@ -797,6 +798,7 @@ struct ngene_info {
 #define NGENE_VBOX_V2   7
 
        int   fw_version;
+       bool  msi_supported;
        char *name;
 
        int   io_type[MAX_STREAM];