aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c43
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h4
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c2
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c11
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c2
-rw-r--r--drivers/media/video/videobuf-dvb.c9
-rw-r--r--include/media/videobuf-dvb.h6
8 files changed, 65 insertions, 15 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 26671757c70b..62696f865576 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -47,6 +47,7 @@ static int dvb_shutdown_timeout;
47static int dvb_force_auto_inversion; 47static int dvb_force_auto_inversion;
48static int dvb_override_tune_delay; 48static int dvb_override_tune_delay;
49static int dvb_powerdown_on_sleep = 1; 49static int dvb_powerdown_on_sleep = 1;
50static int dvb_mfe_wait_time = 5;
50 51
51module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); 52module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
52MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); 53MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off).");
@@ -58,6 +59,8 @@ module_param(dvb_override_tune_delay, int, 0644);
58MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); 59MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
59module_param(dvb_powerdown_on_sleep, int, 0644); 60module_param(dvb_powerdown_on_sleep, int, 0644);
60MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)"); 61MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)");
62module_param(dvb_mfe_wait_time, int, 0644);
63MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open() for multi-frontend to become available (default:5 seconds)");
61 64
62#define dprintk if (dvb_frontend_debug) printk 65#define dprintk if (dvb_frontend_debug) printk
63 66
@@ -1706,13 +1709,46 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
1706 struct dvb_device *dvbdev = file->private_data; 1709 struct dvb_device *dvbdev = file->private_data;
1707 struct dvb_frontend *fe = dvbdev->priv; 1710 struct dvb_frontend *fe = dvbdev->priv;
1708 struct dvb_frontend_private *fepriv = fe->frontend_priv; 1711 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1712 struct dvb_adapter *adapter = fe->dvb;
1713 struct dvb_device *mfedev;
1714 struct dvb_frontend *mfe;
1715 struct dvb_frontend_private *mfepriv;
1716 int mferetry;
1709 int ret; 1717 int ret;
1710 1718
1711 dprintk ("%s\n", __func__); 1719 dprintk ("%s\n", __func__);
1712 1720
1721 if (adapter->mfe_shared) {
1722 mutex_lock (&adapter->mfe_lock);
1723 if (adapter->mfe_dvbdev != dvbdev) {
1724 if (adapter->mfe_dvbdev) {
1725 mfedev = adapter->mfe_dvbdev;
1726 mfe = mfedev->priv;
1727 mfepriv = mfe->frontend_priv;
1728 mutex_unlock (&adapter->mfe_lock);
1729 mferetry = (dvb_mfe_wait_time << 1);
1730 while (mferetry-- && (mfedev->users != -1 || mfepriv->thread != NULL)) {
1731 if(msleep_interruptible(500)) {
1732 if(signal_pending(current))
1733 return -EINTR;
1734 }
1735 }
1736 mutex_lock (&adapter->mfe_lock);
1737 mfedev = adapter->mfe_dvbdev;
1738 mfe = mfedev->priv;
1739 mfepriv = mfe->frontend_priv;
1740 if (mfedev->users != -1 || mfepriv->thread != NULL) {
1741 ret = -EBUSY;
1742 goto err0;
1743 }
1744 }
1745 adapter->mfe_dvbdev = dvbdev;
1746 }
1747 }
1748
1713 if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) { 1749 if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
1714 if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) 1750 if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
1715 return ret; 1751 goto err0;
1716 } 1752 }
1717 1753
1718 if ((ret = dvb_generic_open (inode, file)) < 0) 1754 if ((ret = dvb_generic_open (inode, file)) < 0)
@@ -1732,6 +1768,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
1732 fepriv->events.eventr = fepriv->events.eventw = 0; 1768 fepriv->events.eventr = fepriv->events.eventw = 0;
1733 } 1769 }
1734 1770
1771 if (adapter->mfe_shared)
1772 mutex_unlock (&adapter->mfe_lock);
1735 return ret; 1773 return ret;
1736 1774
1737err2: 1775err2:
@@ -1739,6 +1777,9 @@ err2:
1739err1: 1777err1:
1740 if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) 1778 if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
1741 fe->ops.ts_bus_ctrl(fe, 0); 1779 fe->ops.ts_bus_ctrl(fe, 0);
1780err0:
1781 if (adapter->mfe_shared)
1782 mutex_unlock (&adapter->mfe_lock);
1742 return ret; 1783 return ret;
1743} 1784}
1744 1785
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 665776d72a48..a113744a56cc 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -326,6 +326,9 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
326 adap->name = name; 326 adap->name = name;
327 adap->module = module; 327 adap->module = module;
328 adap->device = device; 328 adap->device = device;
329 adap->mfe_shared = 0;
330 adap->mfe_dvbdev = NULL;
331 mutex_init (&adap->mfe_lock);
329 332
330 list_add_tail (&adap->list_head, &dvb_adapter_list); 333 list_add_tail (&adap->list_head, &dvb_adapter_list);
331 334
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 89d12dc477a7..574e336bac35 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -62,6 +62,10 @@ struct dvb_adapter {
62 struct device *device; 62 struct device *device;
63 63
64 struct module *module; 64 struct module *module;
65
66 int mfe_shared; /* indicates mutually exclusive frontends */
67 struct dvb_device *mfe_dvbdev; /* frontend device in use */
68 struct mutex mfe_lock; /* access lock for thread creation */
65}; 69};
66 70
67 71
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index c14878f74bcc..78851526db68 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -556,7 +556,7 @@ static int dvb_register(struct cx23885_tsport *port)
556 556
557 /* register everything */ 557 /* register everything */
558 return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, 558 return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
559 &dev->pci->dev, adapter_nr); 559 &dev->pci->dev, adapter_nr, 0);
560 560
561} 561}
562 562
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 9bb7bee0da6d..0dd0ff9227fb 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -594,14 +594,9 @@ static struct stv0288_config tevii_tuner_earda_config = {
594 594
595static int dvb_register(struct cx8802_dev *dev) 595static int dvb_register(struct cx8802_dev *dev)
596{ 596{
597 //struct cx88_core *core = dev->core;
598
599 ///* init struct videobuf_dvb */
600 //fe->dvb.name = core->name;
601 //dev->ts_gen_cntrl = 0x0c;
602
603 struct cx88_core *core = dev->core; 597 struct cx88_core *core = dev->core;
604 struct videobuf_dvb_frontend *fe0, *fe1 = NULL; 598 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
599 int mfe_shared = 0; /* bus not shared by default */
605 600
606 /* Get the first frontend */ 601 /* Get the first frontend */
607 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); 602 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
@@ -669,6 +664,7 @@ static int dvb_register(struct cx8802_dev *dev)
669 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); 664 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
670 if (fe1) { 665 if (fe1) {
671 dev->frontends.gate = 2; 666 dev->frontends.gate = 2;
667 mfe_shared = 1;
672 fe1->dvb.frontend = dvb_attach(cx22702_attach, 668 fe1->dvb.frontend = dvb_attach(cx22702_attach,
673 &hauppauge_hvr_config, 669 &hauppauge_hvr_config,
674 &dev->core->i2c_adap); 670 &dev->core->i2c_adap);
@@ -1013,6 +1009,7 @@ static int dvb_register(struct cx8802_dev *dev)
1013 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); 1009 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1014 if (fe1) { 1010 if (fe1) {
1015 dev->frontends.gate = 2; 1011 dev->frontends.gate = 2;
1012 mfe_shared = 1;
1016 fe1->dvb.frontend = dvb_attach(cx22702_attach, 1013 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1017 &hauppauge_hvr_config, 1014 &hauppauge_hvr_config,
1018 &dev->core->i2c_adap); 1015 &dev->core->i2c_adap);
@@ -1110,7 +1107,7 @@ static int dvb_register(struct cx8802_dev *dev)
1110 1107
1111 /* register everything */ 1108 /* register everything */
1112 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, 1109 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1113 &dev->pci->dev, adapter_nr); 1110 &dev->pci->dev, adapter_nr, mfe_shared);
1114 1111
1115frontend_detach: 1112frontend_detach:
1116 if (fe0->dvb.frontend) { 1113 if (fe0->dvb.frontend) {
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 30ae0cbe78a0..d2d238912fbf 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1395,7 +1395,7 @@ static int dvb_init(struct saa7134_dev *dev)
1395 1395
1396 /* register everything else */ 1396 /* register everything else */
1397 ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, 1397 ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1398 &dev->pci->dev, adapter_nr); 1398 &dev->pci->dev, adapter_nr, 0);
1399 1399
1400 /* this sequence is necessary to make the tda1004x load its firmware 1400 /* this sequence is necessary to make the tda1004x load its firmware
1401 * and to enter analog mode of hybrid boards 1401 * and to enter analog mode of hybrid boards
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index a0a80e1e79e3..af0b75cda6fd 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -140,7 +140,8 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
140 struct module *module, 140 struct module *module,
141 void *adapter_priv, 141 void *adapter_priv,
142 struct device *device, 142 struct device *device,
143 short *adapter_nr) //NEW 143 short *adapter_nr,
144 int mfe_shared)
144{ 145{
145 struct list_head *list, *q; 146 struct list_head *list, *q;
146 struct videobuf_dvb_frontend *fe; 147 struct videobuf_dvb_frontend *fe;
@@ -153,7 +154,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
153 } 154 }
154 155
155 /* Bring up the adapter */ 156 /* Bring up the adapter */
156 res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, fe->dvb.name, adapter_nr); //NEW 157 res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, fe->dvb.name, adapter_nr, mfe_shared);
157 if (res < 0) { 158 if (res < 0) {
158 printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res); 159 printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
159 goto err; 160 goto err;
@@ -181,7 +182,8 @@ int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
181 void *adapter_priv, 182 void *adapter_priv,
182 struct device *device, 183 struct device *device,
183 char *adapter_name, 184 char *adapter_name,
184 short *adapter_nr) //NEW 185 short *adapter_nr,
186 int mfe_shared)
185{ 187{
186 int result; 188 int result;
187 189
@@ -194,6 +196,7 @@ int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
194 adapter_name, result); 196 adapter_name, result);
195 } 197 }
196 fe->adapter.priv = adapter_priv; 198 fe->adapter.priv = adapter_priv;
199 fe->adapter.mfe_shared = mfe_shared;
197 200
198 return result; 201 return result;
199} 202}
diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h
index 47bc2c5e7ba9..1a401f7320b9 100644
--- a/include/media/videobuf-dvb.h
+++ b/include/media/videobuf-dvb.h
@@ -43,7 +43,8 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
43 struct module *module, 43 struct module *module,
44 void *adapter_priv, 44 void *adapter_priv,
45 struct device *device, 45 struct device *device,
46 short *adapter_nr); //NEW 46 short *adapter_nr,
47 int mfe_shared);
47 48
48void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f); 49void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f);
49 50
@@ -52,7 +53,8 @@ int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *f,
52 void *adapter_priv, 53 void *adapter_priv,
53 struct device *device, 54 struct device *device,
54 char *adapter_name, 55 char *adapter_name,
55 short *adapter_nr); //NEW 56 short *adapter_nr,
57 int mfe_shared);
56 58
57int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, struct videobuf_dvb *dvb); 59int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, struct videobuf_dvb *dvb);
58 60