diff options
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.c | 43 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvbdev.c | 3 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvbdev.h | 4 | ||||
-rw-r--r-- | drivers/media/video/cx23885/cx23885-dvb.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-dvb.c | 11 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-dvb.c | 2 | ||||
-rw-r--r-- | drivers/media/video/videobuf-dvb.c | 9 | ||||
-rw-r--r-- | include/media/videobuf-dvb.h | 6 |
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; | |||
47 | static int dvb_force_auto_inversion; | 47 | static int dvb_force_auto_inversion; |
48 | static int dvb_override_tune_delay; | 48 | static int dvb_override_tune_delay; |
49 | static int dvb_powerdown_on_sleep = 1; | 49 | static int dvb_powerdown_on_sleep = 1; |
50 | static int dvb_mfe_wait_time = 5; | ||
50 | 51 | ||
51 | module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); | 52 | module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); |
52 | MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); | 53 | MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); |
@@ -58,6 +59,8 @@ module_param(dvb_override_tune_delay, int, 0644); | |||
58 | MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); | 59 | MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); |
59 | module_param(dvb_powerdown_on_sleep, int, 0644); | 60 | module_param(dvb_powerdown_on_sleep, int, 0644); |
60 | MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)"); | 61 | MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)"); |
62 | module_param(dvb_mfe_wait_time, int, 0644); | ||
63 | MODULE_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 | ||
1737 | err2: | 1775 | err2: |
@@ -1739,6 +1777,9 @@ err2: | |||
1739 | err1: | 1777 | err1: |
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); |
1780 | err0: | ||
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 | ||
595 | static int dvb_register(struct cx8802_dev *dev) | 595 | static 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 | ||
1115 | frontend_detach: | 1112 | frontend_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 | ||
48 | void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f); | 49 | void 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 | ||
57 | int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, struct videobuf_dvb *dvb); | 59 | int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, struct videobuf_dvb *dvb); |
58 | 60 | ||