diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-cards.c | 1 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-core.c | 37 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene.h | 1 |
3 files changed, 39 insertions, 0 deletions
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c index 93e6f9e954ca..6d87427d214a 100644 --- a/drivers/media/dvb/ngene/ngene-cards.c +++ b/drivers/media/dvb/ngene/ngene-cards.c @@ -436,6 +436,7 @@ static struct pci_driver ngene_pci_driver = { .probe = ngene_probe, .remove = __devexit_p(ngene_remove), .err_handler = &ngene_errors, + .shutdown = ngene_shutdown, }; static __init int module_init_ngene(void) diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index deaf72aab058..422f83b9dca1 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c @@ -45,6 +45,10 @@ static int one_adapter = 1; module_param(one_adapter, int, 0444); MODULE_PARM_DESC(one_adapter, "Use only one adapter."); +static int shutdown_workaround; +module_param(shutdown_workaround, int, 0644); +MODULE_PARM_DESC(one_adapter, "Activate workaround for shutdown problem with some chipsets."); + static int debug; module_param(debug, int, 0444); MODULE_PARM_DESC(debug, "Print debugging information."); @@ -1574,6 +1578,39 @@ static void cxd_detach(struct ngene *dev) ci->en = 0; } +/***********************************/ +/* workaround for shutdown failure */ +/***********************************/ + +static void ngene_unlink(struct ngene *dev) +{ + struct ngene_command com; + + com.cmd.hdr.Opcode = CMD_MEM_WRITE; + com.cmd.hdr.Length = 3; + com.cmd.MemoryWrite.address = 0x910c; + com.cmd.MemoryWrite.data = 0xff; + com.in_len = 3; + com.out_len = 1; + + down(&dev->cmd_mutex); + ngwritel(0, NGENE_INT_ENABLE); + ngene_command_mutex(dev, &com); + up(&dev->cmd_mutex); +} + +void ngene_shutdown(struct pci_dev *pdev) +{ + struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); + + if (!dev || !shutdown_workaround) + return; + + printk(KERN_INFO DEVICE_NAME ": shutdown workaround...\n"); + ngene_unlink(dev); + pci_disable_device(pdev); +} + /****************************************************************************/ /* device probe/remove calls ************************************************/ /****************************************************************************/ diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h index f7834066386f..c1bb81014fb4 100644 --- a/drivers/media/dvb/ngene/ngene.h +++ b/drivers/media/dvb/ngene/ngene.h @@ -881,6 +881,7 @@ struct ngene_buffer { int __devinit ngene_probe(struct pci_dev *pci_dev, const struct pci_device_id *id); void __devexit ngene_remove(struct pci_dev *pdev); +void ngene_shutdown(struct pci_dev *pdev); int ngene_command(struct ngene *dev, struct ngene_command *com); int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level); void set_transfer(struct ngene_channel *chan, int state); |