diff options
Diffstat (limited to 'drivers/media/dvb')
-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 |
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; | |||
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 | ||