diff options
author | Johannes Stezenbach <devnull@localhost> | 2005-01-09 01:28:18 +0000 |
---|---|---|
committer | Johannes Stezenbach <devnull@localhost> | 2005-01-09 01:28:18 +0000 |
commit | 9b432f78f4e082705fe90c5d8885d9f7ced755d0 (patch) | |
tree | 5b6156f27e86284751b674992874d824760b9c4e /linux/drivers/media/dvb | |
parent | 383685b47cdf88f3629edb1fea124fae45dd22f8 (diff) | |
download | mediapointer-dvb-s2-9b432f78f4e082705fe90c5d8885d9f7ced755d0.tar.gz mediapointer-dvb-s2-9b432f78f4e082705fe90c5d8885d9f7ced755d0.tar.bz2 |
patch by Emard: fix Oops provoked by insmod/rmmod test loop
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 2ae489243..de7cfc589 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -1151,15 +1151,14 @@ static int stop_ts_capture(struct av7110 *budget) if (--budget->feeding1) return budget->feeding1; - saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off + saa7146_write(budget->dev, MC1, MASK_20); /* DMA3 off */ SAA7146_IER_DISABLE(budget->dev, MASK_10); + SAA7146_ISR_CLEAR(budget->dev, MASK_10); return 0; } static int start_ts_capture(struct av7110 *budget) { - struct saa7146_dev *dev = budget->dev; - dprintk(2, "budget: %p\n", budget); if (budget->feeding1) @@ -1167,8 +1166,8 @@ static int start_ts_capture(struct av7110 *budget) memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH); budget->tsf = 0xff; budget->ttbp = 0; - saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on - SAA7146_IER_ENABLE(budget->dev, MASK_10); // VPE + SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ + saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ return ++budget->feeding1; } @@ -2291,7 +2290,7 @@ err_no_mem: dev->pci, length, &av7110->pt); if (!av7110->grabbing) goto err_no_mem; - saa7146_write(dev, PCI_BT_V1, 0x1c1c101f); + saa7146_write(dev, PCI_BT_V1, 0x1c1f101f); saa7146_write(dev, BCS_CTRL, 0x80400040); /* set dd1 stream a & b */ saa7146_write(dev, DD1_STREAM_B, 0x00000000); @@ -2363,6 +2362,7 @@ err_no_mem: saa7146_write(dev, MC1, (MASK_13 | MASK_29)); /* end of budgetpatch register initialization */ + tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110); } else { saa7146_write(dev, PCI_BT_V1, 0x1c00101f); saa7146_write(dev, BCS_CTRL, 0x80400040); @@ -2377,7 +2377,6 @@ err_no_mem: saa7146_write(dev, GPIO_CTRL, 0x000000); } - tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110); tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110); tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110); @@ -2491,10 +2490,14 @@ static int av7110_detach(struct saa7146_dev* saa) if (!av7110->device_initialized ) return 0; - tasklet_kill(&av7110->vpe_tasklet); - if (budgetpatch) + if (budgetpatch) { + saa7146_write(saa, MC1, MASK_20); /* DMA3 off */ + SAA7146_IER_DISABLE(saa, MASK_10); + SAA7146_ISR_CLEAR(saa, MASK_10); + msleep(50); + tasklet_kill(&av7110->vpe_tasklet); saa7146_pgtable_free(saa->pci, &av7110->pt); - + } av7110_exit_v4l(av7110); av7110->arm_rmmod = 1; @@ -2503,6 +2506,9 @@ static int av7110_detach(struct saa7146_dev* saa) while (av7110->arm_thread) msleep(1); + tasklet_kill(&av7110->debi_tasklet); + tasklet_kill(&av7110->gpio_tasklet); + dvb_unregister(av7110); SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03); @@ -2568,7 +2574,7 @@ static void av7110_irq(struct saa7146_dev* dev, u32 *isr) tasklet_schedule(&av7110->gpio_tasklet); } - if (*isr & MASK_10) + if ((*isr & MASK_10) && budgetpatch) tasklet_schedule(&av7110->vpe_tasklet); } |