diff options
author | Oliver Endriss <o.endriss@gmx.de> | 2010-05-16 10:29:14 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-06-01 06:20:12 +0200 |
commit | 4387418129895fd9aa2e2f6368ea69e9c4ddd0f2 (patch) | |
tree | 00780b29a16c8bde363d4d65d074f938fb853517 /drivers/media/dvb | |
parent | V4L/DVB: ngene: Do not call demuxer with interrupts disabled (diff) | |
download | linux-4387418129895fd9aa2e2f6368ea69e9c4ddd0f2.tar.xz linux-4387418129895fd9aa2e2f6368ea69e9c4ddd0f2.zip |
V4L/DVB: ngene: Implement support for MSI
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>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-core.c | 33 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene.h | 2 |
2 files changed, 34 insertions, 1 deletions
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index 46749d6ef1ee..35bed6095b1e 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c @@ -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; } diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h index 676fcbb79026..b951d59e3617 100644 --- a/drivers/media/dvb/ngene/ngene.h +++ b/drivers/media/dvb/ngene/ngene.h @@ -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]; |