aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb')
-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
3 files changed, 49 insertions, 1 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