aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
authorAkihiro Tsukada <tskd2@yahoo.co.jp>2012-03-10 09:38:13 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-19 14:46:36 -0400
commit847e87659620890bfc80ce7bf682f2a5354543b2 (patch)
treeb9929128874639472b0892e58ab10eddc8db71e0 /drivers/media/dvb
parent2321acf2962514088c2230b6d54f7a56368576c5 (diff)
[media] dvb: earth-pt1: stop polling data when no one accesses the device
The driver started a kthread to poll the DMA buffers soon after probing, which relsuleted in 1000/sec sleeps and wakeups of the thread doing nothing useful until someone started feeding. This patch changes the creation and destruction of the kthread depending on the number of users. Signed-off-by: Akihiro Tsukada <tskd2@yahoo.co.jp> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb')
-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: