aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ngene/ngene-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/ngene/ngene-core.c')
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c80
1 files changed, 55 insertions, 25 deletions
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
index c8b4dfa0ab5f..4caeb163a666 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -53,8 +53,6 @@ MODULE_PARM_DESC(debug, "Print debugging information.");
53 53
54DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 54DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
55 55
56#define COMMAND_TIMEOUT_WORKAROUND
57
58#define dprintk if (debug) printk 56#define dprintk if (debug) printk
59 57
60#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) 58#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr)))
@@ -147,24 +145,24 @@ static void demux_tasklet(unsigned long data)
147 } else { 145 } else {
148 if (chan->HWState == HWSTATE_RUN) { 146 if (chan->HWState == HWSTATE_RUN) {
149 u32 Flags = 0; 147 u32 Flags = 0;
148 IBufferExchange *exch1 = chan->pBufferExchange;
149 IBufferExchange *exch2 = chan->pBufferExchange2;
150 if (Cur->ngeneBuffer.SR.Flags & 0x01) 150 if (Cur->ngeneBuffer.SR.Flags & 0x01)
151 Flags |= BEF_EVEN_FIELD; 151 Flags |= BEF_EVEN_FIELD;
152 if (Cur->ngeneBuffer.SR.Flags & 0x20) 152 if (Cur->ngeneBuffer.SR.Flags & 0x20)
153 Flags |= BEF_OVERFLOW; 153 Flags |= BEF_OVERFLOW;
154 if (chan->pBufferExchange) 154 spin_unlock_irq(&chan->state_lock);
155 chan->pBufferExchange(chan, 155 if (exch1)
156 Cur->Buffer1, 156 exch1(chan, Cur->Buffer1,
157 chan-> 157 chan->Capture1Length,
158 Capture1Length, 158 Cur->ngeneBuffer.SR.Clock,
159 Cur->ngeneBuffer. 159 Flags);
160 SR.Clock, Flags); 160 if (exch2)
161 if (chan->pBufferExchange2) 161 exch2(chan, Cur->Buffer2,
162 chan->pBufferExchange2(chan, 162 chan->Capture2Length,
163 Cur->Buffer2, 163 Cur->ngeneBuffer.SR.Clock,
164 chan-> 164 Flags);
165 Capture2Length, 165 spin_lock_irq(&chan->state_lock);
166 Cur->ngeneBuffer.
167 SR.Clock, Flags);
168 } else if (chan->HWState != HWSTATE_STOP) 166 } else if (chan->HWState != HWSTATE_STOP)
169 chan->HWState = HWSTATE_RUN; 167 chan->HWState = HWSTATE_RUN;
170 } 168 }
@@ -572,11 +570,7 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream,
572 u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700); 570 u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700);
573 u16 BsSDO = 0x9B00; 571 u16 BsSDO = 0x9B00;
574 572
575 /* down(&dev->stream_mutex); */ 573 down(&dev->stream_mutex);
576 while (down_trylock(&dev->stream_mutex)) {
577 printk(KERN_INFO DEVICE_NAME ": SC locked\n");
578 msleep(1);
579 }
580 memset(&com, 0, sizeof(com)); 574 memset(&com, 0, sizeof(com));
581 com.cmd.hdr.Opcode = CMD_CONTROL; 575 com.cmd.hdr.Opcode = CMD_CONTROL;
582 com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2; 576 com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2;
@@ -1252,14 +1246,17 @@ static int ngene_load_firm(struct ngene *dev)
1252 version = 15; 1246 version = 15;
1253 size = 23466; 1247 size = 23466;
1254 fw_name = "ngene_15.fw"; 1248 fw_name = "ngene_15.fw";
1249 dev->cmd_timeout_workaround = true;
1255 break; 1250 break;
1256 case 16: 1251 case 16:
1257 size = 23498; 1252 size = 23498;
1258 fw_name = "ngene_16.fw"; 1253 fw_name = "ngene_16.fw";
1254 dev->cmd_timeout_workaround = true;
1259 break; 1255 break;
1260 case 17: 1256 case 17:
1261 size = 24446; 1257 size = 24446;
1262 fw_name = "ngene_17.fw"; 1258 fw_name = "ngene_17.fw";
1259 dev->cmd_timeout_workaround = true;
1263 break; 1260 break;
1264 } 1261 }
1265 1262
@@ -1299,11 +1296,16 @@ static void ngene_stop(struct ngene *dev)
1299 ngwritel(0, NGENE_EVENT); 1296 ngwritel(0, NGENE_EVENT);
1300 ngwritel(0, NGENE_EVENT_HI); 1297 ngwritel(0, NGENE_EVENT_HI);
1301 free_irq(dev->pci_dev->irq, dev); 1298 free_irq(dev->pci_dev->irq, dev);
1299#ifdef CONFIG_PCI_MSI
1300 if (dev->msi_enabled)
1301 pci_disable_msi(dev->pci_dev);
1302#endif
1302} 1303}
1303 1304
1304static int ngene_start(struct ngene *dev) 1305static int ngene_start(struct ngene *dev)
1305{ 1306{
1306 int stat; 1307 int stat;
1308 unsigned long flags;
1307 int i; 1309 int i;
1308 1310
1309 pci_set_master(dev->pci_dev); 1311 pci_set_master(dev->pci_dev);
@@ -1333,6 +1335,28 @@ static int ngene_start(struct ngene *dev)
1333 if (stat < 0) 1335 if (stat < 0)
1334 goto fail; 1336 goto fail;
1335 1337
1338#ifdef CONFIG_PCI_MSI
1339 /* enable MSI if kernel and card support it */
1340 if (pci_msi_enabled() && dev->card_info->msi_supported) {
1341 ngwritel(0, NGENE_INT_ENABLE);
1342 free_irq(dev->pci_dev->irq, dev);
1343 stat = pci_enable_msi(dev->pci_dev);
1344 if (stat) {
1345 printk(KERN_INFO DEVICE_NAME
1346 ": MSI not available\n");
1347 flags = IRQF_SHARED;
1348 } else {
1349 flags = 0;
1350 dev->msi_enabled = true;
1351 }
1352 stat = request_irq(dev->pci_dev->irq, irq_handler,
1353 flags, "nGene", dev);
1354 if (stat < 0)
1355 goto fail2;
1356 ngwritel(1, NGENE_INT_ENABLE);
1357 }
1358#endif
1359
1336 stat = ngene_i2c_init(dev, 0); 1360 stat = ngene_i2c_init(dev, 0);
1337 if (stat < 0) 1361 if (stat < 0)
1338 goto fail; 1362 goto fail;
@@ -1358,10 +1382,18 @@ static int ngene_start(struct ngene *dev)
1358 bconf = BUFFER_CONFIG_3333; 1382 bconf = BUFFER_CONFIG_3333;
1359 stat = ngene_command_config_buf(dev, bconf); 1383 stat = ngene_command_config_buf(dev, bconf);
1360 } 1384 }
1361 return stat; 1385 if (!stat)
1386 return stat;
1387
1388 /* otherwise error: fall through */
1362fail: 1389fail:
1363 ngwritel(0, NGENE_INT_ENABLE); 1390 ngwritel(0, NGENE_INT_ENABLE);
1364 free_irq(dev->pci_dev->irq, dev); 1391 free_irq(dev->pci_dev->irq, dev);
1392#ifdef CONFIG_PCI_MSI
1393fail2:
1394 if (dev->msi_enabled)
1395 pci_disable_msi(dev->pci_dev);
1396#endif
1365 return stat; 1397 return stat;
1366} 1398}
1367 1399
@@ -1379,10 +1411,8 @@ static void release_channel(struct ngene_channel *chan)
1379 struct ngene_info *ni = dev->card_info; 1411 struct ngene_info *ni = dev->card_info;
1380 int io = ni->io_type[chan->number]; 1412 int io = ni->io_type[chan->number];
1381 1413
1382#ifdef COMMAND_TIMEOUT_WORKAROUND 1414 if (chan->dev->cmd_timeout_workaround && chan->running)
1383 if (chan->running)
1384 set_transfer(chan, 0); 1415 set_transfer(chan, 0);
1385#endif
1386 1416
1387 tasklet_kill(&chan->demux_tasklet); 1417 tasklet_kill(&chan->demux_tasklet);
1388 1418