summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Endriss <o.endriss@gmx.de>2010-05-16 05:29:14 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-06-01 01:20:12 -0300
commit4387418129895fd9aa2e2f6368ea69e9c4ddd0f2 (patch)
tree00780b29a16c8bde363d4d65d074f938fb853517
parenteb05d155bc9f51ff701c09bc9b5e4b4f5a4b4d9f (diff)
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>
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c33
-rw-r--r--drivers/media/dvb/ngene/ngene.h2
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];