aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/pt1
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/pt1')
-rw-r--r--drivers/media/dvb/pt1/pt1.c73
1 files changed, 50 insertions, 23 deletions
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index b81df5fafe26..463f7849c44c 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -77,6 +77,8 @@ struct pt1 {
77 struct pt1_adapter *adaps[PT1_NR_ADAPS]; 77 struct pt1_adapter *adaps[PT1_NR_ADAPS];
78 struct pt1_table *tables; 78 struct pt1_table *tables;
79 struct task_struct *kthread; 79 struct task_struct *kthread;
80 int table_index;
81 int buf_index;
80 82
81 struct mutex lock; 83 struct mutex lock;
82 int power; 84 int power;
@@ -303,30 +305,25 @@ static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
303static int pt1_thread(void *data) 305static int pt1_thread(void *data)
304{ 306{
305 struct pt1 *pt1; 307 struct pt1 *pt1;
306 int table_index;
307 int buf_index;
308 struct pt1_buffer_page *page; 308 struct pt1_buffer_page *page;
309 309
310 pt1 = data; 310 pt1 = data;
311 set_freezable(); 311 set_freezable();
312 312
313 table_index = 0;
314 buf_index = 0;
315
316 while (!kthread_should_stop()) { 313 while (!kthread_should_stop()) {
317 try_to_freeze(); 314 try_to_freeze();
318 315
319 page = pt1->tables[table_index].bufs[buf_index].page; 316 page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page;
320 if (!pt1_filter(pt1, page)) { 317 if (!pt1_filter(pt1, page)) {
321 schedule_timeout_interruptible((HZ + 999) / 1000); 318 schedule_timeout_interruptible((HZ + 999) / 1000);
322 continue; 319 continue;
323 } 320 }
324 321
325 if (++buf_index >= PT1_NR_BUFS) { 322 if (++pt1->buf_index >= PT1_NR_BUFS) {
326 pt1_increment_table_count(pt1); 323 pt1_increment_table_count(pt1);
327 buf_index = 0; 324 pt1->buf_index = 0;
328 if (++table_index >= pt1_nr_tables) 325 if (++pt1->table_index >= pt1_nr_tables)
329 table_index = 0; 326 pt1->table_index = 0;
330 } 327 }
331 } 328 }
332 329
@@ -477,21 +474,60 @@ err:
477 return ret; 474 return ret;
478} 475}
479 476
477static int pt1_start_polling(struct pt1 *pt1)
478{
479 int ret = 0;
480
481 mutex_lock(&pt1->lock);
482 if (!pt1->kthread) {
483 pt1->kthread = kthread_run(pt1_thread, pt1, "earth-pt1");
484 if (IS_ERR(pt1->kthread)) {
485 ret = PTR_ERR(pt1->kthread);
486 pt1->kthread = NULL;
487 }
488 }
489 mutex_unlock(&pt1->lock);
490 return ret;
491}
492
480static int pt1_start_feed(struct dvb_demux_feed *feed) 493static int pt1_start_feed(struct dvb_demux_feed *feed)
481{ 494{
482 struct pt1_adapter *adap; 495 struct pt1_adapter *adap;
483 adap = container_of(feed->demux, struct pt1_adapter, demux); 496 adap = container_of(feed->demux, struct pt1_adapter, demux);
484 if (!adap->users++) 497 if (!adap->users++) {
498 int ret;
499
500 ret = pt1_start_polling(adap->pt1);
501 if (ret)
502 return ret;
485 pt1_set_stream(adap->pt1, adap->index, 1); 503 pt1_set_stream(adap->pt1, adap->index, 1);
504 }
486 return 0; 505 return 0;
487} 506}
488 507
508static void pt1_stop_polling(struct pt1 *pt1)
509{
510 int i, count;
511
512 mutex_lock(&pt1->lock);
513 for (i = 0, count = 0; i < PT1_NR_ADAPS; i++)
514 count += pt1->adaps[i]->users;
515
516 if (count == 0 && pt1->kthread) {
517 kthread_stop(pt1->kthread);
518 pt1->kthread = NULL;
519 }
520 mutex_unlock(&pt1->lock);
521}
522
489static int pt1_stop_feed(struct dvb_demux_feed *feed) 523static int pt1_stop_feed(struct dvb_demux_feed *feed)
490{ 524{
491 struct pt1_adapter *adap; 525 struct pt1_adapter *adap;
492 adap = container_of(feed->demux, struct pt1_adapter, demux); 526 adap = container_of(feed->demux, struct pt1_adapter, demux);
493 if (!--adap->users) 527 if (!--adap->users) {
494 pt1_set_stream(adap->pt1, adap->index, 0); 528 pt1_set_stream(adap->pt1, adap->index, 0);
529 pt1_stop_polling(adap->pt1);
530 }
495 return 0; 531 return 0;
496} 532}
497 533
@@ -1020,7 +1056,8 @@ static void __devexit pt1_remove(struct pci_dev *pdev)
1020 pt1 = pci_get_drvdata(pdev); 1056 pt1 = pci_get_drvdata(pdev);
1021 regs = pt1->regs; 1057 regs = pt1->regs;
1022 1058
1023 kthread_stop(pt1->kthread); 1059 if (pt1->kthread)
1060 kthread_stop(pt1->kthread);
1024 pt1_cleanup_tables(pt1); 1061 pt1_cleanup_tables(pt1);
1025 pt1_cleanup_frontends(pt1); 1062 pt1_cleanup_frontends(pt1);
1026 pt1_disable_ram(pt1); 1063 pt1_disable_ram(pt1);
@@ -1043,7 +1080,6 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1043 void __iomem *regs; 1080 void __iomem *regs;
1044 struct pt1 *pt1; 1081 struct pt1 *pt1;
1045 struct i2c_adapter *i2c_adap; 1082 struct i2c_adapter *i2c_adap;
1046 struct task_struct *kthread;
1047 1083
1048 ret = pci_enable_device(pdev); 1084 ret = pci_enable_device(pdev);
1049 if (ret < 0) 1085 if (ret < 0)
@@ -1139,17 +1175,8 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1139 if (ret < 0) 1175 if (ret < 0)
1140 goto err_pt1_cleanup_frontends; 1176 goto err_pt1_cleanup_frontends;
1141 1177
1142 kthread = kthread_run(pt1_thread, pt1, "pt1");
1143 if (IS_ERR(kthread)) {
1144 ret = PTR_ERR(kthread);
1145 goto err_pt1_cleanup_tables;
1146 }
1147
1148 pt1->kthread = kthread;
1149 return 0; 1178 return 0;
1150 1179
1151err_pt1_cleanup_tables:
1152 pt1_cleanup_tables(pt1);
1153err_pt1_cleanup_frontends: 1180err_pt1_cleanup_frontends:
1154 pt1_cleanup_frontends(pt1); 1181 pt1_cleanup_frontends(pt1);
1155err_pt1_disable_ram: 1182err_pt1_disable_ram: