linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table()
@ 2016-08-09 21:32 Max Kellermann
  2016-08-09 21:32 ` [PATCH 02/12] [media] dvbdev: split dvb_unregister_device() Max Kellermann
                   ` (11 more replies)
  0 siblings, 12 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

rc_unregister_device() will first call ir_free_table(), and later
device_del(); however, the latter causes a call to rc_dev_uevent(),
which prints rc_map.name, which at this point has already bee freed.

This fixes a use-after-free bug found with KASAN.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/rc/rc-main.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 8e7f292..1e5a520 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -159,6 +159,7 @@ static void ir_free_table(struct rc_map *rc_map)
 {
 	rc_map->size = 0;
 	kfree(rc_map->name);
+	rc_map->name = NULL;
 	kfree(rc_map->scan);
 	rc_map->scan = NULL;
 }

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 02/12] [media] dvbdev: split dvb_unregister_device()
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
@ 2016-08-09 21:32 ` Max Kellermann
  2016-08-09 21:32 ` [PATCH 03/12] [media] dvb-core/en50221: use dvb_remove_device() Max Kellermann
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

dvb_unregister_device() has a major problem: it combines unregistering
with memory disposal.  Sometimes, it is necessary to unregister a
device, but no memory can be freed yet, because a process still has a
(stale) file handle.  Therefore, we need to split
dvb_unregister_device().  This will allow sanitizing a few callers.

With my new design, dvb_unregister_device() appears misnamed, but to
reduce patch noise, I'm not renaming it just yet.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/dvb-core/dvbdev.c |   19 ++++++++++++++++++-
 drivers/media/dvb-core/dvbdev.h |   23 +++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 75a3f4b..1bc2dba 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -523,7 +523,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 EXPORT_SYMBOL(dvb_register_device);
 
 
-void dvb_unregister_device(struct dvb_device *dvbdev)
+void dvb_remove_device(struct dvb_device *dvbdev)
 {
 	if (!dvbdev)
 		return;
@@ -537,9 +537,26 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
 	device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
 
 	list_del (&dvbdev->list_head);
+}
+EXPORT_SYMBOL(dvb_remove_device);
+
+
+void dvb_free_device(struct dvb_device *dvbdev)
+{
+	if (!dvbdev)
+		return;
+
 	kfree (dvbdev->fops);
 	kfree (dvbdev);
 }
+EXPORT_SYMBOL(dvb_free_device);
+
+
+void dvb_unregister_device(struct dvb_device *dvbdev)
+{
+	dvb_remove_device(dvbdev);
+	dvb_free_device(dvbdev);
+}
 EXPORT_SYMBOL(dvb_unregister_device);
 
 
diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h
index 4aff7bd..576bbd4 100644
--- a/drivers/media/dvb-core/dvbdev.h
+++ b/drivers/media/dvb-core/dvbdev.h
@@ -212,8 +212,31 @@ int dvb_register_device(struct dvb_adapter *adap,
 			int demux_sink_pads);
 
 /**
+ * dvb_remove_device - Remove a registered DVB device
+ *
+ * This does not free memory.  To do that, call dvb_free_device().
+ *
+ * @dvbdev:	pointer to struct dvb_device
+ */
+void dvb_remove_device(struct dvb_device *dvbdev);
+
+/**
+ * dvb_free_device - Free memory occupied by a DVB device.
+ *
+ * Call dvb_unregister_device() before calling this function.
+ *
+ * @dvbdev:	pointer to struct dvb_device
+ */
+void dvb_free_device(struct dvb_device *dvbdev);
+
+/**
  * dvb_unregister_device - Unregisters a DVB device
  *
+ * This is a combination of dvb_remove_device() and dvb_free_device().
+ * Using this function is usually a mistake, and is often an indicator
+ * for a use-after-free bug (when a userspace process keeps a file
+ * handle to a detached device).
+ *
  * @dvbdev:	pointer to struct dvb_device
  */
 void dvb_unregister_device(struct dvb_device *dvbdev);

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 03/12] [media] dvb-core/en50221: use dvb_remove_device()
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
  2016-08-09 21:32 ` [PATCH 02/12] [media] dvbdev: split dvb_unregister_device() Max Kellermann
@ 2016-08-09 21:32 ` Max Kellermann
  2016-08-09 21:32 ` [PATCH 04/12] [media] dvb: make DVB frontend *_ops instances "const" Max Kellermann
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

Commit da677fe14364 ("[media] dvb-core/en50221: use kref to manage
struct dvb_ca_private") moved the dvb_unregister_device() call to the
kref callback, but that left lots of stale device state visible to
userspace (e.g. in sysfs).  By using dvb_remove_device() and
dvb_free_device() instead of dvb_unregister_device(), we can avoid
that.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/dvb-core/dvb_ca_en50221.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
index b5b5b19..09e759c 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
@@ -166,7 +166,7 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca)
 {
 	unsigned int i;
 
-	dvb_unregister_device(ca->dvbdev);
+	dvb_free_device(ca->dvbdev);
 	for (i = 0; i < ca->slot_count; i++)
 		vfree(ca->slot_info[i].rx_buffer.data);
 
@@ -1794,6 +1794,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
 	for (i = 0; i < ca->slot_count; i++) {
 		dvb_ca_en50221_slot_shutdown(ca, i);
 	}
+	dvb_remove_device(ca->dvbdev);
 	dvb_ca_private_put(ca);
 	pubca->private = NULL;
 }

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 04/12] [media] dvb: make DVB frontend *_ops instances "const"
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
  2016-08-09 21:32 ` [PATCH 02/12] [media] dvbdev: split dvb_unregister_device() Max Kellermann
  2016-08-09 21:32 ` [PATCH 03/12] [media] dvb-core/en50221: use dvb_remove_device() Max Kellermann
@ 2016-08-09 21:32 ` Max Kellermann
  2016-08-09 21:32 ` [PATCH 05/12] [media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations Max Kellermann
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

These are immutable.  Making them "const" allows the compiler to move
them to the "rodata" section.

Note that cxd2841er_t_c_ops cannot be made "const", because
cxd2841er_attach() modifies it.  Ouch!

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/common/siano/smsdvb-main.c      |    2 +-
 drivers/media/dvb-frontends/af9013.c          |    4 ++--
 drivers/media/dvb-frontends/af9033.c          |    2 +-
 drivers/media/dvb-frontends/as102_fe.c        |    2 +-
 drivers/media/dvb-frontends/ascot2e.c         |    2 +-
 drivers/media/dvb-frontends/atbm8830.c        |    2 +-
 drivers/media/dvb-frontends/au8522_dig.c      |    4 ++--
 drivers/media/dvb-frontends/bcm3510.c         |    4 ++--
 drivers/media/dvb-frontends/cx22700.c         |    4 ++--
 drivers/media/dvb-frontends/cx24110.c         |    4 ++--
 drivers/media/dvb-frontends/cx24116.c         |    4 ++--
 drivers/media/dvb-frontends/cx24117.c         |    4 ++--
 drivers/media/dvb-frontends/cx24120.c         |    4 ++--
 drivers/media/dvb-frontends/cx24123.c         |    4 ++--
 drivers/media/dvb-frontends/cxd2841er.c       |    4 ++--
 drivers/media/dvb-frontends/dib3000mb.c       |    4 ++--
 drivers/media/dvb-frontends/dib3000mc.c       |    4 ++--
 drivers/media/dvb-frontends/dib7000m.c        |    4 ++--
 drivers/media/dvb-frontends/dib7000p.c        |    4 ++--
 drivers/media/dvb-frontends/dib9000.c         |    4 ++--
 drivers/media/dvb-frontends/drx39xyj/drxj.c   |    4 ++--
 drivers/media/dvb-frontends/drxd_hard.c       |    2 +-
 drivers/media/dvb-frontends/drxk_hard.c       |    2 +-
 drivers/media/dvb-frontends/ds3000.c          |    4 ++--
 drivers/media/dvb-frontends/dvb-pll.c         |    2 +-
 drivers/media/dvb-frontends/dvb_dummy_fe.c    |   12 ++++++------
 drivers/media/dvb-frontends/ec100.c           |    4 ++--
 drivers/media/dvb-frontends/hd29l2.c          |    4 ++--
 drivers/media/dvb-frontends/helene.c          |    4 ++--
 drivers/media/dvb-frontends/horus3a.c         |    2 +-
 drivers/media/dvb-frontends/ix2505v.c         |    2 +-
 drivers/media/dvb-frontends/l64781.c          |    4 ++--
 drivers/media/dvb-frontends/lg2160.c          |    4 ++--
 drivers/media/dvb-frontends/lgdt3305.c        |    8 ++++----
 drivers/media/dvb-frontends/lgdt3306a.c       |    4 ++--
 drivers/media/dvb-frontends/lgdt330x.c        |    8 ++++----
 drivers/media/dvb-frontends/lgs8gl5.c         |    4 ++--
 drivers/media/dvb-frontends/lgs8gxx.c         |    2 +-
 drivers/media/dvb-frontends/m88ds3103.c       |    4 ++--
 drivers/media/dvb-frontends/m88rs2000.c       |    2 +-
 drivers/media/dvb-frontends/mb86a16.c         |    2 +-
 drivers/media/dvb-frontends/mb86a20s.c        |    4 ++--
 drivers/media/dvb-frontends/mn88472.c         |    2 +-
 drivers/media/dvb-frontends/mt312.c           |    2 +-
 drivers/media/dvb-frontends/mt352.c           |    4 ++--
 drivers/media/dvb-frontends/nxt200x.c         |    4 ++--
 drivers/media/dvb-frontends/nxt6000.c         |    4 ++--
 drivers/media/dvb-frontends/or51132.c         |    4 ++--
 drivers/media/dvb-frontends/or51211.c         |    4 ++--
 drivers/media/dvb-frontends/rtl2830.c         |    2 +-
 drivers/media/dvb-frontends/rtl2832.c         |    2 +-
 drivers/media/dvb-frontends/s5h1409.c         |    4 ++--
 drivers/media/dvb-frontends/s5h1411.c         |    4 ++--
 drivers/media/dvb-frontends/s5h1420.c         |    4 ++--
 drivers/media/dvb-frontends/s5h1432.c         |    4 ++--
 drivers/media/dvb-frontends/s921.c            |    4 ++--
 drivers/media/dvb-frontends/si2165.c          |    2 +-
 drivers/media/dvb-frontends/si21xx.c          |    2 +-
 drivers/media/dvb-frontends/sp8870.c          |    4 ++--
 drivers/media/dvb-frontends/sp887x.c          |    4 ++--
 drivers/media/dvb-frontends/stb0899_drv.c     |    2 +-
 drivers/media/dvb-frontends/stb6000.c         |    2 +-
 drivers/media/dvb-frontends/stb6100.c         |    2 +-
 drivers/media/dvb-frontends/stv0288.c         |    2 +-
 drivers/media/dvb-frontends/stv0297.c         |    4 ++--
 drivers/media/dvb-frontends/stv0299.c         |    4 ++--
 drivers/media/dvb-frontends/stv0367.c         |    4 ++--
 drivers/media/dvb-frontends/stv0900_core.c    |    2 +-
 drivers/media/dvb-frontends/stv090x.c         |    2 +-
 drivers/media/dvb-frontends/stv6110.c         |    2 +-
 drivers/media/dvb-frontends/stv6110x.c        |    2 +-
 drivers/media/dvb-frontends/tda10021.c        |    4 ++--
 drivers/media/dvb-frontends/tda10023.c        |    4 ++--
 drivers/media/dvb-frontends/tda10048.c        |    4 ++--
 drivers/media/dvb-frontends/tda1004x.c        |    4 ++--
 drivers/media/dvb-frontends/tda10071.c        |    4 ++--
 drivers/media/dvb-frontends/tda10086.c        |    2 +-
 drivers/media/dvb-frontends/tda18271c2dd.c    |    2 +-
 drivers/media/dvb-frontends/tda665x.c         |    2 +-
 drivers/media/dvb-frontends/tda8083.c         |    4 ++--
 drivers/media/dvb-frontends/tda8261.c         |    2 +-
 drivers/media/dvb-frontends/tda826x.c         |    2 +-
 drivers/media/dvb-frontends/ts2020.c          |    2 +-
 drivers/media/dvb-frontends/tua6100.c         |    2 +-
 drivers/media/dvb-frontends/ves1820.c         |    4 ++--
 drivers/media/dvb-frontends/ves1x93.c         |    4 ++--
 drivers/media/dvb-frontends/zl10036.c         |    2 +-
 drivers/media/dvb-frontends/zl10039.c         |    2 +-
 drivers/media/dvb-frontends/zl10353.c         |    4 ++--
 drivers/media/pci/bt8xx/dst.c                 |   16 ++++++++--------
 drivers/media/pci/pt1/va1j5jf8007s.c          |    2 +-
 drivers/media/pci/pt1/va1j5jf8007t.c          |    2 +-
 drivers/media/tuners/mt2063.c                 |    2 +-
 drivers/media/tuners/mt20xx.c                 |    4 ++--
 drivers/media/tuners/mxl5007t.c               |    2 +-
 drivers/media/tuners/tda827x.c                |    4 ++--
 drivers/media/tuners/tda8290.c                |    4 ++--
 drivers/media/tuners/tda9887.c                |    2 +-
 drivers/media/tuners/tea5761.c                |    2 +-
 drivers/media/tuners/tea5767.c                |    2 +-
 drivers/media/tuners/tuner-simple.c           |    2 +-
 drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c |    2 +-
 drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c |    2 +-
 drivers/media/usb/dvb-usb/af9005-fe.c         |    4 ++--
 drivers/media/usb/dvb-usb/cinergyT2-fe.c      |    4 ++--
 drivers/media/usb/dvb-usb/dtt200u-fe.c        |    4 ++--
 drivers/media/usb/dvb-usb/friio-fe.c          |    4 ++--
 drivers/media/usb/dvb-usb/gp8psk-fe.c         |    4 ++--
 drivers/media/usb/dvb-usb/vp702x-fe.c         |    4 ++--
 drivers/media/usb/dvb-usb/vp7045-fe.c         |    4 ++--
 drivers/media/usb/ttusb-dec/ttusbdecfe.c      |    8 ++++----
 111 files changed, 192 insertions(+), 192 deletions(-)

diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c
index 9148e14..affde14 100644
--- a/drivers/media/common/siano/smsdvb-main.c
+++ b/drivers/media/common/siano/smsdvb-main.c
@@ -1044,7 +1044,7 @@ static void smsdvb_release(struct dvb_frontend *fe)
 	/* do nothing */
 }
 
-static struct dvb_frontend_ops smsdvb_fe_ops = {
+static const struct dvb_frontend_ops smsdvb_fe_ops = {
 	.info = {
 		.name			= "Siano Mobile Digital MDTV Receiver",
 		.frequency_min		= 44250000,
diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c
index 8bcde33..c6cb3bb 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -1351,7 +1351,7 @@ static void af9013_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops af9013_ops;
+static const struct dvb_frontend_ops af9013_ops;
 
 static int af9013_download_firmware(struct af9013_state *state)
 {
@@ -1516,7 +1516,7 @@ err:
 }
 EXPORT_SYMBOL(af9013_attach);
 
-static struct dvb_frontend_ops af9013_ops = {
+static const struct dvb_frontend_ops af9013_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "Afatech AF9013",
diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c
index 9a8157a..f881802 100644
--- a/drivers/media/dvb-frontends/af9033.c
+++ b/drivers/media/dvb-frontends/af9033.c
@@ -1198,7 +1198,7 @@ err:
 	return ret;
 }
 
-static struct dvb_frontend_ops af9033_ops = {
+static const struct dvb_frontend_ops af9033_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "Afatech AF9033 (DVB-T)",
diff --git a/drivers/media/dvb-frontends/as102_fe.c b/drivers/media/dvb-frontends/as102_fe.c
index 9412fcd..98d575f 100644
--- a/drivers/media/dvb-frontends/as102_fe.c
+++ b/drivers/media/dvb-frontends/as102_fe.c
@@ -415,7 +415,7 @@ static void as102_fe_release(struct dvb_frontend *fe)
 }
 
 
-static struct dvb_frontend_ops as102_fe_ops = {
+static const struct dvb_frontend_ops as102_fe_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "Abilis AS102 DVB-T",
diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c
index 8cc8c45..ad304ee 100644
--- a/drivers/media/dvb-frontends/ascot2e.c
+++ b/drivers/media/dvb-frontends/ascot2e.c
@@ -464,7 +464,7 @@ static int ascot2e_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static struct dvb_tuner_ops ascot2e_tuner_ops = {
+static const struct dvb_tuner_ops ascot2e_tuner_ops = {
 	.info = {
 		.name = "Sony ASCOT2E",
 		.frequency_min = 1000000,
diff --git a/drivers/media/dvb-frontends/atbm8830.c b/drivers/media/dvb-frontends/atbm8830.c
index 47248b8..07ce055 100644
--- a/drivers/media/dvb-frontends/atbm8830.c
+++ b/drivers/media/dvb-frontends/atbm8830.c
@@ -428,7 +428,7 @@ static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 	return atbm8830_write_reg(priv, REG_I2C_GATE, enable ? 1 : 0);
 }
 
-static struct dvb_frontend_ops atbm8830_ops = {
+static const struct dvb_frontend_ops atbm8830_ops = {
 	.delsys = { SYS_DTMB },
 	.info = {
 		.name = "AltoBeam ATBM8830/8831 DMB-TH",
diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
index e676b94..7ed326e 100644
--- a/drivers/media/dvb-frontends/au8522_dig.c
+++ b/drivers/media/dvb-frontends/au8522_dig.c
@@ -834,7 +834,7 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe,
 	return 0;
 }
 
-static struct dvb_frontend_ops au8522_ops;
+static const struct dvb_frontend_ops au8522_ops;
 
 
 static void au8522_release(struct dvb_frontend *fe)
@@ -894,7 +894,7 @@ error:
 }
 EXPORT_SYMBOL(au8522_attach);
 
-static struct dvb_frontend_ops au8522_ops = {
+static const struct dvb_frontend_ops au8522_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name			= "Auvitek AU8522 QAM/8VSB Frontend",
diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c
index bb69883..617c5e2 100644
--- a/drivers/media/dvb-frontends/bcm3510.c
+++ b/drivers/media/dvb-frontends/bcm3510.c
@@ -788,7 +788,7 @@ static int bcm3510_init(struct dvb_frontend* fe)
 }
 
 
-static struct dvb_frontend_ops bcm3510_ops;
+static const struct dvb_frontend_ops bcm3510_ops;
 
 struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
 				   struct i2c_adapter *i2c)
@@ -834,7 +834,7 @@ error:
 }
 EXPORT_SYMBOL(bcm3510_attach);
 
-static struct dvb_frontend_ops bcm3510_ops = {
+static const struct dvb_frontend_ops bcm3510_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name = "Broadcom BCM3510 VSB/QAM frontend",
diff --git a/drivers/media/dvb-frontends/cx22700.c b/drivers/media/dvb-frontends/cx22700.c
index 5cad925..2b629e2 100644
--- a/drivers/media/dvb-frontends/cx22700.c
+++ b/drivers/media/dvb-frontends/cx22700.c
@@ -380,7 +380,7 @@ static void cx22700_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops cx22700_ops;
+static const struct dvb_frontend_ops cx22700_ops;
 
 struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
 				    struct i2c_adapter* i2c)
@@ -408,7 +408,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops cx22700_ops = {
+static const struct dvb_frontend_ops cx22700_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "Conexant CX22700 DVB-T",
diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c
index 6cb81ec..5ee05b2 100644
--- a/drivers/media/dvb-frontends/cx24110.c
+++ b/drivers/media/dvb-frontends/cx24110.c
@@ -592,7 +592,7 @@ static void cx24110_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops cx24110_ops;
+static const struct dvb_frontend_ops cx24110_ops;
 
 struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
 				    struct i2c_adapter* i2c)
@@ -625,7 +625,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops cx24110_ops = {
+static const struct dvb_frontend_ops cx24110_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name = "Conexant CX24110 DVB-S",
diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c
index 8814f36..57928e0 100644
--- a/drivers/media/dvb-frontends/cx24116.c
+++ b/drivers/media/dvb-frontends/cx24116.c
@@ -1116,7 +1116,7 @@ static void cx24116_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops cx24116_ops;
+static const struct dvb_frontend_ops cx24116_ops;
 
 struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
 	struct i2c_adapter *i2c)
@@ -1467,7 +1467,7 @@ static int cx24116_get_algo(struct dvb_frontend *fe)
 	return DVBFE_ALGO_HW;
 }
 
-static struct dvb_frontend_ops cx24116_ops = {
+static const struct dvb_frontend_ops cx24116_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2 },
 	.info = {
 		.name = "Conexant CX24116/CX24118",
diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c
index a3f7eb4..d0478bd 100644
--- a/drivers/media/dvb-frontends/cx24117.c
+++ b/drivers/media/dvb-frontends/cx24117.c
@@ -1164,7 +1164,7 @@ static void cx24117_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops cx24117_ops;
+static const struct dvb_frontend_ops cx24117_ops;
 
 struct dvb_frontend *cx24117_attach(const struct cx24117_config *config,
 	struct i2c_adapter *i2c)
@@ -1618,7 +1618,7 @@ static int cx24117_get_frontend(struct dvb_frontend *fe,
 	return 0;
 }
 
-static struct dvb_frontend_ops cx24117_ops = {
+static const struct dvb_frontend_ops cx24117_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2 },
 	.info = {
 		.name = "Conexant CX24117/CX24132",
diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c
index 066ee38..79ede21 100644
--- a/drivers/media/dvb-frontends/cx24120.c
+++ b/drivers/media/dvb-frontends/cx24120.c
@@ -267,7 +267,7 @@ out:
 	return ret;
 }
 
-static struct dvb_frontend_ops cx24120_ops;
+static const struct dvb_frontend_ops cx24120_ops;
 
 struct dvb_frontend *cx24120_attach(const struct cx24120_config *config,
 				    struct i2c_adapter *i2c)
@@ -1552,7 +1552,7 @@ static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 	return 0;
 }
 
-static struct dvb_frontend_ops cx24120_ops = {
+static const struct dvb_frontend_ops cx24120_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2 },
 	.info = {
 		.name = "Conexant CX24120/CX24118",
diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c
index 113b094..0e807c3 100644
--- a/drivers/media/dvb-frontends/cx24123.c
+++ b/drivers/media/dvb-frontends/cx24123.c
@@ -1049,7 +1049,7 @@ struct i2c_adapter *
 }
 EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter);
 
-static struct dvb_frontend_ops cx24123_ops;
+static const struct dvb_frontend_ops cx24123_ops;
 
 struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
 				    struct i2c_adapter *i2c)
@@ -1111,7 +1111,7 @@ error:
 }
 EXPORT_SYMBOL(cx24123_attach);
 
-static struct dvb_frontend_ops cx24123_ops = {
+static const struct dvb_frontend_ops cx24123_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name = "Conexant CX24123/CX24109",
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index ffe88bc..2f7f335 100644
--- a/drivers/media/dvb-frontends/cxd2841er.c
+++ b/drivers/media/dvb-frontends/cxd2841er.c
@@ -3641,7 +3641,7 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe)
 	return 0;
 }
 
-static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops;
+static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops;
 static struct dvb_frontend_ops cxd2841er_t_c_ops;
 
 static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
@@ -3723,7 +3723,7 @@ struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg,
 }
 EXPORT_SYMBOL(cxd2841er_attach_t_c);
 
-static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = {
+static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2 },
 	.info = {
 		.name		= "Sony CXD2841ER DVB-S/S2 demodulator",
diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c
index 6821ecb..5d7c55e 100644
--- a/drivers/media/dvb-frontends/dib3000mb.c
+++ b/drivers/media/dvb-frontends/dib3000mb.c
@@ -751,7 +751,7 @@ static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_
 	return 0;
 }
 
-static struct dvb_frontend_ops dib3000mb_ops;
+static const struct dvb_frontend_ops dib3000mb_ops;
 
 struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
 				      struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
@@ -791,7 +791,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops dib3000mb_ops = {
+static const struct dvb_frontend_ops dib3000mb_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "DiBcom 3000M-B DVB-T",
diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c
index da0f1dc..564297d 100644
--- a/drivers/media/dvb-frontends/dib3000mc.c
+++ b/drivers/media/dvb-frontends/dib3000mc.c
@@ -873,7 +873,7 @@ int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defa
 }
 EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
 
-static struct dvb_frontend_ops dib3000mc_ops;
+static const struct dvb_frontend_ops dib3000mc_ops;
 
 struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
 {
@@ -906,7 +906,7 @@ error:
 }
 EXPORT_SYMBOL(dib3000mc_attach);
 
-static struct dvb_frontend_ops dib3000mc_ops = {
+static const struct dvb_frontend_ops dib3000mc_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "DiBcom 3000MC/P",
diff --git a/drivers/media/dvb-frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c
index b3ddae8..41e1ea6c 100644
--- a/drivers/media/dvb-frontends/dib7000m.c
+++ b/drivers/media/dvb-frontends/dib7000m.c
@@ -1394,7 +1394,7 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
 EXPORT_SYMBOL(dib7000m_i2c_enumeration);
 #endif
 
-static struct dvb_frontend_ops dib7000m_ops;
+static const struct dvb_frontend_ops dib7000m_ops;
 struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
 {
 	struct dvb_frontend *demod;
@@ -1432,7 +1432,7 @@ error:
 }
 EXPORT_SYMBOL(dib7000m_attach);
 
-static struct dvb_frontend_ops dib7000m_ops = {
+static const struct dvb_frontend_ops dib7000m_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "DiBcom 7000MA/MB/PA/PB/MC",
diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c
index b861d44..95fa6f3 100644
--- a/drivers/media/dvb-frontends/dib7000p.c
+++ b/drivers/media/dvb-frontends/dib7000p.c
@@ -2714,7 +2714,7 @@ static int dib7090_slave_reset(struct dvb_frontend *fe)
 	return 0;
 }
 
-static struct dvb_frontend_ops dib7000p_ops;
+static const struct dvb_frontend_ops dib7000p_ops;
 static struct dvb_frontend *dib7000p_init(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
 {
 	struct dvb_frontend *demod;
@@ -2804,7 +2804,7 @@ void *dib7000p_attach(struct dib7000p_ops *ops)
 }
 EXPORT_SYMBOL(dib7000p_attach);
 
-static struct dvb_frontend_ops dib7000p_ops = {
+static const struct dvb_frontend_ops dib7000p_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		 .name = "DiBcom 7000PC",
diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c
index 5897977..cd1f0e0 100644
--- a/drivers/media/dvb-frontends/dib9000.c
+++ b/drivers/media/dvb-frontends/dib9000.c
@@ -2483,7 +2483,7 @@ struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int sla
 }
 EXPORT_SYMBOL(dib9000_get_slave_frontend);
 
-static struct dvb_frontend_ops dib9000_ops;
+static const struct dvb_frontend_ops dib9000_ops;
 struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg)
 {
 	struct dvb_frontend *fe;
@@ -2560,7 +2560,7 @@ error:
 }
 EXPORT_SYMBOL(dib9000_attach);
 
-static struct dvb_frontend_ops dib9000_ops = {
+static const struct dvb_frontend_ops dib9000_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		 .name = "DiBcom 9000",
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index bd6d2ee..f1c3e3b 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -12264,7 +12264,7 @@ static void drx39xxj_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops drx39xxj_ops;
+static const struct dvb_frontend_ops drx39xxj_ops;
 
 struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
 {
@@ -12363,7 +12363,7 @@ error:
 }
 EXPORT_SYMBOL(drx39xxj_attach);
 
-static struct dvb_frontend_ops drx39xxj_ops = {
+static const struct dvb_frontend_ops drx39xxj_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		 .name = "Micronas DRX39xxj family Frontend",
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c
index 445a15c..4143f03 100644
--- a/drivers/media/dvb-frontends/drxd_hard.c
+++ b/drivers/media/dvb-frontends/drxd_hard.c
@@ -2912,7 +2912,7 @@ static void drxd_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops drxd_ops = {
+static const struct dvb_frontend_ops drxd_ops = {
 	.delsys = { SYS_DVBT},
 	.info = {
 		 .name = "Micronas DRXD DVB-T",
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index b975da0..901b1f1 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -6737,7 +6737,7 @@ static int drxk_get_tune_settings(struct dvb_frontend *fe,
 	}
 }
 
-static struct dvb_frontend_ops drxk_ops = {
+static const struct dvb_frontend_ops drxk_ops = {
 	/* .delsys will be filled dynamically */
 	.info = {
 		.name = "DRXK",
diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c
index 447b518..3764e91 100644
--- a/drivers/media/dvb-frontends/ds3000.c
+++ b/drivers/media/dvb-frontends/ds3000.c
@@ -830,7 +830,7 @@ static void ds3000_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops ds3000_ops;
+static const struct dvb_frontend_ops ds3000_ops;
 
 struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
 				    struct i2c_adapter *i2c)
@@ -1104,7 +1104,7 @@ static int ds3000_initfe(struct dvb_frontend *fe)
 	return 0;
 }
 
-static struct dvb_frontend_ops ds3000_ops = {
+static const struct dvb_frontend_ops ds3000_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2 },
 	.info = {
 		.name = "Montage Technology DS3000",
diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c
index 53089e1..735a966 100644
--- a/drivers/media/dvb-frontends/dvb-pll.c
+++ b/drivers/media/dvb-frontends/dvb-pll.c
@@ -739,7 +739,7 @@ static int dvb_pll_init(struct dvb_frontend *fe)
 	return -EINVAL;
 }
 
-static struct dvb_tuner_ops dvb_pll_tuner_ops = {
+static const struct dvb_tuner_ops dvb_pll_tuner_ops = {
 	.release = dvb_pll_release,
 	.sleep = dvb_pll_sleep,
 	.init = dvb_pll_init,
diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.c b/drivers/media/dvb-frontends/dvb_dummy_fe.c
index e5bd8c6..efc3c31 100644
--- a/drivers/media/dvb-frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb-frontends/dvb_dummy_fe.c
@@ -119,7 +119,7 @@ static void dvb_dummy_fe_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
+static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
 
 struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
 {
@@ -136,7 +136,7 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
 	return &state->frontend;
 }
 
-static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
+static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
 
 struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
 {
@@ -153,7 +153,7 @@ struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
 	return &state->frontend;
 }
 
-static struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
+static const struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
 
 struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
 {
@@ -170,7 +170,7 @@ struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
 	return &state->frontend;
 }
 
-static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
+static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "Dummy DVB-T",
@@ -201,7 +201,7 @@ static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
 	.read_ucblocks = dvb_dummy_fe_read_ucblocks,
 };
 
-static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
+static const struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
 	.delsys = { SYS_DVBC_ANNEX_A },
 	.info = {
 		.name			= "Dummy DVB-C",
@@ -230,7 +230,7 @@ static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
 	.read_ucblocks = dvb_dummy_fe_read_ucblocks,
 };
 
-static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
+static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name			= "Dummy DVB-S",
diff --git a/drivers/media/dvb-frontends/ec100.c b/drivers/media/dvb-frontends/ec100.c
index c9012e6..d97ce21 100644
--- a/drivers/media/dvb-frontends/ec100.c
+++ b/drivers/media/dvb-frontends/ec100.c
@@ -280,7 +280,7 @@ static void ec100_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops ec100_ops;
+static const struct dvb_frontend_ops ec100_ops;
 
 struct dvb_frontend *ec100_attach(const struct ec100_config *config,
 	struct i2c_adapter *i2c)
@@ -315,7 +315,7 @@ error:
 }
 EXPORT_SYMBOL(ec100_attach);
 
-static struct dvb_frontend_ops ec100_ops = {
+static const struct dvb_frontend_ops ec100_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "E3C EC100 DVB-T",
diff --git a/drivers/media/dvb-frontends/hd29l2.c b/drivers/media/dvb-frontends/hd29l2.c
index 1c7eb47..8b53633 100644
--- a/drivers/media/dvb-frontends/hd29l2.c
+++ b/drivers/media/dvb-frontends/hd29l2.c
@@ -793,7 +793,7 @@ static void hd29l2_release(struct dvb_frontend *fe)
 	kfree(priv);
 }
 
-static struct dvb_frontend_ops hd29l2_ops;
+static const struct dvb_frontend_ops hd29l2_ops;
 
 struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
 	struct i2c_adapter *i2c)
@@ -828,7 +828,7 @@ err:
 }
 EXPORT_SYMBOL(hd29l2_attach);
 
-static struct dvb_frontend_ops hd29l2_ops = {
+static const struct dvb_frontend_ops hd29l2_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "HDIC HD29L2 DMB-TH",
diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c
index 97a8982..4cb0505 100644
--- a/drivers/media/dvb-frontends/helene.c
+++ b/drivers/media/dvb-frontends/helene.c
@@ -842,7 +842,7 @@ static int helene_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static struct dvb_tuner_ops helene_tuner_ops = {
+static const struct dvb_tuner_ops helene_tuner_ops = {
 	.info = {
 		.name = "Sony HELENE Ter tuner",
 		.frequency_min = 1000000,
@@ -856,7 +856,7 @@ static struct dvb_tuner_ops helene_tuner_ops = {
 	.get_frequency = helene_get_frequency,
 };
 
-static struct dvb_tuner_ops helene_tuner_ops_s = {
+static const struct dvb_tuner_ops helene_tuner_ops_s = {
 	.info = {
 		.name = "Sony HELENE Sat tuner",
 		.frequency_min = 500000,
diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c
index a98bca5..0c089b5 100644
--- a/drivers/media/dvb-frontends/horus3a.c
+++ b/drivers/media/dvb-frontends/horus3a.c
@@ -326,7 +326,7 @@ static int horus3a_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static struct dvb_tuner_ops horus3a_tuner_ops = {
+static const struct dvb_tuner_ops horus3a_tuner_ops = {
 	.info = {
 		.name = "Sony Horus3a",
 		.frequency_min = 950000,
diff --git a/drivers/media/dvb-frontends/ix2505v.c b/drivers/media/dvb-frontends/ix2505v.c
index 0e3387e..2826bbb 100644
--- a/drivers/media/dvb-frontends/ix2505v.c
+++ b/drivers/media/dvb-frontends/ix2505v.c
@@ -258,7 +258,7 @@ static int ix2505v_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static struct dvb_tuner_ops ix2505v_tuner_ops = {
+static const struct dvb_tuner_ops ix2505v_tuner_ops = {
 	.info = {
 		.name = "Sharp IX2505V (B0017)",
 		.frequency_min = 950000,
diff --git a/drivers/media/dvb-frontends/l64781.c b/drivers/media/dvb-frontends/l64781.c
index 2f3d051..68923c8 100644
--- a/drivers/media/dvb-frontends/l64781.c
+++ b/drivers/media/dvb-frontends/l64781.c
@@ -496,7 +496,7 @@ static void l64781_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops l64781_ops;
+static const struct dvb_frontend_ops l64781_ops;
 
 struct dvb_frontend* l64781_attach(const struct l64781_config* config,
 				   struct i2c_adapter* i2c)
@@ -571,7 +571,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops l64781_ops = {
+static const struct dvb_frontend_ops l64781_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "LSI L64781 DVB-T",
diff --git a/drivers/media/dvb-frontends/lg2160.c b/drivers/media/dvb-frontends/lg2160.c
index f51a3a0..3b31e5f 100644
--- a/drivers/media/dvb-frontends/lg2160.c
+++ b/drivers/media/dvb-frontends/lg2160.c
@@ -1359,7 +1359,7 @@ static void lg216x_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops lg2160_ops = {
+static const struct dvb_frontend_ops lg2160_ops = {
 	.delsys = { SYS_ATSCMH },
 	.info = {
 		.name = "LG Electronics LG2160 ATSC/MH Frontend",
@@ -1387,7 +1387,7 @@ static struct dvb_frontend_ops lg2160_ops = {
 	.release              = lg216x_release,
 };
 
-static struct dvb_frontend_ops lg2161_ops = {
+static const struct dvb_frontend_ops lg2161_ops = {
 	.delsys = { SYS_ATSCMH },
 	.info = {
 		.name = "LG Electronics LG2161 ATSC/MH Frontend",
diff --git a/drivers/media/dvb-frontends/lgdt3305.c b/drivers/media/dvb-frontends/lgdt3305.c
index 4503e88..9f5d938 100644
--- a/drivers/media/dvb-frontends/lgdt3305.c
+++ b/drivers/media/dvb-frontends/lgdt3305.c
@@ -1103,8 +1103,8 @@ static void lgdt3305_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops lgdt3304_ops;
-static struct dvb_frontend_ops lgdt3305_ops;
+static const struct dvb_frontend_ops lgdt3304_ops;
+static const struct dvb_frontend_ops lgdt3305_ops;
 
 struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
 				     struct i2c_adapter *i2c_adap)
@@ -1164,7 +1164,7 @@ fail:
 }
 EXPORT_SYMBOL(lgdt3305_attach);
 
-static struct dvb_frontend_ops lgdt3304_ops = {
+static const struct dvb_frontend_ops lgdt3304_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name = "LG Electronics LGDT3304 VSB/QAM Frontend",
@@ -1187,7 +1187,7 @@ static struct dvb_frontend_ops lgdt3304_ops = {
 	.release              = lgdt3305_release,
 };
 
-static struct dvb_frontend_ops lgdt3305_ops = {
+static const struct dvb_frontend_ops lgdt3305_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name = "LG Electronics LGDT3305 VSB/QAM Frontend",
diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c
index 179c26e..98ce182 100644
--- a/drivers/media/dvb-frontends/lgdt3306a.c
+++ b/drivers/media/dvb-frontends/lgdt3306a.c
@@ -1775,7 +1775,7 @@ static void lgdt3306a_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops lgdt3306a_ops;
+static const struct dvb_frontend_ops lgdt3306a_ops;
 
 struct dvb_frontend *lgdt3306a_attach(const struct lgdt3306a_config *config,
 				      struct i2c_adapter *i2c_adap)
@@ -2111,7 +2111,7 @@ static void lgdt3306a_DumpRegs(struct lgdt3306a_state *state)
 
 
 
-static struct dvb_frontend_ops lgdt3306a_ops = {
+static const struct dvb_frontend_ops lgdt3306a_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name = "LG Electronics LGDT3306A VSB/QAM Frontend",
diff --git a/drivers/media/dvb-frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c
index 96bf254..35b4772 100644
--- a/drivers/media/dvb-frontends/lgdt330x.c
+++ b/drivers/media/dvb-frontends/lgdt330x.c
@@ -729,8 +729,8 @@ static void lgdt330x_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops lgdt3302_ops;
-static struct dvb_frontend_ops lgdt3303_ops;
+static const struct dvb_frontend_ops lgdt3302_ops;
+static const struct dvb_frontend_ops lgdt3303_ops;
 
 struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
 				     struct i2c_adapter* i2c)
@@ -775,7 +775,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops lgdt3302_ops = {
+static const struct dvb_frontend_ops lgdt3302_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name= "LG Electronics LGDT3302 VSB/QAM Frontend",
@@ -798,7 +798,7 @@ static struct dvb_frontend_ops lgdt3302_ops = {
 	.release              = lgdt330x_release,
 };
 
-static struct dvb_frontend_ops lgdt3303_ops = {
+static const struct dvb_frontend_ops lgdt3303_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name= "LG Electronics LGDT3303 VSB/QAM Frontend",
diff --git a/drivers/media/dvb-frontends/lgs8gl5.c b/drivers/media/dvb-frontends/lgs8gl5.c
index fbfd87b..970e42f 100644
--- a/drivers/media/dvb-frontends/lgs8gl5.c
+++ b/drivers/media/dvb-frontends/lgs8gl5.c
@@ -376,7 +376,7 @@ lgs8gl5_release(struct dvb_frontend *fe)
 }
 
 
-static struct dvb_frontend_ops lgs8gl5_ops;
+static const struct dvb_frontend_ops lgs8gl5_ops;
 
 
 struct dvb_frontend*
@@ -412,7 +412,7 @@ error:
 EXPORT_SYMBOL(lgs8gl5_attach);
 
 
-static struct dvb_frontend_ops lgs8gl5_ops = {
+static const struct dvb_frontend_ops lgs8gl5_ops = {
 	.delsys = { SYS_DTMB },
 	.info = {
 		.name			= "Legend Silicon LGS-8GL5 DMB-TH",
diff --git a/drivers/media/dvb-frontends/lgs8gxx.c b/drivers/media/dvb-frontends/lgs8gxx.c
index 919daeb..6d2e624 100644
--- a/drivers/media/dvb-frontends/lgs8gxx.c
+++ b/drivers/media/dvb-frontends/lgs8gxx.c
@@ -985,7 +985,7 @@ static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 	return lgs8gxx_write_reg(priv, 0x01, 0);
 }
 
-static struct dvb_frontend_ops lgs8gxx_ops = {
+static const struct dvb_frontend_ops lgs8gxx_ops = {
 	.delsys = { SYS_DTMB },
 	.info = {
 		.name = "Legend Silicon LGS8913/LGS8GXX DMB-TH",
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index e0fe5bc..50bce68 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -16,7 +16,7 @@
 
 #include "m88ds3103_priv.h"
 
-static struct dvb_frontend_ops m88ds3103_ops;
+static const struct dvb_frontend_ops m88ds3103_ops;
 
 /* write single register with mask */
 static int m88ds3103_update_bits(struct m88ds3103_dev *dev,
@@ -1295,7 +1295,7 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
 }
 EXPORT_SYMBOL(m88ds3103_attach);
 
-static struct dvb_frontend_ops m88ds3103_ops = {
+static const struct dvb_frontend_ops m88ds3103_ops = {
 	.delsys = {SYS_DVBS, SYS_DVBS2},
 	.info = {
 		.name = "Montage Technology M88DS3103",
diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c
index ef79a4e..5c94589 100644
--- a/drivers/media/dvb-frontends/m88rs2000.c
+++ b/drivers/media/dvb-frontends/m88rs2000.c
@@ -753,7 +753,7 @@ static void m88rs2000_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops m88rs2000_ops = {
+static const struct dvb_frontend_ops m88rs2000_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name			= "M88RS2000 DVB-S",
diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c
index 79bc671..9bb122c 100644
--- a/drivers/media/dvb-frontends/mb86a16.c
+++ b/drivers/media/dvb-frontends/mb86a16.c
@@ -1816,7 +1816,7 @@ static enum dvbfe_algo mb86a16_frontend_algo(struct dvb_frontend *fe)
 	return DVBFE_ALGO_CUSTOM;
 }
 
-static struct dvb_frontend_ops mb86a16_ops = {
+static const struct dvb_frontend_ops mb86a16_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name			= "Fujitsu MB86A16 DVB-S",
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index 4132532..caf9308 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -2058,7 +2058,7 @@ static void mb86a20s_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops mb86a20s_ops;
+static const struct dvb_frontend_ops mb86a20s_ops;
 
 struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
 				    struct i2c_adapter *i2c)
@@ -2106,7 +2106,7 @@ error:
 }
 EXPORT_SYMBOL(mb86a20s_attach);
 
-static struct dvb_frontend_ops mb86a20s_ops = {
+static const struct dvb_frontend_ops mb86a20s_ops = {
 	.delsys = { SYS_ISDBT },
 	/* Use dib8000 values per default */
 	.info = {
diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
index 18fb2df..b6f5f83 100644
--- a/drivers/media/dvb-frontends/mn88472.c
+++ b/drivers/media/dvb-frontends/mn88472.c
@@ -411,7 +411,7 @@ err:
 	return ret;
 }
 
-static struct dvb_frontend_ops mn88472_ops = {
+static const struct dvb_frontend_ops mn88472_ops = {
 	.delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
 	.info = {
 		.name = "Panasonic MN88472",
diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c
index fc08429..f53ef10 100644
--- a/drivers/media/dvb-frontends/mt312.c
+++ b/drivers/media/dvb-frontends/mt312.c
@@ -748,7 +748,7 @@ static void mt312_release(struct dvb_frontend *fe)
 }
 
 #define MT312_SYS_CLK		90000000UL	/* 90 MHz */
-static struct dvb_frontend_ops mt312_ops = {
+static const struct dvb_frontend_ops mt312_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name = "Zarlink ???? DVB-S",
diff --git a/drivers/media/dvb-frontends/mt352.c b/drivers/media/dvb-frontends/mt352.c
index c0bb632..48ea040 100644
--- a/drivers/media/dvb-frontends/mt352.c
+++ b/drivers/media/dvb-frontends/mt352.c
@@ -538,7 +538,7 @@ static void mt352_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops mt352_ops;
+static const struct dvb_frontend_ops mt352_ops;
 
 struct dvb_frontend* mt352_attach(const struct mt352_config* config,
 				  struct i2c_adapter* i2c)
@@ -566,7 +566,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops mt352_ops = {
+static const struct dvb_frontend_ops mt352_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "Zarlink MT352 DVB-T",
diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c
index 79c3040..9df76b9 100644
--- a/drivers/media/dvb-frontends/nxt200x.c
+++ b/drivers/media/dvb-frontends/nxt200x.c
@@ -1150,7 +1150,7 @@ static void nxt200x_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops nxt200x_ops;
+static const struct dvb_frontend_ops nxt200x_ops;
 
 struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
 				   struct i2c_adapter* i2c)
@@ -1213,7 +1213,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops nxt200x_ops = {
+static const struct dvb_frontend_ops nxt200x_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name = "Nextwave NXT200X VSB/QAM frontend",
diff --git a/drivers/media/dvb-frontends/nxt6000.c b/drivers/media/dvb-frontends/nxt6000.c
index 73f9505..e00c78a 100644
--- a/drivers/media/dvb-frontends/nxt6000.c
+++ b/drivers/media/dvb-frontends/nxt6000.c
@@ -548,7 +548,7 @@ static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
 	}
 }
 
-static struct dvb_frontend_ops nxt6000_ops;
+static const struct dvb_frontend_ops nxt6000_ops;
 
 struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
 				    struct i2c_adapter* i2c)
@@ -576,7 +576,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops nxt6000_ops = {
+static const struct dvb_frontend_ops nxt6000_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "NxtWave NXT6000 DVB-T",
diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c
index a165af9..b8b7b30 100644
--- a/drivers/media/dvb-frontends/or51132.c
+++ b/drivers/media/dvb-frontends/or51132.c
@@ -561,7 +561,7 @@ static void or51132_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops or51132_ops;
+static const struct dvb_frontend_ops or51132_ops;
 
 struct dvb_frontend* or51132_attach(const struct or51132_config* config,
 				    struct i2c_adapter* i2c)
@@ -585,7 +585,7 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config,
 	return &state->frontend;
 }
 
-static struct dvb_frontend_ops or51132_ops = {
+static const struct dvb_frontend_ops or51132_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name			= "Oren OR51132 VSB/QAM Frontend",
diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c
index e82413b..94d643d 100644
--- a/drivers/media/dvb-frontends/or51211.c
+++ b/drivers/media/dvb-frontends/or51211.c
@@ -508,7 +508,7 @@ static void or51211_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops or51211_ops;
+static const struct dvb_frontend_ops or51211_ops;
 
 struct dvb_frontend* or51211_attach(const struct or51211_config* config,
 				    struct i2c_adapter* i2c)
@@ -532,7 +532,7 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config,
 	return &state->frontend;
 }
 
-static struct dvb_frontend_ops or51211_ops = {
+static const struct dvb_frontend_ops or51211_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name               = "Oren OR51211 VSB Frontend",
diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c
index 8722605..7bbfe11 100644
--- a/drivers/media/dvb-frontends/rtl2830.c
+++ b/drivers/media/dvb-frontends/rtl2830.c
@@ -548,7 +548,7 @@ static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 	return 0;
 }
 
-static struct dvb_frontend_ops rtl2830_ops = {
+static const struct dvb_frontend_ops rtl2830_ops = {
 	.delsys = {SYS_DVBT},
 	.info = {
 		.name = "Realtek RTL2830 (DVB-T)",
diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
index 0ced01f..94bf5b7 100644
--- a/drivers/media/dvb-frontends/rtl2832.c
+++ b/drivers/media/dvb-frontends/rtl2832.c
@@ -837,7 +837,7 @@ static int rtl2832_deselect(struct i2c_mux_core *muxc, u32 chan_id)
 	return 0;
 }
 
-static struct dvb_frontend_ops rtl2832_ops = {
+static const struct dvb_frontend_ops rtl2832_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "Realtek RTL2832 (DVB-T)",
diff --git a/drivers/media/dvb-frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c
index c68965a..72d70b7 100644
--- a/drivers/media/dvb-frontends/s5h1409.c
+++ b/drivers/media/dvb-frontends/s5h1409.c
@@ -949,7 +949,7 @@ static void s5h1409_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops s5h1409_ops;
+static const struct dvb_frontend_ops s5h1409_ops;
 
 struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
 				    struct i2c_adapter *i2c)
@@ -995,7 +995,7 @@ error:
 }
 EXPORT_SYMBOL(s5h1409_attach);
 
-static struct dvb_frontend_ops s5h1409_ops = {
+static const struct dvb_frontend_ops s5h1409_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name			= "Samsung S5H1409 QAM/8VSB Frontend",
diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c
index 90f86e8..14bf7e6 100644
--- a/drivers/media/dvb-frontends/s5h1411.c
+++ b/drivers/media/dvb-frontends/s5h1411.c
@@ -864,7 +864,7 @@ static void s5h1411_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops s5h1411_ops;
+static const struct dvb_frontend_ops s5h1411_ops;
 
 struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
 				    struct i2c_adapter *i2c)
@@ -914,7 +914,7 @@ error:
 }
 EXPORT_SYMBOL(s5h1411_attach);
 
-static struct dvb_frontend_ops s5h1411_ops = {
+static const struct dvb_frontend_ops s5h1411_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
 		.name			= "Samsung S5H1411 QAM/8VSB Frontend",
diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c
index d7d0b7d..f9a18fe 100644
--- a/drivers/media/dvb-frontends/s5h1420.c
+++ b/drivers/media/dvb-frontends/s5h1420.c
@@ -880,7 +880,7 @@ struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe)
 }
 EXPORT_SYMBOL(s5h1420_get_tuner_i2c_adapter);
 
-static struct dvb_frontend_ops s5h1420_ops;
+static const struct dvb_frontend_ops s5h1420_ops;
 
 struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
 				    struct i2c_adapter *i2c)
@@ -934,7 +934,7 @@ error:
 }
 EXPORT_SYMBOL(s5h1420_attach);
 
-static struct dvb_frontend_ops s5h1420_ops = {
+static const struct dvb_frontend_ops s5h1420_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name     = "Samsung S5H1420/PnpNetwork PN1010 DVB-S",
diff --git a/drivers/media/dvb-frontends/s5h1432.c b/drivers/media/dvb-frontends/s5h1432.c
index 4215652..97b9954 100644
--- a/drivers/media/dvb-frontends/s5h1432.c
+++ b/drivers/media/dvb-frontends/s5h1432.c
@@ -341,7 +341,7 @@ static void s5h1432_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops s5h1432_ops;
+static const struct dvb_frontend_ops s5h1432_ops;
 
 struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
 				    struct i2c_adapter *i2c)
@@ -370,7 +370,7 @@ struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
 }
 EXPORT_SYMBOL(s5h1432_attach);
 
-static struct dvb_frontend_ops s5h1432_ops = {
+static const struct dvb_frontend_ops s5h1432_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		 .name = "Samsung s5h1432 DVB-T Frontend",
diff --git a/drivers/media/dvb-frontends/s921.c b/drivers/media/dvb-frontends/s921.c
index b5e3d90..d843455 100644
--- a/drivers/media/dvb-frontends/s921.c
+++ b/drivers/media/dvb-frontends/s921.c
@@ -477,7 +477,7 @@ static void s921_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops s921_ops;
+static const struct dvb_frontend_ops s921_ops;
 
 struct dvb_frontend *s921_attach(const struct s921_config *config,
 				    struct i2c_adapter *i2c)
@@ -505,7 +505,7 @@ struct dvb_frontend *s921_attach(const struct s921_config *config,
 }
 EXPORT_SYMBOL(s921_attach);
 
-static struct dvb_frontend_ops s921_ops = {
+static const struct dvb_frontend_ops s921_ops = {
 	.delsys = { SYS_ISDBT },
 	/* Use dib8000 values per default */
 	.info = {
diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c
index 8bf716a..b005cf9 100644
--- a/drivers/media/dvb-frontends/si2165.c
+++ b/drivers/media/dvb-frontends/si2165.c
@@ -1011,7 +1011,7 @@ static void si2165_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops si2165_ops = {
+static const struct dvb_frontend_ops si2165_ops = {
 	.info = {
 		.name = "Silicon Labs ",
 		 /* For DVB-C */
diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c
index 62ad7a7..6c11f10 100644
--- a/drivers/media/dvb-frontends/si21xx.c
+++ b/drivers/media/dvb-frontends/si21xx.c
@@ -866,7 +866,7 @@ static void si21xx_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops si21xx_ops = {
+static const struct dvb_frontend_ops si21xx_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name			= "SL SI21XX DVB-S",
diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c
index e87ac30..04454cb78 100644
--- a/drivers/media/dvb-frontends/sp8870.c
+++ b/drivers/media/dvb-frontends/sp8870.c
@@ -551,7 +551,7 @@ static void sp8870_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops sp8870_ops;
+static const struct dvb_frontend_ops sp8870_ops;
 
 struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
 				   struct i2c_adapter* i2c)
@@ -580,7 +580,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops sp8870_ops = {
+static const struct dvb_frontend_ops sp8870_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "Spase SP8870 DVB-T",
diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c
index 4378fe1..fff1ca4 100644
--- a/drivers/media/dvb-frontends/sp887x.c
+++ b/drivers/media/dvb-frontends/sp887x.c
@@ -562,7 +562,7 @@ static void sp887x_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops sp887x_ops;
+static const struct dvb_frontend_ops sp887x_ops;
 
 struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
 				   struct i2c_adapter* i2c)
@@ -591,7 +591,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops sp887x_ops = {
+static const struct dvb_frontend_ops sp887x_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "Spase SP887x DVB-T",
diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
index 3d171b0..1d34e95 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.c
+++ b/drivers/media/dvb-frontends/stb0899_drv.c
@@ -1586,7 +1586,7 @@ static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe)
 	return DVBFE_ALGO_CUSTOM;
 }
 
-static struct dvb_frontend_ops stb0899_ops = {
+static const struct dvb_frontend_ops stb0899_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
 	.info = {
 		.name 			= "STB0899 Multistandard",
diff --git a/drivers/media/dvb-frontends/stb6000.c b/drivers/media/dvb-frontends/stb6000.c
index a0c3c52..73347d5 100644
--- a/drivers/media/dvb-frontends/stb6000.c
+++ b/drivers/media/dvb-frontends/stb6000.c
@@ -186,7 +186,7 @@ static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static struct dvb_tuner_ops stb6000_tuner_ops = {
+static const struct dvb_tuner_ops stb6000_tuner_ops = {
 	.info = {
 		.name = "ST STB6000",
 		.frequency_min = 950000,
diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c
index b9c2511..5add118 100644
--- a/drivers/media/dvb-frontends/stb6100.c
+++ b/drivers/media/dvb-frontends/stb6100.c
@@ -522,7 +522,7 @@ static int stb6100_set_params(struct dvb_frontend *fe)
 	return 0;
 }
 
-static struct dvb_tuner_ops stb6100_ops = {
+static const struct dvb_tuner_ops stb6100_ops = {
 	.info = {
 		.name			= "STB6100 Silicon Tuner",
 		.frequency_min		= 950000,
diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c
index c93d9a4..2fed47b 100644
--- a/drivers/media/dvb-frontends/stv0288.c
+++ b/drivers/media/dvb-frontends/stv0288.c
@@ -536,7 +536,7 @@ static void stv0288_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops stv0288_ops = {
+static const struct dvb_frontend_ops stv0288_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name			= "ST STV0288 DVB-S",
diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c
index 81b27b7..0529b1e 100644
--- a/drivers/media/dvb-frontends/stv0297.c
+++ b/drivers/media/dvb-frontends/stv0297.c
@@ -658,7 +658,7 @@ static void stv0297_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops stv0297_ops;
+static const struct dvb_frontend_ops stv0297_ops;
 
 struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
 				    struct i2c_adapter *i2c)
@@ -690,7 +690,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops stv0297_ops = {
+static const struct dvb_frontend_ops stv0297_ops = {
 	.delsys = { SYS_DVBC_ANNEX_A },
 	.info = {
 		 .name = "ST STV0297 DVB-C",
diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c
index 7927fa9..e1dc5c5 100644
--- a/drivers/media/dvb-frontends/stv0299.c
+++ b/drivers/media/dvb-frontends/stv0299.c
@@ -673,7 +673,7 @@ static void stv0299_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops stv0299_ops;
+static const struct dvb_frontend_ops stv0299_ops;
 
 struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
 				    struct i2c_adapter* i2c)
@@ -713,7 +713,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops stv0299_ops = {
+static const struct dvb_frontend_ops stv0299_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name			= "ST STV0299 DVB-S",
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index abc379a..4ac1ce2 100644
--- a/drivers/media/dvb-frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
@@ -2272,7 +2272,7 @@ static void stv0367_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops stv0367ter_ops = {
+static const struct dvb_frontend_ops stv0367ter_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "ST STV0367 DVB-T",
@@ -3390,7 +3390,7 @@ static int stv0367cab_read_ucblcks(struct dvb_frontend *fe, u32 *ucblocks)
 	return 0;
 };
 
-static struct dvb_frontend_ops stv0367cab_ops = {
+static const struct dvb_frontend_ops stv0367cab_ops = {
 	.delsys = { SYS_DVBC_ANNEX_A },
 	.info = {
 		.name = "ST STV0367 DVB-C",
diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c
index f667005..43a0f69 100644
--- a/drivers/media/dvb-frontends/stv0900_core.c
+++ b/drivers/media/dvb-frontends/stv0900_core.c
@@ -1875,7 +1875,7 @@ static int stv0900_get_frontend(struct dvb_frontend *fe,
 	return 0;
 }
 
-static struct dvb_frontend_ops stv0900_ops = {
+static const struct dvb_frontend_ops stv0900_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
 	.info = {
 		.name			= "STV0900 frontend",
diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
index 25bdf6e..0e834aa 100644
--- a/drivers/media/dvb-frontends/stv090x.c
+++ b/drivers/media/dvb-frontends/stv090x.c
@@ -4886,7 +4886,7 @@ static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir,
 	return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
 }
 
-static struct dvb_frontend_ops stv090x_ops = {
+static const struct dvb_frontend_ops stv090x_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
 	.info = {
 		.name			= "STV090x Multistandard",
diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c
index 91c6dcf..66a5a7f 100644
--- a/drivers/media/dvb-frontends/stv6110.c
+++ b/drivers/media/dvb-frontends/stv6110.c
@@ -382,7 +382,7 @@ static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
 	return 0;
 }
 
-static struct dvb_tuner_ops stv6110_tuner_ops = {
+static const struct dvb_tuner_ops stv6110_tuner_ops = {
 	.info = {
 		.name = "ST STV6110",
 		.frequency_min = 950000,
diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c
index a62c01e..c611ad2 100644
--- a/drivers/media/dvb-frontends/stv6110x.c
+++ b/drivers/media/dvb-frontends/stv6110x.c
@@ -345,7 +345,7 @@ static int stv6110x_release(struct dvb_frontend *fe)
 	return 0;
 }
 
-static struct dvb_tuner_ops stv6110x_ops = {
+static const struct dvb_tuner_ops stv6110x_ops = {
 	.info = {
 		.name		= "STV6110(A) Silicon Tuner",
 		.frequency_min	=  950000,
diff --git a/drivers/media/dvb-frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c
index 806c566..3556933 100644
--- a/drivers/media/dvb-frontends/tda10021.c
+++ b/drivers/media/dvb-frontends/tda10021.c
@@ -444,7 +444,7 @@ static void tda10021_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops tda10021_ops;
+static const struct dvb_frontend_ops tda10021_ops;
 
 struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
 				     struct i2c_adapter* i2c,
@@ -484,7 +484,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops tda10021_ops = {
+static const struct dvb_frontend_ops tda10021_ops = {
 	.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C },
 	.info = {
 		.name = "Philips TDA10021 DVB-C",
diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c
index 3b8c7e4..2874581 100644
--- a/drivers/media/dvb-frontends/tda10023.c
+++ b/drivers/media/dvb-frontends/tda10023.c
@@ -516,7 +516,7 @@ static void tda10023_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops tda10023_ops;
+static const struct dvb_frontend_ops tda10023_ops;
 
 struct dvb_frontend *tda10023_attach(const struct tda10023_config *config,
 				     struct i2c_adapter *i2c,
@@ -573,7 +573,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops tda10023_ops = {
+static const struct dvb_frontend_ops tda10023_ops = {
 	.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C },
 	.info = {
 		.name = "Philips TDA10023 DVB-C",
diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c
index c2bf89d..285c39c 100644
--- a/drivers/media/dvb-frontends/tda10048.c
+++ b/drivers/media/dvb-frontends/tda10048.c
@@ -1094,7 +1094,7 @@ static void tda10048_establish_defaults(struct dvb_frontend *fe)
 	}
 }
 
-static struct dvb_frontend_ops tda10048_ops;
+static const struct dvb_frontend_ops tda10048_ops;
 
 struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
 	struct i2c_adapter *i2c)
@@ -1156,7 +1156,7 @@ error:
 }
 EXPORT_SYMBOL(tda10048_attach);
 
-static struct dvb_frontend_ops tda10048_ops = {
+static const struct dvb_frontend_ops tda10048_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "NXP TDA10048HN DVB-T",
diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c
index b898483..e674508 100644
--- a/drivers/media/dvb-frontends/tda1004x.c
+++ b/drivers/media/dvb-frontends/tda1004x.c
@@ -1245,7 +1245,7 @@ static void tda1004x_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops tda10045_ops = {
+static const struct dvb_frontend_ops tda10045_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "Philips TDA10045H DVB-T",
@@ -1315,7 +1315,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
 	return &state->frontend;
 }
 
-static struct dvb_frontend_ops tda10046_ops = {
+static const struct dvb_frontend_ops tda10046_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "Philips TDA10046H DVB-T",
diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c
index 37ebeef2..a59f4fd 100644
--- a/drivers/media/dvb-frontends/tda10071.c
+++ b/drivers/media/dvb-frontends/tda10071.c
@@ -20,7 +20,7 @@
 
 #include "tda10071_priv.h"
 
-static struct dvb_frontend_ops tda10071_ops;
+static const struct dvb_frontend_ops tda10071_ops;
 
 /*
  * XXX: regmap_update_bits() does not fit our needs as it does not support
@@ -1102,7 +1102,7 @@ static int tda10071_get_tune_settings(struct dvb_frontend *fe,
 	return 0;
 }
 
-static struct dvb_frontend_ops tda10071_ops = {
+static const struct dvb_frontend_ops tda10071_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2 },
 	.info = {
 		.name = "NXP TDA10071",
diff --git a/drivers/media/dvb-frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c
index 31d0acb..b6d16c0 100644
--- a/drivers/media/dvb-frontends/tda10086.c
+++ b/drivers/media/dvb-frontends/tda10086.c
@@ -706,7 +706,7 @@ static void tda10086_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops tda10086_ops = {
+static const struct dvb_frontend_ops tda10086_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name     = "Philips TDA10086 DVB-S",
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c
index de0a1c1..bc247f9 100644
--- a/drivers/media/dvb-frontends/tda18271c2dd.c
+++ b/drivers/media/dvb-frontends/tda18271c2dd.c
@@ -1217,7 +1217,7 @@ static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
 }
 
 
-static struct dvb_tuner_ops tuner_ops = {
+static const struct dvb_tuner_ops tuner_ops = {
 	.info = {
 		.name = "NXP TDA18271C2D",
 		.frequency_min  =  47125000,
diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c
index 82f8cc5..7ca9659 100644
--- a/drivers/media/dvb-frontends/tda665x.c
+++ b/drivers/media/dvb-frontends/tda665x.c
@@ -206,7 +206,7 @@ static int tda665x_release(struct dvb_frontend *fe)
 	return 0;
 }
 
-static struct dvb_tuner_ops tda665x_ops = {
+static const struct dvb_tuner_ops tda665x_ops = {
 	.get_status	= tda665x_get_status,
 	.set_params	= tda665x_set_params,
 	.get_frequency	= tda665x_get_frequency,
diff --git a/drivers/media/dvb-frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c
index 9072d64..aa3200d 100644
--- a/drivers/media/dvb-frontends/tda8083.c
+++ b/drivers/media/dvb-frontends/tda8083.c
@@ -421,7 +421,7 @@ static void tda8083_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops tda8083_ops;
+static const struct dvb_frontend_ops tda8083_ops;
 
 struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
 				    struct i2c_adapter* i2c)
@@ -449,7 +449,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops tda8083_ops = {
+static const struct dvb_frontend_ops tda8083_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name			= "Philips TDA8083 DVB-S",
diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c
index 3285b1b..e0df931 100644
--- a/drivers/media/dvb-frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -161,7 +161,7 @@ static int tda8261_release(struct dvb_frontend *fe)
 	return 0;
 }
 
-static struct dvb_tuner_ops tda8261_ops = {
+static const struct dvb_tuner_ops tda8261_ops = {
 
 	.info = {
 		.name		= "TDA8261",
diff --git a/drivers/media/dvb-frontends/tda826x.c b/drivers/media/dvb-frontends/tda826x.c
index 04bbcc2..2ec671d 100644
--- a/drivers/media/dvb-frontends/tda826x.c
+++ b/drivers/media/dvb-frontends/tda826x.c
@@ -129,7 +129,7 @@ static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static struct dvb_tuner_ops tda826x_tuner_ops = {
+static const struct dvb_tuner_ops tda826x_tuner_ops = {
 	.info = {
 		.name = "Philips TDA826X",
 		.frequency_min = 950000,
diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c
index 14b410f..a9f6bbe 100644
--- a/drivers/media/dvb-frontends/ts2020.c
+++ b/drivers/media/dvb-frontends/ts2020.c
@@ -496,7 +496,7 @@ static int ts2020_read_signal_strength(struct dvb_frontend *fe,
 	return 0;
 }
 
-static struct dvb_tuner_ops ts2020_tuner_ops = {
+static const struct dvb_tuner_ops ts2020_tuner_ops = {
 	.info = {
 		.name = "TS2020",
 		.frequency_min = 950000,
diff --git a/drivers/media/dvb-frontends/tua6100.c b/drivers/media/dvb-frontends/tua6100.c
index 029384d..6da12b9 100644
--- a/drivers/media/dvb-frontends/tua6100.c
+++ b/drivers/media/dvb-frontends/tua6100.c
@@ -157,7 +157,7 @@ static int tua6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static struct dvb_tuner_ops tua6100_tuner_ops = {
+static const struct dvb_tuner_ops tua6100_tuner_ops = {
 	.info = {
 		.name = "Infineon TUA6100",
 		.frequency_min = 950000,
diff --git a/drivers/media/dvb-frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c
index b09fe88..23787a9 100644
--- a/drivers/media/dvb-frontends/ves1820.c
+++ b/drivers/media/dvb-frontends/ves1820.c
@@ -369,7 +369,7 @@ static void ves1820_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops ves1820_ops;
+static const struct dvb_frontend_ops ves1820_ops;
 
 struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
 				    struct i2c_adapter* i2c,
@@ -408,7 +408,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops ves1820_ops = {
+static const struct dvb_frontend_ops ves1820_ops = {
 	.delsys = { SYS_DVBC_ANNEX_A },
 	.info = {
 		.name = "VLSI VES1820 DVB-C",
diff --git a/drivers/media/dvb-frontends/ves1x93.c b/drivers/media/dvb-frontends/ves1x93.c
index ed113e2..d0ee52f 100644
--- a/drivers/media/dvb-frontends/ves1x93.c
+++ b/drivers/media/dvb-frontends/ves1x93.c
@@ -454,7 +454,7 @@ static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
 	}
 }
 
-static struct dvb_frontend_ops ves1x93_ops;
+static const struct dvb_frontend_ops ves1x93_ops;
 
 struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
 				    struct i2c_adapter* i2c)
@@ -512,7 +512,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops ves1x93_ops = {
+static const struct dvb_frontend_ops ves1x93_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name			= "VLSI VES1x93 DVB-S",
diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c
index 0903d46..7ed8131 100644
--- a/drivers/media/dvb-frontends/zl10036.c
+++ b/drivers/media/dvb-frontends/zl10036.c
@@ -446,7 +446,7 @@ static int zl10036_init(struct dvb_frontend *fe)
 	return ret;
 }
 
-static struct dvb_tuner_ops zl10036_tuner_ops = {
+static const struct dvb_tuner_ops zl10036_tuner_ops = {
 	.info = {
 		.name = "Zarlink ZL10036",
 		.frequency_min = 950000,
diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c
index ee09ec2..f8c271b 100644
--- a/drivers/media/dvb-frontends/zl10039.c
+++ b/drivers/media/dvb-frontends/zl10039.c
@@ -255,7 +255,7 @@ static int zl10039_release(struct dvb_frontend *fe)
 	return 0;
 }
 
-static struct dvb_tuner_ops zl10039_ops = {
+static const struct dvb_tuner_ops zl10039_ops = {
 	.release = zl10039_release,
 	.init = zl10039_init,
 	.sleep = zl10039_sleep,
diff --git a/drivers/media/dvb-frontends/zl10353.c b/drivers/media/dvb-frontends/zl10353.c
index 3b08176..4f3ff3e 100644
--- a/drivers/media/dvb-frontends/zl10353.c
+++ b/drivers/media/dvb-frontends/zl10353.c
@@ -602,7 +602,7 @@ static void zl10353_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops zl10353_ops;
+static const struct dvb_frontend_ops zl10353_ops;
 
 struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
 				    struct i2c_adapter *i2c)
@@ -634,7 +634,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops zl10353_ops = {
+static const struct dvb_frontend_ops zl10353_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "Zarlink ZL10353 DVB-T",
diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c
index 35bc9b2..b3a973f 100644
--- a/drivers/media/pci/bt8xx/dst.c
+++ b/drivers/media/pci/bt8xx/dst.c
@@ -1722,10 +1722,10 @@ static void bt8xx_dst_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops dst_dvbt_ops;
-static struct dvb_frontend_ops dst_dvbs_ops;
-static struct dvb_frontend_ops dst_dvbc_ops;
-static struct dvb_frontend_ops dst_atsc_ops;
+static const struct dvb_frontend_ops dst_dvbt_ops;
+static const struct dvb_frontend_ops dst_dvbs_ops;
+static const struct dvb_frontend_ops dst_dvbc_ops;
+static const struct dvb_frontend_ops dst_atsc_ops;
 
 struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
 {
@@ -1761,7 +1761,7 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
 
 EXPORT_SYMBOL(dst_attach);
 
-static struct dvb_frontend_ops dst_dvbt_ops = {
+static const struct dvb_frontend_ops dst_dvbt_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name = "DST DVB-T",
@@ -1790,7 +1790,7 @@ static struct dvb_frontend_ops dst_dvbt_ops = {
 	.read_snr = dst_read_snr,
 };
 
-static struct dvb_frontend_ops dst_dvbs_ops = {
+static const struct dvb_frontend_ops dst_dvbs_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name = "DST DVB-S",
@@ -1819,7 +1819,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
 	.set_tone = dst_set_tone,
 };
 
-static struct dvb_frontend_ops dst_dvbc_ops = {
+static const struct dvb_frontend_ops dst_dvbc_ops = {
 	.delsys = { SYS_DVBC_ANNEX_A },
 	.info = {
 		.name = "DST DVB-C",
@@ -1848,7 +1848,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
 	.read_snr = dst_read_snr,
 };
 
-static struct dvb_frontend_ops dst_atsc_ops = {
+static const struct dvb_frontend_ops dst_atsc_ops = {
 	.delsys = { SYS_ATSC },
 	.info = {
 		.name = "DST ATSC",
diff --git a/drivers/media/pci/pt1/va1j5jf8007s.c b/drivers/media/pci/pt1/va1j5jf8007s.c
index d0e70dc0..249273b 100644
--- a/drivers/media/pci/pt1/va1j5jf8007s.c
+++ b/drivers/media/pci/pt1/va1j5jf8007s.c
@@ -578,7 +578,7 @@ static void va1j5jf8007s_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops va1j5jf8007s_ops = {
+static const struct dvb_frontend_ops va1j5jf8007s_ops = {
 	.delsys = { SYS_ISDBS },
 	.info = {
 		.name = "VA1J5JF8007/VA1J5JF8011 ISDB-S",
diff --git a/drivers/media/pci/pt1/va1j5jf8007t.c b/drivers/media/pci/pt1/va1j5jf8007t.c
index 0268f20..e0766e6 100644
--- a/drivers/media/pci/pt1/va1j5jf8007t.c
+++ b/drivers/media/pci/pt1/va1j5jf8007t.c
@@ -427,7 +427,7 @@ static void va1j5jf8007t_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops va1j5jf8007t_ops = {
+static const struct dvb_frontend_ops va1j5jf8007t_ops = {
 	.delsys = { SYS_ISDBT },
 	.info = {
 		.name = "VA1J5JF8007/VA1J5JF8011 ISDB-T",
diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c
index 7f0b9d5..dfec237 100644
--- a/drivers/media/tuners/mt2063.c
+++ b/drivers/media/tuners/mt2063.c
@@ -2201,7 +2201,7 @@ static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
 	return 0;
 }
 
-static struct dvb_tuner_ops mt2063_ops = {
+static const struct dvb_tuner_ops mt2063_ops = {
 	.info = {
 		 .name = "MT2063 Silicon Tuner",
 		 .frequency_min = 45000000,
diff --git a/drivers/media/tuners/mt20xx.c b/drivers/media/tuners/mt20xx.c
index 9e03104..52da467 100644
--- a/drivers/media/tuners/mt20xx.c
+++ b/drivers/media/tuners/mt20xx.c
@@ -363,7 +363,7 @@ static int mt2032_set_params(struct dvb_frontend *fe,
 	return ret;
 }
 
-static struct dvb_tuner_ops mt2032_tuner_ops = {
+static const struct dvb_tuner_ops mt2032_tuner_ops = {
 	.set_analog_params = mt2032_set_params,
 	.release           = microtune_release,
 	.get_frequency     = microtune_get_frequency,
@@ -563,7 +563,7 @@ static int mt2050_set_params(struct dvb_frontend *fe,
 	return ret;
 }
 
-static struct dvb_tuner_ops mt2050_tuner_ops = {
+static const struct dvb_tuner_ops mt2050_tuner_ops = {
 	.set_analog_params = mt2050_set_params,
 	.release           = microtune_release,
 	.get_frequency     = microtune_get_frequency,
diff --git a/drivers/media/tuners/mxl5007t.c b/drivers/media/tuners/mxl5007t.c
index f4ae04c..42569c6 100644
--- a/drivers/media/tuners/mxl5007t.c
+++ b/drivers/media/tuners/mxl5007t.c
@@ -794,7 +794,7 @@ static int mxl5007t_release(struct dvb_frontend *fe)
 
 /* ------------------------------------------------------------------------- */
 
-static struct dvb_tuner_ops mxl5007t_tuner_ops = {
+static const struct dvb_tuner_ops mxl5007t_tuner_ops = {
 	.info = {
 		.name = "MaxLinear MxL5007T",
 	},
diff --git a/drivers/media/tuners/tda827x.c b/drivers/media/tuners/tda827x.c
index edcb4a7..5050ce9 100644
--- a/drivers/media/tuners/tda827x.c
+++ b/drivers/media/tuners/tda827x.c
@@ -818,7 +818,7 @@ static int tda827x_initial_sleep(struct dvb_frontend *fe)
 	return fe->ops.tuner_ops.sleep(fe);
 }
 
-static struct dvb_tuner_ops tda827xo_tuner_ops = {
+static const struct dvb_tuner_ops tda827xo_tuner_ops = {
 	.info = {
 		.name = "Philips TDA827X",
 		.frequency_min  =  55000000,
@@ -834,7 +834,7 @@ static struct dvb_tuner_ops tda827xo_tuner_ops = {
 	.get_bandwidth = tda827x_get_bandwidth,
 };
 
-static struct dvb_tuner_ops tda827xa_tuner_ops = {
+static const struct dvb_tuner_ops tda827xa_tuner_ops = {
 	.info = {
 		.name = "Philips TDA827XA",
 		.frequency_min  =  44000000,
diff --git a/drivers/media/tuners/tda8290.c b/drivers/media/tuners/tda8290.c
index 998e82b..273556d 100644
--- a/drivers/media/tuners/tda8290.c
+++ b/drivers/media/tuners/tda8290.c
@@ -721,7 +721,7 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props)
 	return -ENODEV;
 }
 
-static struct analog_demod_ops tda8290_ops = {
+static const struct analog_demod_ops tda8290_ops = {
 	.set_params     = tda8290_set_params,
 	.has_signal     = tda8290_has_signal,
 	.standby        = tda8290_standby,
@@ -729,7 +729,7 @@ static struct analog_demod_ops tda8290_ops = {
 	.i2c_gate_ctrl  = tda8290_i2c_bridge,
 };
 
-static struct analog_demod_ops tda8295_ops = {
+static const struct analog_demod_ops tda8295_ops = {
 	.set_params     = tda8295_set_params,
 	.has_signal     = tda8295_has_signal,
 	.standby        = tda8295_standby,
diff --git a/drivers/media/tuners/tda9887.c b/drivers/media/tuners/tda9887.c
index 56be6c2..c0e815f 100644
--- a/drivers/media/tuners/tda9887.c
+++ b/drivers/media/tuners/tda9887.c
@@ -659,7 +659,7 @@ static void tda9887_release(struct dvb_frontend *fe)
 	fe->analog_demod_priv = NULL;
 }
 
-static struct analog_demod_ops tda9887_ops = {
+static const struct analog_demod_ops tda9887_ops = {
 	.info		= {
 		.name	= "tda9887",
 	},
diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c
index bf78cb9..36b0b1e 100644
--- a/drivers/media/tuners/tea5761.c
+++ b/drivers/media/tuners/tea5761.c
@@ -301,7 +301,7 @@ static int tea5761_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static struct dvb_tuner_ops tea5761_tuner_ops = {
+static const struct dvb_tuner_ops tea5761_tuner_ops = {
 	.info = {
 		.name           = "tea5761", // Philips TEA5761HN FM Radio
 	},
diff --git a/drivers/media/tuners/tea5767.c b/drivers/media/tuners/tea5767.c
index 36e85d8..6d86aa6 100644
--- a/drivers/media/tuners/tea5767.c
+++ b/drivers/media/tuners/tea5767.c
@@ -423,7 +423,7 @@ static int tea5767_set_config (struct dvb_frontend *fe, void *priv_cfg)
 	return 0;
 }
 
-static struct dvb_tuner_ops tea5767_tuner_ops = {
+static const struct dvb_tuner_ops tea5767_tuner_ops = {
 	.info = {
 		.name           = "tea5767", // Philips TEA5767HN FM Radio
 	},
diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c
index 8e9ce14..9ba9582 100644
--- a/drivers/media/tuners/tuner-simple.c
+++ b/drivers/media/tuners/tuner-simple.c
@@ -1035,7 +1035,7 @@ static int simple_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
 	return 0;
 }
 
-static struct dvb_tuner_ops simple_tuner_ops = {
+static const struct dvb_tuner_ops simple_tuner_ops = {
 	.init              = simple_init,
 	.sleep             = simple_sleep,
 	.set_analog_params = simple_set_params,
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
index 047a32f..639e156 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
@@ -549,7 +549,7 @@ static void mxl111sf_demod_release(struct dvb_frontend *fe)
 	fe->demodulator_priv = NULL;
 }
 
-static struct dvb_frontend_ops mxl111sf_demod_ops = {
+static const struct dvb_frontend_ops mxl111sf_demod_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name               = "MaxLinear MxL111SF DVB-T demodulator",
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
index 7d16252..f141dcc 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
@@ -466,7 +466,7 @@ static int mxl111sf_tuner_release(struct dvb_frontend *fe)
 
 /* ------------------------------------------------------------------------- */
 
-static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = {
+static const struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = {
 	.info = {
 		.name = "MaxLinear MxL111SF",
 #if 0
diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c
index 09db3d0..9862d3e 100644
--- a/drivers/media/usb/dvb-usb/af9005-fe.c
+++ b/drivers/media/usb/dvb-usb/af9005-fe.c
@@ -1430,7 +1430,7 @@ static void af9005_fe_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops af9005_fe_ops;
+static const struct dvb_frontend_ops af9005_fe_ops;
 
 struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d)
 {
@@ -1455,7 +1455,7 @@ struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d)
 	return NULL;
 }
 
-static struct dvb_frontend_ops af9005_fe_ops = {
+static const struct dvb_frontend_ops af9005_fe_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		 .name = "AF9005 USB DVB-T",
diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
index b3ec743..7d90dab 100644
--- a/drivers/media/usb/dvb-usb/cinergyT2-fe.c
+++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
@@ -303,7 +303,7 @@ static void cinergyt2_fe_release(struct dvb_frontend *fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops cinergyt2_fe_ops;
+static const struct dvb_frontend_ops cinergyt2_fe_ops;
 
 struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
 {
@@ -319,7 +319,7 @@ struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
 }
 
 
-static struct dvb_frontend_ops cinergyt2_fe_ops = {
+static const struct dvb_frontend_ops cinergyt2_fe_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= DRIVER_NAME,
diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c
index c09332b..db03851 100644
--- a/drivers/media/usb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c
@@ -155,7 +155,7 @@ static void dtt200u_fe_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops dtt200u_fe_ops;
+static const struct dvb_frontend_ops dtt200u_fe_ops;
 
 struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
 {
@@ -178,7 +178,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops dtt200u_fe_ops = {
+static const struct dvb_frontend_ops dtt200u_fe_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "WideView USB DVB-T",
diff --git a/drivers/media/usb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c
index 979f05b..0251a4e 100644
--- a/drivers/media/usb/dvb-usb/friio-fe.c
+++ b/drivers/media/usb/dvb-usb/friio-fe.c
@@ -401,7 +401,7 @@ static void jdvbt90502_release(struct dvb_frontend *fe)
 }
 
 
-static struct dvb_frontend_ops jdvbt90502_ops;
+static const struct dvb_frontend_ops jdvbt90502_ops;
 
 struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d)
 {
@@ -432,7 +432,7 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops jdvbt90502_ops = {
+static const struct dvb_frontend_ops jdvbt90502_ops = {
 	.delsys = { SYS_ISDBT },
 	.info = {
 		.name			= "Comtech JDVBT90502 ISDB-T",
diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/usb/dvb-usb/gp8psk-fe.c
index db6eb79..59da367 100644
--- a/drivers/media/usb/dvb-usb/gp8psk-fe.c
+++ b/drivers/media/usb/dvb-usb/gp8psk-fe.c
@@ -308,7 +308,7 @@ static void gp8psk_fe_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops gp8psk_fe_ops;
+static const struct dvb_frontend_ops gp8psk_fe_ops;
 
 struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
 {
@@ -328,7 +328,7 @@ success:
 }
 
 
-static struct dvb_frontend_ops gp8psk_fe_ops = {
+static const struct dvb_frontend_ops gp8psk_fe_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name			= "Genpix DVB-S",
diff --git a/drivers/media/usb/dvb-usb/vp702x-fe.c b/drivers/media/usb/dvb-usb/vp702x-fe.c
index 27398c0..7ff31ba 100644
--- a/drivers/media/usb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/usb/dvb-usb/vp702x-fe.c
@@ -323,7 +323,7 @@ static void vp702x_fe_release(struct dvb_frontend* fe)
 	kfree(st);
 }
 
-static struct dvb_frontend_ops vp702x_fe_ops;
+static const struct dvb_frontend_ops vp702x_fe_ops;
 
 struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
 {
@@ -345,7 +345,7 @@ error:
 }
 
 
-static struct dvb_frontend_ops vp702x_fe_ops = {
+static const struct dvb_frontend_ops vp702x_fe_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name           = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S",
diff --git a/drivers/media/usb/dvb-usb/vp7045-fe.c b/drivers/media/usb/dvb-usb/vp7045-fe.c
index 7765602..4520ad9 100644
--- a/drivers/media/usb/dvb-usb/vp7045-fe.c
+++ b/drivers/media/usb/dvb-usb/vp7045-fe.c
@@ -140,7 +140,7 @@ static void vp7045_fe_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops vp7045_fe_ops;
+static const struct dvb_frontend_ops vp7045_fe_ops;
 
 struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
 {
@@ -158,7 +158,7 @@ error:
 }
 
 
-static struct dvb_frontend_ops vp7045_fe_ops = {
+static const struct dvb_frontend_ops vp7045_fe_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "Twinhan VP7045/46 USB DVB-T",
diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.c b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
index 8781335..2d94449 100644
--- a/drivers/media/usb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
@@ -205,7 +205,7 @@ static void ttusbdecfe_release(struct dvb_frontend* fe)
 	kfree(state);
 }
 
-static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
+static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
 
 struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
 {
@@ -225,7 +225,7 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf
 	return &state->frontend;
 }
 
-static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
+static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
 
 struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
 {
@@ -247,7 +247,7 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf
 	return &state->frontend;
 }
 
-static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
+static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
 	.delsys = { SYS_DVBT },
 	.info = {
 		.name			= "TechnoTrend/Hauppauge DEC2000-t Frontend",
@@ -270,7 +270,7 @@ static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
 	.read_status = ttusbdecfe_dvbt_read_status,
 };
 
-static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
+static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
 	.delsys = { SYS_DVBS },
 	.info = {
 		.name			= "TechnoTrend/Hauppauge DEC3000-s Frontend",

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 05/12] [media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
                   ` (2 preceding siblings ...)
  2016-08-09 21:32 ` [PATCH 04/12] [media] dvb: make DVB frontend *_ops instances "const" Max Kellermann
@ 2016-08-09 21:32 ` Max Kellermann
  2016-08-09 23:01   ` kbuild test robot
  2016-08-09 23:19   ` kbuild test robot
  2016-08-09 21:32 ` [PATCH 06/12] [media] dvb_frontend: tuner_ops.release returns void Max Kellermann
                   ` (7 subsequent siblings)
  11 siblings, 2 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

Most release callback functions are identical: free the "tuner_priv"
and clear it.  Let's eliminate some bloat by providing this simple
implementation in the dvb_frontend library.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/dvb-core/dvb_frontend.c      |    9 +++++++++
 drivers/media/dvb-core/dvb_frontend.h      |    7 +++++++
 drivers/media/dvb-frontends/dib0070.c      |    9 +--------
 drivers/media/dvb-frontends/dib0090.c      |   11 ++---------
 drivers/media/dvb-frontends/dvb-pll.c      |    9 +--------
 drivers/media/dvb-frontends/itd1000.c      |    9 +--------
 drivers/media/dvb-frontends/ix2505v.c      |   12 +-----------
 drivers/media/dvb-frontends/stb6000.c      |    9 +--------
 drivers/media/dvb-frontends/stb6100.c      |   14 +-------------
 drivers/media/dvb-frontends/stv6110.c      |    9 +--------
 drivers/media/dvb-frontends/stv6110x.c     |   12 +-----------
 drivers/media/dvb-frontends/tda18271c2dd.c |   10 +---------
 drivers/media/dvb-frontends/tda665x.c      |   11 +----------
 drivers/media/dvb-frontends/tda8261.c      |   11 +----------
 drivers/media/dvb-frontends/tda826x.c      |    9 +--------
 drivers/media/dvb-frontends/tua6100.c      |    9 +--------
 drivers/media/dvb-frontends/zl10036.c      |   12 +-----------
 drivers/media/tuners/fc0011.c              |   10 +---------
 drivers/media/tuners/fc0012.c              |    9 +--------
 drivers/media/tuners/fc0013.c              |    9 +--------
 drivers/media/tuners/mc44s803.c            |   12 +-----------
 drivers/media/tuners/mt2060.c              |    9 +--------
 drivers/media/tuners/mt20xx.c              |   12 ++----------
 drivers/media/tuners/mt2266.c              |    9 +--------
 drivers/media/tuners/qt1010.c              |    9 +--------
 drivers/media/tuners/tda18218.c            |    9 +--------
 drivers/media/tuners/tda827x.c             |   11 ++---------
 drivers/media/tuners/tea5761.c             |   10 +---------
 drivers/media/tuners/tea5767.c             |   10 +---------
 29 files changed, 46 insertions(+), 245 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index be99c8d..ed9686b 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -169,6 +169,15 @@ static bool has_get_frontend(struct dvb_frontend *fe)
 	return fe->ops.get_frontend != NULL;
 }
 
+int
+dvb_tuner_simple_release(struct dvb_frontend *fe)
+{
+	kfree(fe->tuner_priv);
+	fe->tuner_priv = NULL;
+	return 0;
+}
+EXPORT_SYMBOL(dvb_tuner_simple_release);
+
 /*
  * Due to DVBv3 API calls, a delivery system should be mapped into one of
  * the 4 DVBv3 delivery systems (FE_QPSK, FE_QAM, FE_OFDM or FE_ATSC),
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index fb6e848..6b675a8 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -267,6 +267,13 @@ struct dvb_tuner_ops {
 };
 
 /**
+ * A common default implementation for dvb_tuner_ops.release.  All it
+ * does is kfree() the tuner_priv and assign NULL to it.
+ */
+int
+dvb_tuner_simple_release(struct dvb_frontend *fe);
+
+/**
  * struct analog_demod_info - Information struct for analog TV part of the demod
  *
  * @name:	Name of the analog TV demodulator
diff --git a/drivers/media/dvb-frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c
index ee7d669..8e31f12 100644
--- a/drivers/media/dvb-frontends/dib0070.c
+++ b/drivers/media/dvb-frontends/dib0070.c
@@ -722,13 +722,6 @@ static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static int dib0070_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static const struct dvb_tuner_ops dib0070_ops = {
 	.info = {
 		.name           = "DiBcom DiB0070",
@@ -736,7 +729,7 @@ static const struct dvb_tuner_ops dib0070_ops = {
 		.frequency_max  = 860000000,
 		.frequency_step =      1000,
 	},
-	.release       = dib0070_release,
+	.release       = dvb_tuner_simple_release,
 
 	.init          = dib0070_wakeup,
 	.sleep         = dib0070_sleep,
diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c
index 14c4032..7780df2 100644
--- a/drivers/media/dvb-frontends/dib0090.c
+++ b/drivers/media/dvb-frontends/dib0090.c
@@ -2524,13 +2524,6 @@ static int dib0090_tune(struct dvb_frontend *fe)
 	return ret;
 }
 
-static int dib0090_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
 {
 	struct dib0090_state *state = fe->tuner_priv;
@@ -2592,7 +2585,7 @@ static const struct dvb_tuner_ops dib0090_ops = {
 		 .frequency_max = 860000000,
 		 .frequency_step = 1000,
 		 },
-	.release = dib0090_release,
+	.release = dvb_tuner_simple_release,
 
 	.init = dib0090_wakeup,
 	.sleep = dib0090_sleep,
@@ -2607,7 +2600,7 @@ static const struct dvb_tuner_ops dib0090_fw_ops = {
 		 .frequency_max = 860000000,
 		 .frequency_step = 1000,
 		 },
-	.release = dib0090_release,
+	.release = dvb_tuner_simple_release,
 
 	.init = NULL,
 	.sleep = NULL,
diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c
index 735a966..7065806 100644
--- a/drivers/media/dvb-frontends/dvb-pll.c
+++ b/drivers/media/dvb-frontends/dvb-pll.c
@@ -601,13 +601,6 @@ static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf,
 	return (div * desc->entries[i].stepsize) - desc->iffreq;
 }
 
-static int dvb_pll_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static int dvb_pll_sleep(struct dvb_frontend *fe)
 {
 	struct dvb_pll_priv *priv = fe->tuner_priv;
@@ -740,7 +733,7 @@ static int dvb_pll_init(struct dvb_frontend *fe)
 }
 
 static const struct dvb_tuner_ops dvb_pll_tuner_ops = {
-	.release = dvb_pll_release,
+	.release = dvb_tuner_simple_release,
 	.sleep = dvb_pll_sleep,
 	.init = dvb_pll_init,
 	.set_params = dvb_pll_set_params,
diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c
index cadcae4..d09f718 100644
--- a/drivers/media/dvb-frontends/itd1000.c
+++ b/drivers/media/dvb-frontends/itd1000.c
@@ -348,13 +348,6 @@ static int itd1000_sleep(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int itd1000_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static const struct dvb_tuner_ops itd1000_tuner_ops = {
 	.info = {
 		.name           = "Integrant ITD1000",
@@ -363,7 +356,7 @@ static const struct dvb_tuner_ops itd1000_tuner_ops = {
 		.frequency_step = 125,     /* kHz for QPSK frontends */
 	},
 
-	.release       = itd1000_release,
+	.release       = dvb_tuner_simple_release,
 
 	.init          = itd1000_init,
 	.sleep         = itd1000_sleep,
diff --git a/drivers/media/dvb-frontends/ix2505v.c b/drivers/media/dvb-frontends/ix2505v.c
index 2826bbb..7742a7a 100644
--- a/drivers/media/dvb-frontends/ix2505v.c
+++ b/drivers/media/dvb-frontends/ix2505v.c
@@ -94,16 +94,6 @@ static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count)
 	return 0;
 }
 
-static int ix2505v_release(struct dvb_frontend *fe)
-{
-	struct ix2505v_state *state = fe->tuner_priv;
-
-	fe->tuner_priv = NULL;
-	kfree(state);
-
-	return 0;
-}
-
 /**
  *  Data write format of the Sharp IX2505V B0017
  *
@@ -264,7 +254,7 @@ static const struct dvb_tuner_ops ix2505v_tuner_ops = {
 		.frequency_min = 950000,
 		.frequency_max = 2175000
 	},
-	.release = ix2505v_release,
+	.release = dvb_tuner_simple_release,
 	.set_params = ix2505v_set_params,
 	.get_frequency = ix2505v_get_frequency,
 };
diff --git a/drivers/media/dvb-frontends/stb6000.c b/drivers/media/dvb-frontends/stb6000.c
index 73347d5..5252d48 100644
--- a/drivers/media/dvb-frontends/stb6000.c
+++ b/drivers/media/dvb-frontends/stb6000.c
@@ -41,13 +41,6 @@ struct stb6000_priv {
 	u32 frequency;
 };
 
-static int stb6000_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static int stb6000_sleep(struct dvb_frontend *fe)
 {
 	struct stb6000_priv *priv = fe->tuner_priv;
@@ -192,7 +185,7 @@ static const struct dvb_tuner_ops stb6000_tuner_ops = {
 		.frequency_min = 950000,
 		.frequency_max = 2150000
 	},
-	.release = stb6000_release,
+	.release = dvb_tuner_simple_release,
 	.sleep = stb6000_sleep,
 	.set_params = stb6000_set_params,
 	.get_frequency = stb6000_get_frequency,
diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c
index 5add118..befd26b 100644
--- a/drivers/media/dvb-frontends/stb6100.c
+++ b/drivers/media/dvb-frontends/stb6100.c
@@ -61,8 +61,6 @@ struct stb6100_lkup {
 	u8   reg;
 };
 
-static int stb6100_release(struct dvb_frontend *fe);
-
 static const struct stb6100_lkup lkup[] = {
 	{       0,  950000, 0x0a },
 	{  950000, 1000000, 0x0a },
@@ -536,7 +534,7 @@ static const struct dvb_tuner_ops stb6100_ops = {
 	.set_params	= stb6100_set_params,
 	.get_frequency  = stb6100_get_frequency,
 	.get_bandwidth  = stb6100_get_bandwidth,
-	.release	= stb6100_release
+	.release	= dvb_tuner_simple_release
 };
 
 struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
@@ -560,16 +558,6 @@ struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
 	return fe;
 }
 
-static int stb6100_release(struct dvb_frontend *fe)
-{
-	struct stb6100_state *state = fe->tuner_priv;
-
-	fe->tuner_priv = NULL;
-	kfree(state);
-
-	return 0;
-}
-
 EXPORT_SYMBOL(stb6100_attach);
 MODULE_PARM_DESC(verbose, "Set Verbosity level");
 
diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c
index 66a5a7f..d9a88ad 100644
--- a/drivers/media/dvb-frontends/stv6110.c
+++ b/drivers/media/dvb-frontends/stv6110.c
@@ -59,13 +59,6 @@ static s32 abssub(s32 a, s32 b)
 		return b - a;
 };
 
-static int stv6110_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[],
 							int start, int len)
 {
@@ -390,7 +383,7 @@ static const struct dvb_tuner_ops stv6110_tuner_ops = {
 		.frequency_step = 1000,
 	},
 	.init = stv6110_init,
-	.release = stv6110_release,
+	.release = dvb_tuner_simple_release,
 	.sleep = stv6110_sleep,
 	.set_params = stv6110_set_params,
 	.get_frequency = stv6110_get_frequency,
diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c
index c611ad2..70d5641 100644
--- a/drivers/media/dvb-frontends/stv6110x.c
+++ b/drivers/media/dvb-frontends/stv6110x.c
@@ -335,16 +335,6 @@ static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)
 }
 
 
-static int stv6110x_release(struct dvb_frontend *fe)
-{
-	struct stv6110x_state *stv6110x = fe->tuner_priv;
-
-	fe->tuner_priv = NULL;
-	kfree(stv6110x);
-
-	return 0;
-}
-
 static const struct dvb_tuner_ops stv6110x_ops = {
 	.info = {
 		.name		= "STV6110(A) Silicon Tuner",
@@ -352,7 +342,7 @@ static const struct dvb_tuner_ops stv6110x_ops = {
 		.frequency_max	= 2150000,
 		.frequency_step	= 0,
 	},
-	.release		= stv6110x_release
+	.release		= dvb_tuner_simple_release,
 };
 
 static const struct stv6110x_devctl stv6110x_ctl = {
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c
index bc247f9..a324f30 100644
--- a/drivers/media/dvb-frontends/tda18271c2dd.c
+++ b/drivers/media/dvb-frontends/tda18271c2dd.c
@@ -1126,14 +1126,6 @@ static int init(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
-
 static int set_params(struct dvb_frontend *fe)
 {
 	struct tda_state *state = fe->tuner_priv;
@@ -1227,7 +1219,7 @@ static const struct dvb_tuner_ops tuner_ops = {
 	.init              = init,
 	.sleep             = sleep,
 	.set_params        = set_params,
-	.release           = release,
+	.release           = dvb_tuner_simple_release,
 	.get_if_frequency  = get_if_frequency,
 	.get_bandwidth     = get_bandwidth,
 };
diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c
index 7ca9659..39a1eb2 100644
--- a/drivers/media/dvb-frontends/tda665x.c
+++ b/drivers/media/dvb-frontends/tda665x.c
@@ -197,20 +197,11 @@ static int tda665x_set_params(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int tda665x_release(struct dvb_frontend *fe)
-{
-	struct tda665x_state *state = fe->tuner_priv;
-
-	fe->tuner_priv = NULL;
-	kfree(state);
-	return 0;
-}
-
 static const struct dvb_tuner_ops tda665x_ops = {
 	.get_status	= tda665x_get_status,
 	.set_params	= tda665x_set_params,
 	.get_frequency	= tda665x_get_frequency,
-	.release	= tda665x_release
+	.release	= dvb_tuner_simple_release,
 };
 
 struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c
index e0df931..65f729f 100644
--- a/drivers/media/dvb-frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -152,15 +152,6 @@ static int tda8261_set_params(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int tda8261_release(struct dvb_frontend *fe)
-{
-	struct tda8261_state *state = fe->tuner_priv;
-
-	fe->tuner_priv = NULL;
-	kfree(state);
-	return 0;
-}
-
 static const struct dvb_tuner_ops tda8261_ops = {
 
 	.info = {
@@ -173,7 +164,7 @@ static const struct dvb_tuner_ops tda8261_ops = {
 	.set_params	= tda8261_set_params,
 	.get_frequency	= tda8261_get_frequency,
 	.get_status	= tda8261_get_status,
-	.release	= tda8261_release
+	.release	= dvb_tuner_simple_release,
 };
 
 struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/dvb-frontends/tda826x.c b/drivers/media/dvb-frontends/tda826x.c
index 2ec671d..bf8946c 100644
--- a/drivers/media/dvb-frontends/tda826x.c
+++ b/drivers/media/dvb-frontends/tda826x.c
@@ -41,13 +41,6 @@ struct tda826x_priv {
 	u32 frequency;
 };
 
-static int tda826x_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static int tda826x_sleep(struct dvb_frontend *fe)
 {
 	struct tda826x_priv *priv = fe->tuner_priv;
@@ -135,7 +128,7 @@ static const struct dvb_tuner_ops tda826x_tuner_ops = {
 		.frequency_min = 950000,
 		.frequency_max = 2175000
 	},
-	.release = tda826x_release,
+	.release = dvb_tuner_simple_release,
 	.sleep = tda826x_sleep,
 	.set_params = tda826x_set_params,
 	.get_frequency = tda826x_get_frequency,
diff --git a/drivers/media/dvb-frontends/tua6100.c b/drivers/media/dvb-frontends/tua6100.c
index 6da12b9..9e9a8ad 100644
--- a/drivers/media/dvb-frontends/tua6100.c
+++ b/drivers/media/dvb-frontends/tua6100.c
@@ -42,13 +42,6 @@ struct tua6100_priv {
 	u32 frequency;
 };
 
-static int tua6100_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static int tua6100_sleep(struct dvb_frontend *fe)
 {
 	struct tua6100_priv *priv = fe->tuner_priv;
@@ -164,7 +157,7 @@ static const struct dvb_tuner_ops tua6100_tuner_ops = {
 		.frequency_max = 2150000,
 		.frequency_step = 1000,
 	},
-	.release = tua6100_release,
+	.release = dvb_tuner_simple_release,
 	.sleep = tua6100_sleep,
 	.set_params = tua6100_set_params,
 	.get_frequency = tua6100_get_frequency,
diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c
index 7ed8131..2368188 100644
--- a/drivers/media/dvb-frontends/zl10036.c
+++ b/drivers/media/dvb-frontends/zl10036.c
@@ -134,16 +134,6 @@ static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count)
 	return 0;
 }
 
-static int zl10036_release(struct dvb_frontend *fe)
-{
-	struct zl10036_state *state = fe->tuner_priv;
-
-	fe->tuner_priv = NULL;
-	kfree(state);
-
-	return 0;
-}
-
 static int zl10036_sleep(struct dvb_frontend *fe)
 {
 	struct zl10036_state *state = fe->tuner_priv;
@@ -453,7 +443,7 @@ static const struct dvb_tuner_ops zl10036_tuner_ops = {
 		.frequency_max = 2175000
 	},
 	.init = zl10036_init,
-	.release = zl10036_release,
+	.release = dvb_tuner_simple_release,
 	.sleep = zl10036_sleep,
 	.set_params = zl10036_set_params,
 	.get_frequency = zl10036_get_frequency,
diff --git a/drivers/media/tuners/fc0011.c b/drivers/media/tuners/fc0011.c
index 3932aa8..a7c6df2 100644
--- a/drivers/media/tuners/fc0011.c
+++ b/drivers/media/tuners/fc0011.c
@@ -112,14 +112,6 @@ static int fc0011_readreg(struct fc0011_priv *priv, u8 reg, u8 *val)
 	return 0;
 }
 
-static int fc0011_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-
-	return 0;
-}
-
 static int fc0011_init(struct dvb_frontend *fe)
 {
 	struct fc0011_priv *priv = fe->tuner_priv;
@@ -486,7 +478,7 @@ static const struct dvb_tuner_ops fc0011_tuner_ops = {
 		.frequency_max	= 1000000000,
 	},
 
-	.release		= fc0011_release,
+	.release		= dvb_tuner_simple_release,
 	.init			= fc0011_init,
 
 	.set_params		= fc0011_set_params,
diff --git a/drivers/media/tuners/fc0012.c b/drivers/media/tuners/fc0012.c
index d74e920..7faff84 100644
--- a/drivers/media/tuners/fc0012.c
+++ b/drivers/media/tuners/fc0012.c
@@ -55,13 +55,6 @@ static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val)
 	return 0;
 }
 
-static int fc0012_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static int fc0012_init(struct dvb_frontend *fe)
 {
 	struct fc0012_priv *priv = fe->tuner_priv;
@@ -427,7 +420,7 @@ static const struct dvb_tuner_ops fc0012_tuner_ops = {
 		.frequency_step = 0,
 	},
 
-	.release	= fc0012_release,
+	.release	= dvb_tuner_simple_release,
 
 	.init		= fc0012_init,
 
diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c
index 522690d..b068b97 100644
--- a/drivers/media/tuners/fc0013.c
+++ b/drivers/media/tuners/fc0013.c
@@ -52,13 +52,6 @@ static int fc0013_readreg(struct fc0013_priv *priv, u8 reg, u8 *val)
 	return 0;
 }
 
-static int fc0013_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static int fc0013_init(struct dvb_frontend *fe)
 {
 	struct fc0013_priv *priv = fe->tuner_priv;
@@ -586,7 +579,7 @@ static const struct dvb_tuner_ops fc0013_tuner_ops = {
 		.frequency_step	= 0,
 	},
 
-	.release	= fc0013_release,
+	.release	= dvb_tuner_simple_release,
 
 	.init		= fc0013_init,
 	.sleep		= fc0013_sleep,
diff --git a/drivers/media/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c
index f1b7640..c6c8113 100644
--- a/drivers/media/tuners/mc44s803.c
+++ b/drivers/media/tuners/mc44s803.c
@@ -80,16 +80,6 @@ static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val)
 	return 0;
 }
 
-static int mc44s803_release(struct dvb_frontend *fe)
-{
-	struct mc44s803_priv *priv = fe->tuner_priv;
-
-	fe->tuner_priv = NULL;
-	kfree(priv);
-
-	return 0;
-}
-
 static int mc44s803_init(struct dvb_frontend *fe)
 {
 	struct mc44s803_priv *priv = fe->tuner_priv;
@@ -312,7 +302,7 @@ static const struct dvb_tuner_ops mc44s803_tuner_ops = {
 		.frequency_step =     100000,
 	},
 
-	.release       = mc44s803_release,
+	.release       = dvb_tuner_simple_release,
 	.init          = mc44s803_init,
 	.set_params    = mc44s803_set_params,
 	.get_frequency = mc44s803_get_frequency,
diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c
index b87b254..14e7b64 100644
--- a/drivers/media/tuners/mt2060.c
+++ b/drivers/media/tuners/mt2060.c
@@ -332,13 +332,6 @@ static int mt2060_sleep(struct dvb_frontend *fe)
 	return ret;
 }
 
-static int mt2060_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static const struct dvb_tuner_ops mt2060_tuner_ops = {
 	.info = {
 		.name           = "Microtune MT2060",
@@ -347,7 +340,7 @@ static const struct dvb_tuner_ops mt2060_tuner_ops = {
 		.frequency_step =     50000,
 	},
 
-	.release       = mt2060_release,
+	.release       = dvb_tuner_simple_release,
 
 	.init          = mt2060_init,
 	.sleep         = mt2060_sleep,
diff --git a/drivers/media/tuners/mt20xx.c b/drivers/media/tuners/mt20xx.c
index 52da467..72a6a97 100644
--- a/drivers/media/tuners/mt20xx.c
+++ b/drivers/media/tuners/mt20xx.c
@@ -49,14 +49,6 @@ struct microtune_priv {
 	u32 frequency;
 };
 
-static int microtune_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-
-	return 0;
-}
-
 static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 {
 	struct microtune_priv *priv = fe->tuner_priv;
@@ -365,7 +357,7 @@ static int mt2032_set_params(struct dvb_frontend *fe,
 
 static const struct dvb_tuner_ops mt2032_tuner_ops = {
 	.set_analog_params = mt2032_set_params,
-	.release           = microtune_release,
+	.release           = dvb_tuner_simple_release,
 	.get_frequency     = microtune_get_frequency,
 };
 
@@ -565,7 +557,7 @@ static int mt2050_set_params(struct dvb_frontend *fe,
 
 static const struct dvb_tuner_ops mt2050_tuner_ops = {
 	.set_analog_params = mt2050_set_params,
-	.release           = microtune_release,
+	.release           = dvb_tuner_simple_release,
 	.get_frequency     = microtune_get_frequency,
 };
 
diff --git a/drivers/media/tuners/mt2266.c b/drivers/media/tuners/mt2266.c
index bca4d75..35ea5e7 100644
--- a/drivers/media/tuners/mt2266.c
+++ b/drivers/media/tuners/mt2266.c
@@ -296,13 +296,6 @@ static int mt2266_sleep(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int mt2266_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static const struct dvb_tuner_ops mt2266_tuner_ops = {
 	.info = {
 		.name           = "Microtune MT2266",
@@ -310,7 +303,7 @@ static const struct dvb_tuner_ops mt2266_tuner_ops = {
 		.frequency_max  = 862000000,
 		.frequency_step =     50000,
 	},
-	.release       = mt2266_release,
+	.release       = dvb_tuner_simple_release,
 	.init          = mt2266_init,
 	.sleep         = mt2266_sleep,
 	.set_params    = mt2266_set_params,
diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c
index ae8cbec..5a1662a 100644
--- a/drivers/media/tuners/qt1010.c
+++ b/drivers/media/tuners/qt1010.c
@@ -377,13 +377,6 @@ static int qt1010_init(struct dvb_frontend *fe)
 	return qt1010_set_params(fe);
 }
 
-static int qt1010_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 {
 	struct qt1010_priv *priv = fe->tuner_priv;
@@ -405,7 +398,7 @@ static const struct dvb_tuner_ops qt1010_tuner_ops = {
 		.frequency_step = QT1010_STEP,
 	},
 
-	.release       = qt1010_release,
+	.release       = dvb_tuner_simple_release,
 	.init          = qt1010_init,
 	/* TODO: implement sleep */
 
diff --git a/drivers/media/tuners/tda18218.c b/drivers/media/tuners/tda18218.c
index 9300e93..4d2916f 100644
--- a/drivers/media/tuners/tda18218.c
+++ b/drivers/media/tuners/tda18218.c
@@ -265,13 +265,6 @@ static int tda18218_init(struct dvb_frontend *fe)
 	return ret;
 }
 
-static int tda18218_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static const struct dvb_tuner_ops tda18218_tuner_ops = {
 	.info = {
 		.name           = "NXP TDA18218",
@@ -281,7 +274,7 @@ static const struct dvb_tuner_ops tda18218_tuner_ops = {
 		.frequency_step =      1000,
 	},
 
-	.release       = tda18218_release,
+	.release       = dvb_tuner_simple_release,
 	.init          = tda18218_init,
 	.sleep         = tda18218_sleep,
 
diff --git a/drivers/media/tuners/tda827x.c b/drivers/media/tuners/tda827x.c
index 5050ce9..4befb81 100644
--- a/drivers/media/tuners/tda827x.c
+++ b/drivers/media/tuners/tda827x.c
@@ -767,13 +767,6 @@ static void tda827xa_agcf(struct dvb_frontend *fe)
 
 /* ------------------------------------------------------------------ */
 
-static int tda827x_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-	return 0;
-}
-
 static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 {
 	struct tda827x_priv *priv = fe->tuner_priv;
@@ -825,7 +818,7 @@ static const struct dvb_tuner_ops tda827xo_tuner_ops = {
 		.frequency_max  = 860000000,
 		.frequency_step =    250000
 	},
-	.release = tda827x_release,
+	.release = dvb_tuner_simple_release,
 	.init = tda827x_initial_init,
 	.sleep = tda827x_initial_sleep,
 	.set_params = tda827xo_set_params,
@@ -841,7 +834,7 @@ static const struct dvb_tuner_ops tda827xa_tuner_ops = {
 		.frequency_max  = 906000000,
 		.frequency_step =     62500
 	},
-	.release = tda827x_release,
+	.release = dvb_tuner_simple_release,
 	.init = tda827x_init,
 	.sleep = tda827xa_sleep,
 	.set_params = tda827xa_set_params,
diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c
index 36b0b1e..be184c5 100644
--- a/drivers/media/tuners/tea5761.c
+++ b/drivers/media/tuners/tea5761.c
@@ -286,14 +286,6 @@ int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
 	return 0;
 }
 
-static int tea5761_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-
-	return 0;
-}
-
 static int tea5761_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 {
 	struct tea5761_priv *priv = fe->tuner_priv;
@@ -307,7 +299,7 @@ static const struct dvb_tuner_ops tea5761_tuner_ops = {
 	},
 	.set_analog_params = set_radio_freq,
 	.sleep		   = set_radio_sleep,
-	.release           = tea5761_release,
+	.release           = dvb_tuner_simple_release,
 	.get_frequency     = tea5761_get_frequency,
 	.get_status        = tea5761_get_status,
 	.get_rf_strength   = tea5761_get_rf_strength,
diff --git a/drivers/media/tuners/tea5767.c b/drivers/media/tuners/tea5767.c
index 6d86aa6..5edc4f9 100644
--- a/drivers/media/tuners/tea5767.c
+++ b/drivers/media/tuners/tea5767.c
@@ -398,14 +398,6 @@ int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
 	return 0;
 }
 
-static int tea5767_release(struct dvb_frontend *fe)
-{
-	kfree(fe->tuner_priv);
-	fe->tuner_priv = NULL;
-
-	return 0;
-}
-
 static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 {
 	struct tea5767_priv *priv = fe->tuner_priv;
@@ -431,7 +423,7 @@ static const struct dvb_tuner_ops tea5767_tuner_ops = {
 	.set_analog_params = set_radio_freq,
 	.set_config	   = tea5767_set_config,
 	.sleep             = tea5767_standby,
-	.release           = tea5767_release,
+	.release           = dvb_tuner_simple_release,
 	.get_frequency     = tea5767_get_frequency,
 	.get_status        = tea5767_get_status,
 	.get_rf_strength   = tea5767_get_rf_strength,

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 06/12] [media] dvb_frontend: tuner_ops.release returns void
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
                   ` (3 preceding siblings ...)
  2016-08-09 21:32 ` [PATCH 05/12] [media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations Max Kellermann
@ 2016-08-09 21:32 ` Max Kellermann
  2016-08-09 21:32 ` [PATCH 07/12] [media] dvb_frontend: merge the two dvb_frontend_detach() versions Max Kellermann
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

It is not clear what this return value means.  All implemenations
return 0, and the one caller ignores the value.  Let's remove this
useless return value completely.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/dvb-core/dvb_frontend.c         |    3 +--
 drivers/media/dvb-core/dvb_frontend.h         |    4 ++--
 drivers/media/dvb-frontends/ascot2e.c         |    3 +--
 drivers/media/dvb-frontends/cx24113.c         |    3 +--
 drivers/media/dvb-frontends/helene.c          |    3 +--
 drivers/media/dvb-frontends/horus3a.c         |    3 +--
 drivers/media/dvb-frontends/ts2020.c          |    3 +--
 drivers/media/dvb-frontends/zl10039.c         |    3 +--
 drivers/media/tuners/max2165.c                |    4 +---
 drivers/media/tuners/mt2063.c                 |    4 +---
 drivers/media/tuners/mt2131.c                 |    3 +--
 drivers/media/tuners/mxl5005s.c               |    3 +--
 drivers/media/tuners/mxl5007t.c               |    4 +---
 drivers/media/tuners/r820t.c                  |    4 +---
 drivers/media/tuners/tda18271-fe.c            |    4 +---
 drivers/media/tuners/tuner-simple.c           |    4 +---
 drivers/media/tuners/tuner-xc2028.c           |    4 +---
 drivers/media/tuners/xc4000.c                 |    4 +---
 drivers/media/tuners/xc5000.c                 |    4 +---
 drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c |    3 +--
 20 files changed, 21 insertions(+), 49 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index ed9686b..fea635b 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -169,12 +169,11 @@ static bool has_get_frontend(struct dvb_frontend *fe)
 	return fe->ops.get_frontend != NULL;
 }
 
-int
+void
 dvb_tuner_simple_release(struct dvb_frontend *fe)
 {
 	kfree(fe->tuner_priv);
 	fe->tuner_priv = NULL;
-	return 0;
 }
 EXPORT_SYMBOL(dvb_tuner_simple_release);
 
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 6b675a8..5bfb16b 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -225,7 +225,7 @@ struct dvb_tuner_ops {
 
 	struct dvb_tuner_info info;
 
-	int (*release)(struct dvb_frontend *fe);
+	void (*release)(struct dvb_frontend *fe);
 	int (*init)(struct dvb_frontend *fe);
 	int (*sleep)(struct dvb_frontend *fe);
 	int (*suspend)(struct dvb_frontend *fe);
@@ -270,7 +270,7 @@ struct dvb_tuner_ops {
  * A common default implementation for dvb_tuner_ops.release.  All it
  * does is kfree() the tuner_priv and assign NULL to it.
  */
-int
+void
 dvb_tuner_simple_release(struct dvb_frontend *fe);
 
 /**
diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c
index ad304ee..0ee0df5 100644
--- a/drivers/media/dvb-frontends/ascot2e.c
+++ b/drivers/media/dvb-frontends/ascot2e.c
@@ -254,14 +254,13 @@ static int ascot2e_init(struct dvb_frontend *fe)
 	return ascot2e_leave_power_save(priv);
 }
 
-static int ascot2e_release(struct dvb_frontend *fe)
+static void ascot2e_release(struct dvb_frontend *fe)
 {
 	struct ascot2e_priv *priv = fe->tuner_priv;
 
 	dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 	kfree(fe->tuner_priv);
 	fe->tuner_priv = NULL;
-	return 0;
 }
 
 static int ascot2e_sleep(struct dvb_frontend *fe)
diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c
index 3883c3b..0c0b4f6 100644
--- a/drivers/media/dvb-frontends/cx24113.c
+++ b/drivers/media/dvb-frontends/cx24113.c
@@ -527,13 +527,12 @@ static int cx24113_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static int cx24113_release(struct dvb_frontend *fe)
+static void cx24113_release(struct dvb_frontend *fe)
 {
 	struct cx24113_state *state = fe->tuner_priv;
 	dprintk("\n");
 	fe->tuner_priv = NULL;
 	kfree(state);
-	return 0;
 }
 
 static const struct dvb_tuner_ops cx24113_tuner_ops = {
diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c
index 4cb0505..fa56a20 100644
--- a/drivers/media/dvb-frontends/helene.c
+++ b/drivers/media/dvb-frontends/helene.c
@@ -434,14 +434,13 @@ static int helene_init(struct dvb_frontend *fe)
 	return helene_leave_power_save(priv);
 }
 
-static int helene_release(struct dvb_frontend *fe)
+static void helene_release(struct dvb_frontend *fe)
 {
 	struct helene_priv *priv = fe->tuner_priv;
 
 	dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 	kfree(fe->tuner_priv);
 	fe->tuner_priv = NULL;
-	return 0;
 }
 
 static int helene_sleep(struct dvb_frontend *fe)
diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c
index 0c089b5..94bb4f7 100644
--- a/drivers/media/dvb-frontends/horus3a.c
+++ b/drivers/media/dvb-frontends/horus3a.c
@@ -151,14 +151,13 @@ static int horus3a_init(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int horus3a_release(struct dvb_frontend *fe)
+static void horus3a_release(struct dvb_frontend *fe)
 {
 	struct horus3a_priv *priv = fe->tuner_priv;
 
 	dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 	kfree(fe->tuner_priv);
 	fe->tuner_priv = NULL;
-	return 0;
 }
 
 static int horus3a_sleep(struct dvb_frontend *fe)
diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c
index a9f6bbe..931e5c9 100644
--- a/drivers/media/dvb-frontends/ts2020.c
+++ b/drivers/media/dvb-frontends/ts2020.c
@@ -56,7 +56,7 @@ struct ts2020_reg_val {
 
 static void ts2020_stat_work(struct work_struct *work);
 
-static int ts2020_release(struct dvb_frontend *fe)
+static void ts2020_release(struct dvb_frontend *fe)
 {
 	struct ts2020_priv *priv = fe->tuner_priv;
 	struct i2c_client *client = priv->client;
@@ -64,7 +64,6 @@ static int ts2020_release(struct dvb_frontend *fe)
 	dev_dbg(&client->dev, "\n");
 
 	i2c_unregister_device(client);
-	return 0;
 }
 
 static int ts2020_sleep(struct dvb_frontend *fe)
diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c
index f8c271b..22cea79 100644
--- a/drivers/media/dvb-frontends/zl10039.c
+++ b/drivers/media/dvb-frontends/zl10039.c
@@ -245,14 +245,13 @@ error:
 	return ret;
 }
 
-static int zl10039_release(struct dvb_frontend *fe)
+static void zl10039_release(struct dvb_frontend *fe)
 {
 	struct zl10039_state *state = fe->tuner_priv;
 
 	dprintk("%s\n", __func__);
 	kfree(state);
 	fe->tuner_priv = NULL;
-	return 0;
 }
 
 static const struct dvb_tuner_ops zl10039_ops = {
diff --git a/drivers/media/tuners/max2165.c b/drivers/media/tuners/max2165.c
index 353b178..c3f1092 100644
--- a/drivers/media/tuners/max2165.c
+++ b/drivers/media/tuners/max2165.c
@@ -370,15 +370,13 @@ static int max2165_init(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int max2165_release(struct dvb_frontend *fe)
+static void max2165_release(struct dvb_frontend *fe)
 {
 	struct max2165_priv *priv = fe->tuner_priv;
 	dprintk("%s()\n", __func__);
 
 	kfree(priv);
 	fe->tuner_priv = NULL;
-
-	return 0;
 }
 
 static const struct dvb_tuner_ops max2165_tuner_ops = {
diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c
index dfec237..8b39d8d 100644
--- a/drivers/media/tuners/mt2063.c
+++ b/drivers/media/tuners/mt2063.c
@@ -2019,7 +2019,7 @@ static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
 	return 0;
 }
 
-static int mt2063_release(struct dvb_frontend *fe)
+static void mt2063_release(struct dvb_frontend *fe)
 {
 	struct mt2063_state *state = fe->tuner_priv;
 
@@ -2027,8 +2027,6 @@ static int mt2063_release(struct dvb_frontend *fe)
 
 	fe->tuner_priv = NULL;
 	kfree(state);
-
-	return 0;
 }
 
 static int mt2063_set_analog_params(struct dvb_frontend *fe,
diff --git a/drivers/media/tuners/mt2131.c b/drivers/media/tuners/mt2131.c
index 6e2cdd2..e7790e4 100644
--- a/drivers/media/tuners/mt2131.c
+++ b/drivers/media/tuners/mt2131.c
@@ -230,12 +230,11 @@ static int mt2131_init(struct dvb_frontend *fe)
 	return ret;
 }
 
-static int mt2131_release(struct dvb_frontend *fe)
+static void mt2131_release(struct dvb_frontend *fe)
 {
 	dprintk(1, "%s()\n", __func__);
 	kfree(fe->tuner_priv);
 	fe->tuner_priv = NULL;
-	return 0;
 }
 
 static const struct dvb_tuner_ops mt2131_tuner_ops = {
diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c
index 92a3be4..353744f 100644
--- a/drivers/media/tuners/mxl5005s.c
+++ b/drivers/media/tuners/mxl5005s.c
@@ -4063,12 +4063,11 @@ static int mxl5005s_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static int mxl5005s_release(struct dvb_frontend *fe)
+static void mxl5005s_release(struct dvb_frontend *fe)
 {
 	dprintk(1, "%s()\n", __func__);
 	kfree(fe->tuner_priv);
 	fe->tuner_priv = NULL;
-	return 0;
 }
 
 static const struct dvb_tuner_ops mxl5005s_tuner_ops = {
diff --git a/drivers/media/tuners/mxl5007t.c b/drivers/media/tuners/mxl5007t.c
index 42569c6..b16dfa5 100644
--- a/drivers/media/tuners/mxl5007t.c
+++ b/drivers/media/tuners/mxl5007t.c
@@ -776,7 +776,7 @@ static int mxl5007t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static int mxl5007t_release(struct dvb_frontend *fe)
+static void mxl5007t_release(struct dvb_frontend *fe)
 {
 	struct mxl5007t_state *state = fe->tuner_priv;
 
@@ -788,8 +788,6 @@ static int mxl5007t_release(struct dvb_frontend *fe)
 	mutex_unlock(&mxl5007t_list_mutex);
 
 	fe->tuner_priv = NULL;
-
-	return 0;
 }
 
 /* ------------------------------------------------------------------------- */
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index 08dca40..ba80376 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -2286,7 +2286,7 @@ static int r820t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
 	return 0;
 }
 
-static int r820t_release(struct dvb_frontend *fe)
+static void r820t_release(struct dvb_frontend *fe)
 {
 	struct r820t_priv *priv = fe->tuner_priv;
 
@@ -2300,8 +2300,6 @@ static int r820t_release(struct dvb_frontend *fe)
 	mutex_unlock(&r820t_list_mutex);
 
 	fe->tuner_priv = NULL;
-
-	return 0;
 }
 
 static const struct dvb_tuner_ops r820t_tuner_ops = {
diff --git a/drivers/media/tuners/tda18271-fe.c b/drivers/media/tuners/tda18271-fe.c
index f862074..ee2733a 100644
--- a/drivers/media/tuners/tda18271-fe.c
+++ b/drivers/media/tuners/tda18271-fe.c
@@ -1048,7 +1048,7 @@ fail:
 	return ret;
 }
 
-static int tda18271_release(struct dvb_frontend *fe)
+static void tda18271_release(struct dvb_frontend *fe)
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 
@@ -1060,8 +1060,6 @@ static int tda18271_release(struct dvb_frontend *fe)
 	mutex_unlock(&tda18271_list_mutex);
 
 	fe->tuner_priv = NULL;
-
-	return 0;
 }
 
 static int tda18271_get_frequency(struct dvb_frontend *fe, u32 *frequency)
diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c
index 9ba9582..63a1d41 100644
--- a/drivers/media/tuners/tuner-simple.c
+++ b/drivers/media/tuners/tuner-simple.c
@@ -1005,7 +1005,7 @@ static int simple_sleep(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int simple_release(struct dvb_frontend *fe)
+static void simple_release(struct dvb_frontend *fe)
 {
 	struct tuner_simple_priv *priv = fe->tuner_priv;
 
@@ -1017,8 +1017,6 @@ static int simple_release(struct dvb_frontend *fe)
 	mutex_unlock(&tuner_simple_list_mutex);
 
 	fe->tuner_priv = NULL;
-
-	return 0;
 }
 
 static int simple_get_frequency(struct dvb_frontend *fe, u32 *frequency)
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
index 317ef63..300d63c 100644
--- a/drivers/media/tuners/tuner-xc2028.c
+++ b/drivers/media/tuners/tuner-xc2028.c
@@ -1323,7 +1323,7 @@ static int xc2028_sleep(struct dvb_frontend *fe)
 	return rc;
 }
 
-static int xc2028_dvb_release(struct dvb_frontend *fe)
+static void xc2028_dvb_release(struct dvb_frontend *fe)
 {
 	struct xc2028_data *priv = fe->tuner_priv;
 
@@ -1344,8 +1344,6 @@ static int xc2028_dvb_release(struct dvb_frontend *fe)
 	mutex_unlock(&xc2028_list_mutex);
 
 	fe->tuner_priv = NULL;
-
-	return 0;
 }
 
 static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
index d95c7e0..7ba286c 100644
--- a/drivers/media/tuners/xc4000.c
+++ b/drivers/media/tuners/xc4000.c
@@ -1627,7 +1627,7 @@ static int xc4000_init(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int xc4000_release(struct dvb_frontend *fe)
+static void xc4000_release(struct dvb_frontend *fe)
 {
 	struct xc4000_priv *priv = fe->tuner_priv;
 
@@ -1641,8 +1641,6 @@ static int xc4000_release(struct dvb_frontend *fe)
 	mutex_unlock(&xc4000_list_mutex);
 
 	fe->tuner_priv = NULL;
-
-	return 0;
 }
 
 static const struct dvb_tuner_ops xc4000_tuner_ops = {
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index e6e5e90..796e763 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -1326,7 +1326,7 @@ static int xc5000_init(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int xc5000_release(struct dvb_frontend *fe)
+static void xc5000_release(struct dvb_frontend *fe)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
 
@@ -1346,8 +1346,6 @@ static int xc5000_release(struct dvb_frontend *fe)
 	mutex_unlock(&xc5000_list_mutex);
 
 	fe->tuner_priv = NULL;
-
-	return 0;
 }
 
 static int xc5000_set_config(struct dvb_frontend *fe, void *priv_cfg)
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
index f141dcc..f84bef6 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
@@ -455,13 +455,12 @@ static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe,
 	return 0;
 }
 
-static int mxl111sf_tuner_release(struct dvb_frontend *fe)
+static void mxl111sf_tuner_release(struct dvb_frontend *fe)
 {
 	struct mxl111sf_tuner_state *state = fe->tuner_priv;
 	mxl_dbg("()");
 	kfree(state);
 	fe->tuner_priv = NULL;
-	return 0;
 }
 
 /* ------------------------------------------------------------------------- */

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 07/12] [media] dvb_frontend: merge the two dvb_frontend_detach() versions
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
                   ` (4 preceding siblings ...)
  2016-08-09 21:32 ` [PATCH 06/12] [media] dvb_frontend: tuner_ops.release returns void Max Kellermann
@ 2016-08-09 21:32 ` Max Kellermann
  2016-08-09 21:32 ` [PATCH 08/12] [media] dvb_frontend: add "detach" callback Max Kellermann
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

This code duplication is confusing and error prone.  Let's merge them
by moving the release/dvb_detach call into one function with one
#ifdef.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/dvb-core/dvb_frontend.c |   42 +++++++++------------------------
 1 file changed, 12 insertions(+), 30 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index fea635b..1177414 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -2754,40 +2754,22 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
 }
 EXPORT_SYMBOL(dvb_unregister_frontend);
 
-#ifdef CONFIG_MEDIA_ATTACH
-void dvb_frontend_detach(struct dvb_frontend* fe)
+static void dvb_frontend_invoke_release(struct dvb_frontend *fe,
+					void (*release)(struct dvb_frontend *fe))
 {
-	void *ptr;
-
-	if (fe->ops.release_sec) {
-		fe->ops.release_sec(fe);
-		dvb_detach(fe->ops.release_sec);
-	}
-	if (fe->ops.tuner_ops.release) {
-		fe->ops.tuner_ops.release(fe);
-		dvb_detach(fe->ops.tuner_ops.release);
-	}
-	if (fe->ops.analog_ops.release) {
-		fe->ops.analog_ops.release(fe);
-		dvb_detach(fe->ops.analog_ops.release);
-	}
-	ptr = (void*)fe->ops.release;
-	if (ptr) {
-		fe->ops.release(fe);
-		dvb_detach(ptr);
+	if (release) {
+		release(fe);
+#ifdef CONFIG_MEDIA_ATTACH
+		dvb_detach(release);
+#endif
 	}
 }
-#else
+
 void dvb_frontend_detach(struct dvb_frontend* fe)
 {
-	if (fe->ops.release_sec)
-		fe->ops.release_sec(fe);
-	if (fe->ops.tuner_ops.release)
-		fe->ops.tuner_ops.release(fe);
-	if (fe->ops.analog_ops.release)
-		fe->ops.analog_ops.release(fe);
-	if (fe->ops.release)
-		fe->ops.release(fe);
+	dvb_frontend_invoke_release(fe, fe->ops.release_sec);
+	dvb_frontend_invoke_release(fe, fe->ops.tuner_ops.release);
+	dvb_frontend_invoke_release(fe, fe->ops.analog_ops.release);
+	dvb_frontend_invoke_release(fe, fe->ops.release);
 }
-#endif
 EXPORT_SYMBOL(dvb_frontend_detach);

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 08/12] [media] dvb_frontend: add "detach" callback
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
                   ` (5 preceding siblings ...)
  2016-08-09 21:32 ` [PATCH 07/12] [media] dvb_frontend: merge the two dvb_frontend_detach() versions Max Kellermann
@ 2016-08-09 21:32 ` Max Kellermann
  2016-08-09 21:32 ` [PATCH 09/12] [media] stb0899: move code to " Max Kellermann
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

Prepare for making "release" asynchronous (via kref).  Some operations
may need to be run synchronously in dvb_frontend_detach(), and that's
why we need a "detach" callback.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/dvb-core/dvb_frontend.c |    1 +
 drivers/media/dvb-core/dvb_frontend.h |    7 ++++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 1177414..5bbe389 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -2770,6 +2770,7 @@ void dvb_frontend_detach(struct dvb_frontend* fe)
 	dvb_frontend_invoke_release(fe, fe->ops.release_sec);
 	dvb_frontend_invoke_release(fe, fe->ops.tuner_ops.release);
 	dvb_frontend_invoke_release(fe, fe->ops.analog_ops.release);
+	dvb_frontend_invoke_release(fe, fe->ops.detach);
 	dvb_frontend_invoke_release(fe, fe->ops.release);
 }
 EXPORT_SYMBOL(dvb_frontend_detach);
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 5bfb16b..d535571 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -330,7 +330,11 @@ struct dtv_frontend_properties;
  *
  * @info:		embedded struct dvb_tuner_info with tuner properties
  * @delsys:		Delivery systems supported by the frontend
- * @release:		callback function called when frontend is dettached.
+ * @detach:		callback function called when frontend is detached.
+ *			drivers should clean up, but not yet free the struct
+ *			dvb_frontend allocation.
+ * @release:		callback function called when frontend is ready to be
+ *			freed.
  *			drivers should free any allocated memory.
  * @release_sec:	callback function requesting that the Satelite Equipment
  *			Control (SEC) driver to release and free any memory
@@ -415,6 +419,7 @@ struct dvb_frontend_ops {
 
 	u8 delsys[MAX_DELSYS];
 
+	void (*detach)(struct dvb_frontend *fe);
 	void (*release)(struct dvb_frontend* fe);
 	void (*release_sec)(struct dvb_frontend* fe);
 

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 09/12] [media] stb0899: move code to "detach" callback
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
                   ` (6 preceding siblings ...)
  2016-08-09 21:32 ` [PATCH 08/12] [media] dvb_frontend: add "detach" callback Max Kellermann
@ 2016-08-09 21:32 ` Max Kellermann
  2016-08-09 21:32 ` [PATCH 10/12] [media] dvb_frontend: move kref to struct dvb_frontend Max Kellermann
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

Ensure that STB0899_POSTPROC_GPIO_POWER is set synchronously.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/dvb-frontends/stb0899_drv.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
index 1d34e95..8dc4894 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.c
+++ b/drivers/media/dvb-frontends/stb0899_drv.c
@@ -614,13 +614,19 @@ static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable)
 	return 0;
 }
 
-static void stb0899_release(struct dvb_frontend *fe)
+static void stb0899_detach(struct dvb_frontend *fe)
 {
 	struct stb0899_state *state = fe->demodulator_priv;
 
-	dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend");
 	/* post process event */
 	stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
+}
+
+static void stb0899_release(struct dvb_frontend *fe)
+{
+	struct stb0899_state *state = fe->demodulator_priv;
+
+	dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend");
 	kfree(state);
 }
 
@@ -1603,6 +1609,7 @@ static const struct dvb_frontend_ops stb0899_ops = {
 					  FE_CAN_QPSK
 	},
 
+	.detach				= stb0899_detach,
 	.release			= stb0899_release,
 	.init				= stb0899_init,
 	.sleep				= stb0899_sleep,

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 10/12] [media] dvb_frontend: move kref to struct dvb_frontend
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
                   ` (7 preceding siblings ...)
  2016-08-09 21:32 ` [PATCH 09/12] [media] stb0899: move code to " Max Kellermann
@ 2016-08-09 21:32 ` Max Kellermann
  2016-08-09 21:32 ` [PATCH 11/12] [media] media-entity: clear media_gobj.mdev in _destroy() Max Kellermann
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

This commit amends my old commit fe35637b0a9f ("[media] dvb_frontend:
eliminate blocking wait in dvb_unregister_frontend()"), which added
kref to struct dvb_frontend_private.  It turned out that there are
several use-after-free bugs left, which affect the struct
dvb_frontend.  Protecting it with kref also protects struct
dvb_frontend_private, so we can simply move it.

This is how the use-after-free looks like in KASAN:

    BUG: KASAN: use-after-free in string+0x60/0xb1 at addr ffff880033bd9fc0
    Read of size 1 by task kworker/0:2/617
    CPU: 0 PID: 617 Comm: kworker/0:2 Not tainted 4.8.0-rc1-hosting+ #60
    Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
    Workqueue: usb_hub_wq hub_event
     0000000000000000 ffff880033757218 ffffffff81394e50 ffff880033bd9fd0
     ffff880035c03b00 ffff880033757240 ffffffff811f271d ffff880033bd9fc0
     1ffff1000677b3f8 ffffed000677b3f8 ffff8800337572b8 ffffffff811f2afe
    Call Trace:
     [...]
     [<ffffffff813a2d2f>] vsnprintf+0x39d/0x7e9
     [<ffffffff813993f9>] add_uevent_var+0x10f/0x1dc
     [<ffffffff814fe5ca>] rc_dev_uevent+0x55/0x6f
     [<ffffffff814438f8>] dev_uevent+0x2e1/0x316
     [<ffffffff81399744>] kobject_uevent_env+0x27e/0x701
     [<ffffffff81399bd2>] kobject_uevent+0xb/0xd
     [<ffffffff81443445>] device_del+0x322/0x383
     [<ffffffff81500c0c>] rc_unregister_device+0x98/0xc3
     [<ffffffff81508fb4>] dvb_usb_remote_exit+0x7a/0x90
     [<ffffffff81506157>] dvb_usb_exit+0x1d/0xe5
     [<ffffffff81506e90>] dvb_usb_device_exit+0x69/0x7d
     [<ffffffff8150a181>] pctv452e_usb_disconnect+0x7b/0x80
     [...]
    Object at ffff880033bd9fc0, in cache kmalloc-16 size: 16
    Allocated:
     [...]
    Freed:
    PID = 617
     [...]
     [<ffffffff811f034c>] kfree+0xd9/0x166
     [<ffffffff814fe513>] ir_free_table+0x2f/0x51
     [<ffffffff81500bc1>] rc_unregister_device+0x4d/0xc3
     [<ffffffff81508fb4>] dvb_usb_remote_exit+0x7a/0x90
     [<ffffffff81506157>] dvb_usb_exit+0x1d/0xe5
     [<ffffffff81506e90>] dvb_usb_device_exit+0x69/0x7d
     [<ffffffff8150a181>] pctv452e_usb_disconnect+0x7b/0x80

Another one:

    BUG: KASAN: use-after-free in do_sys_poll+0x336/0x6b8 at addr ffff88003563fcc0
    Read of size 8 by task tuner on fronte/1042
    CPU: 1 PID: 1042 Comm: tuner on fronte Tainted: G    B           4.8.0-rc1-hosting+ #60
    Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
     0000000000000000 ffff88003353f910 ffffffff81394e50 ffff88003563fd80
     ffff880035c03200 ffff88003353f938 ffffffff811f271d ffff88003563fc80
     1ffff10006ac7f98 ffffed0006ac7f98 ffff88003353f9b0 ffffffff811f2afe
    Call Trace:
     [...]
     [<ffffffff812289b3>] do_sys_poll+0x336/0x6b8
     [...]
     [<ffffffff81228ed9>] SyS_poll+0xa9/0x194
     [...]
    Object at ffff88003563fc80, in cache kmalloc-256 size: 256
    Allocated:
     [...]
    Freed:
    PID = 617
     [...]
     [<ffffffff811f034c>] kfree+0xd9/0x166
     [<ffffffff814eb60d>] dvb_unregister_device+0xd6/0xe5
     [<ffffffff814fa4ed>] dvb_unregister_frontend+0x4b/0x66
     [<ffffffff8150810b>] dvb_usb_adapter_frontend_exit+0x69/0xac
     [<ffffffff8150617d>] dvb_usb_exit+0x43/0xe5
     [<ffffffff81506e90>] dvb_usb_device_exit+0x69/0x7d
     [<ffffffff8150a181>] pctv452e_usb_disconnect+0x7b/0x80

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/dvb-core/dvb_frontend.c |   46 ++++++++++++++++++++++-----------
 drivers/media/dvb-core/dvb_frontend.h |    1 +
 2 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 5bbe389..c38143b4 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -99,8 +99,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
 static DEFINE_MUTEX(frontend_mutex);
 
 struct dvb_frontend_private {
-	struct kref refcount;
-
 	/* thread/frontend values */
 	struct dvb_device *dvbdev;
 	struct dvb_frontend_parameters parameters_out;
@@ -138,21 +136,30 @@ struct dvb_frontend_private {
 #endif
 };
 
-static void dvb_frontend_private_free(struct kref *ref)
+static void dvb_frontend_invoke_release(struct dvb_frontend *fe,
+					void (*release)(struct dvb_frontend *fe));
+
+static void dvb_frontend_free(struct kref *ref)
 {
-	struct dvb_frontend_private *fepriv =
-		container_of(ref, struct dvb_frontend_private, refcount);
+	struct dvb_frontend *fe =
+		container_of(ref, struct dvb_frontend, refcount);
+	struct dvb_frontend_private *fepriv = fe->frontend_priv;
+
+	dvb_free_device(fepriv->dvbdev);
+
+	dvb_frontend_invoke_release(fe, fe->ops.release);
+
 	kfree(fepriv);
 }
 
-static void dvb_frontend_private_put(struct dvb_frontend_private *fepriv)
+static void dvb_frontend_put(struct dvb_frontend *fe)
 {
-	kref_put(&fepriv->refcount, dvb_frontend_private_free);
+	kref_put(&fe->refcount, dvb_frontend_free);
 }
 
-static void dvb_frontend_private_get(struct dvb_frontend_private *fepriv)
+static void dvb_frontend_get(struct dvb_frontend *fe)
 {
-	kref_get(&fepriv->refcount);
+	kref_get(&fe->refcount);
 }
 
 static void dvb_frontend_wakeup(struct dvb_frontend *fe);
@@ -2569,7 +2576,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 		fepriv->events.eventr = fepriv->events.eventw = 0;
 	}
 
-	dvb_frontend_private_get(fepriv);
+	dvb_frontend_get(fe);
 
 	if (adapter->mfe_shared)
 		mutex_unlock (&adapter->mfe_lock);
@@ -2619,7 +2626,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
 			fe->ops.ts_bus_ctrl(fe, 0);
 	}
 
-	dvb_frontend_private_put(fepriv);
+	dvb_frontend_put(fe);
 
 	return ret;
 }
@@ -2709,7 +2716,14 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
 	}
 	fepriv = fe->frontend_priv;
 
-	kref_init(&fepriv->refcount);
+	kref_init(&fe->refcount);
+
+	/*
+	 * After initialization, there need to be two references: one
+	 * for dvb_unregister_frontend(), and another one for
+	 * dvb_frontend_detach().
+	 */
+	dvb_frontend_get(fe);
 
 	sema_init(&fepriv->sem, 1);
 	init_waitqueue_head (&fepriv->wait_queue);
@@ -2744,12 +2758,12 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
 	dev_dbg(fe->dvb->device, "%s:\n", __func__);
 
 	mutex_lock(&frontend_mutex);
-	dvb_frontend_stop (fe);
-	dvb_unregister_device (fepriv->dvbdev);
+	dvb_frontend_stop(fe);
+	dvb_remove_device(fepriv->dvbdev);
 
 	/* fe is invalid now */
 	mutex_unlock(&frontend_mutex);
-	dvb_frontend_private_put(fepriv);
+	dvb_frontend_put(fe);
 	return 0;
 }
 EXPORT_SYMBOL(dvb_unregister_frontend);
@@ -2771,6 +2785,6 @@ void dvb_frontend_detach(struct dvb_frontend* fe)
 	dvb_frontend_invoke_release(fe, fe->ops.tuner_ops.release);
 	dvb_frontend_invoke_release(fe, fe->ops.analog_ops.release);
 	dvb_frontend_invoke_release(fe, fe->ops.detach);
-	dvb_frontend_invoke_release(fe, fe->ops.release);
+	dvb_frontend_put(fe);
 }
 EXPORT_SYMBOL(dvb_frontend_detach);
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index d535571..f21b255 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -667,6 +667,7 @@ struct dtv_frontend_properties {
  */
 
 struct dvb_frontend {
+	struct kref refcount;
 	struct dvb_frontend_ops ops;
 	struct dvb_adapter *dvb;
 	void *demodulator_priv;

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 11/12] [media] media-entity: clear media_gobj.mdev in _destroy()
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
                   ` (8 preceding siblings ...)
  2016-08-09 21:32 ` [PATCH 10/12] [media] dvb_frontend: move kref to struct dvb_frontend Max Kellermann
@ 2016-08-09 21:32 ` Max Kellermann
  2016-08-09 21:33 ` [PATCH 12/12] drivers/media/media-device: fix double free bug in _unregister() Max Kellermann
  2016-11-14 23:41 ` [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Shuah Khan
  11 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:32 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

media_gobj_destroy() may be called twice on one instance - once by
media_device_unregister() and again by dvb_media_device_free().  The
function media_remove_intf_links() establishes and documents the
convention that mdev==NULL means that the object is not registered,
but nobody ever NULLs this variable.  So this patch really implements
this behavior, and adds another mdev==NULL check to
media_gobj_destroy() to protect against double removal.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/media-entity.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index d8a2299..9526338 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -203,10 +203,16 @@ void media_gobj_destroy(struct media_gobj *gobj)
 {
 	dev_dbg_obj(__func__, gobj);
 
+	/* Do nothing if the object is not linked. */
+	if (gobj->mdev == NULL)
+		return;
+
 	gobj->mdev->topology_version++;
 
 	/* Remove the object from mdev list */
 	list_del(&gobj->list);
+
+	gobj->mdev = NULL;
 }
 
 int media_entity_pads_init(struct media_entity *entity, u16 num_pads,

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 12/12] drivers/media/media-device: fix double free bug in _unregister()
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
                   ` (9 preceding siblings ...)
  2016-08-09 21:32 ` [PATCH 11/12] [media] media-entity: clear media_gobj.mdev in _destroy() Max Kellermann
@ 2016-08-09 21:33 ` Max Kellermann
  2016-11-14 23:41 ` [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Shuah Khan
  11 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-09 21:33 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab; +Cc: linux-kernel

While removing all interfaces in media_device_unregister(), all
media_interface pointers are freed.  This is illegal and results in
double kfree() if any media_interface is still linked at this point;
maybe because a userspace process still has a file handle.  Once the
process closes the file handle, dvb_media_device_free() gets called,
which frees the dvb_device.intf_devnode again.

This patch removes the unnecessary kfree() call, and documents who's
responsible for really freeing it.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
 drivers/media/media-device.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 1795abe..113a4d1 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -803,9 +803,13 @@ void media_device_unregister(struct media_device *mdev)
 	/* Remove all interfaces from the media device */
 	list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces,
 				 graph_obj.list) {
+		/*
+		 * Unlink the interface, but don't free it here; the
+		 * module which created it is responsible for freeing
+		 * it
+		 */
 		__media_remove_intf_links(intf);
 		media_gobj_destroy(&intf->graph_obj);
-		kfree(intf);
 	}
 
 	mutex_unlock(&mdev->graph_mutex);

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 05/12] [media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations
  2016-08-09 21:32 ` [PATCH 05/12] [media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations Max Kellermann
@ 2016-08-09 23:01   ` kbuild test robot
  2016-08-10 11:56     ` Max Kellermann
  2016-08-09 23:19   ` kbuild test robot
  1 sibling, 1 reply; 16+ messages in thread
From: kbuild test robot @ 2016-08-09 23:01 UTC (permalink / raw)
  To: Max Kellermann; +Cc: kbuild-all, linux-media, shuahkh, mchehab, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1229 bytes --]

Hi Max,

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.8-rc1 next-20160809]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Max-Kellermann/rc-main-clear-rc_map-name-in-ir_free_table/20160810-054811
base:   git://linuxtv.org/media_tree.git master
config: i386-randconfig-n0-201632 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

>> drivers/built-in.o:(.rodata+0x55f58): undefined reference to `dvb_tuner_simple_release'
   drivers/built-in.o:(.rodata+0x56038): undefined reference to `dvb_tuner_simple_release'
   drivers/built-in.o:(.rodata+0x56618): undefined reference to `dvb_tuner_simple_release'
   drivers/built-in.o:(.rodata+0x566f8): undefined reference to `dvb_tuner_simple_release'
   drivers/built-in.o:(.rodata+0x57998): undefined reference to `dvb_tuner_simple_release'

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 23557 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 05/12] [media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations
  2016-08-09 21:32 ` [PATCH 05/12] [media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations Max Kellermann
  2016-08-09 23:01   ` kbuild test robot
@ 2016-08-09 23:19   ` kbuild test robot
  1 sibling, 0 replies; 16+ messages in thread
From: kbuild test robot @ 2016-08-09 23:19 UTC (permalink / raw)
  To: Max Kellermann; +Cc: kbuild-all, linux-media, shuahkh, mchehab, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1184 bytes --]

Hi Max,

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.8-rc1 next-20160809]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Max-Kellermann/rc-main-clear-rc_map-name-in-ir_free_table/20160810-054811
base:   git://linuxtv.org/media_tree.git master
config: i386-randconfig-s0-201632 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

>> ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/tea5767.ko] undefined!
>> ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/tea5761.ko] undefined!
>> ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/tda827x.ko] undefined!
>> ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/mt20xx.ko] undefined!
>> ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/mc44s803.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 34064 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 05/12] [media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations
  2016-08-09 23:01   ` kbuild test robot
@ 2016-08-10 11:56     ` Max Kellermann
  0 siblings, 0 replies; 16+ messages in thread
From: Max Kellermann @ 2016-08-10 11:56 UTC (permalink / raw)
  To: linux-media, shuahkh, mchehab, linux-kernel

On 2016/08/10 01:01, kbuild test robot <lkp@intel.com> wrote:
> url:    https://github.com/0day-ci/linux/commits/Max-Kellermann/rc-main-clear-rc_map-name-in-ir_free_table/20160810-054811
> base:   git://linuxtv.org/media_tree.git master
> config: i386-randconfig-n0-201632 (attached as .config)
> compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=i386 
> 
> All errors (new ones prefixed by >>):
> 
> >> drivers/built-in.o:(.rodata+0x55f58): undefined reference to `dvb_tuner_simple_release'
>    drivers/built-in.o:(.rodata+0x56038): undefined reference to `dvb_tuner_simple_release'
>    drivers/built-in.o:(.rodata+0x56618): undefined reference to `dvb_tuner_simple_release'
>    drivers/built-in.o:(.rodata+0x566f8): undefined reference to `dvb_tuner_simple_release'
>    drivers/built-in.o:(.rodata+0x57998): undefined reference to `dvb_tuner_simple_release'

This configuration breaks because there is no dependency from those
tuners to dvb_frontend.c (where dvb_tuner_simple_release).  However,
without dvb_frontend.c, there is no user of such a tuner, and this
configuration doesn't make sense.

Before I spend time on fixing this, I'd like to know if this patch has
a chance to be merged, or if you generally reject my idea of folding
duplicate code.

Two solutions come to my mind:

1.) add a dependency

2.) move dvb_tuner_simple_release() to a new library, which all tuner
    implementations depend on (which may some day have more common
    tuner code)

Opinions?

Max

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table()
  2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
                   ` (10 preceding siblings ...)
  2016-08-09 21:33 ` [PATCH 12/12] drivers/media/media-device: fix double free bug in _unregister() Max Kellermann
@ 2016-11-14 23:41 ` Shuah Khan
  11 siblings, 0 replies; 16+ messages in thread
From: Shuah Khan @ 2016-11-14 23:41 UTC (permalink / raw)
  To: Max Kellermann, linux-media, mchehab; +Cc: linux-kernel, shuah Khan

On 08/09/2016 03:32 PM, Max Kellermann wrote:
> rc_unregister_device() will first call ir_free_table(), and later
> device_del(); however, the latter causes a call to rc_dev_uevent(),
> which prints rc_map.name, which at this point has already bee freed.
> 
> This fixes a use-after-free bug found with KASAN.
> 
> Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
> ---
>  drivers/media/rc/rc-main.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
> index 8e7f292..1e5a520 100644
> --- a/drivers/media/rc/rc-main.c
> +++ b/drivers/media/rc/rc-main.c
> @@ -159,6 +159,7 @@ static void ir_free_table(struct rc_map *rc_map)
>  {
>  	rc_map->size = 0;
>  	kfree(rc_map->name);
> +	rc_map->name = NULL;
>  	kfree(rc_map->scan);
>  	rc_map->scan = NULL;
>  }
> 

Hi Mauro,

Could you please get this fix into 4.9. I am seeing the following when I do
rmmod on au0828

[  179.010878] ==================================================================
[  179.010895] BUG: KASAN: use-after-free in string+0x170/0x1f0 at addr ffff8801bd513000
[  179.010900] Read of size 1 by task rmmod/1831
[  179.010908] CPU: 1 PID: 1831 Comm: rmmod Tainted: G        W       4.9.0-rc5 #5
[  179.010910] Hardware name: Hewlett-Packard HP ProBook 6475b/180F, BIOS 68TTU Ver. F.04 08/03/2012
[  179.010914]  ffff8801aea2f680 ffffffff81b37ad3 ffff8801fa403b80 ffff8801bd513000
[  179.010922]  ffff8801aea2f6a8 ffffffff8156c301 ffff8801aea2f738 ffff8801bd513000
[  179.010930]  ffff8801fa403b80 ffff8801aea2f728 ffffffff8156c59a ffff8801aea2f770
[  179.010937] Call Trace:
[  179.010944]  [<ffffffff81b37ad3>] dump_stack+0x67/0x94
[  179.010950]  [<ffffffff8156c301>] kasan_object_err+0x21/0x70
[  179.010954]  [<ffffffff8156c59a>] kasan_report_error+0x1fa/0x4d0
[  179.010968]  [<ffffffffa116f05f>] ? au0828_exit+0x10/0x21 [au0828]
[  179.010973]  [<ffffffff8156c8b3>] __asan_report_load1_noabort+0x43/0x50
[  179.010978]  [<ffffffff81b58b20>] ? string+0x170/0x1f0
[  179.010982]  [<ffffffff81b58b20>] string+0x170/0x1f0
[  179.010987]  [<ffffffff81b621c4>] vsnprintf+0x374/0x1c50
[  179.010992]  [<ffffffff81b61e50>] ? pointer+0xa80/0xa80
[  179.010996]  [<ffffffff8156b676>] ? save_stack+0x46/0xd0
[  179.011001]  [<ffffffff81566faa>] ? __kmalloc+0x14a/0x2a0
[  179.011006]  [<ffffffff81b3d70a>] ? kobject_get_path+0x9a/0x200
[  179.011010]  [<ffffffff81b408c2>] ? kobject_uevent_env+0x282/0xca0
[  179.011014]  [<ffffffff81b412eb>] ? kobject_uevent+0xb/0x10
[  179.011020]  [<ffffffff81f10104>] ? device_del+0x434/0x6d0
[  179.011029]  [<ffffffffa0fea717>] ? rc_unregister_device+0x177/0x240 [rc_core]
[  179.011037]  [<ffffffffa116eeb0>] ? au0828_rc_unregister+0x60/0xb0 [au0828]

The problem is fixed with this patch on Linux 4.9-rc4

thanks,
-- Shuah

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2016-11-14 23:41 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-09 21:32 [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Max Kellermann
2016-08-09 21:32 ` [PATCH 02/12] [media] dvbdev: split dvb_unregister_device() Max Kellermann
2016-08-09 21:32 ` [PATCH 03/12] [media] dvb-core/en50221: use dvb_remove_device() Max Kellermann
2016-08-09 21:32 ` [PATCH 04/12] [media] dvb: make DVB frontend *_ops instances "const" Max Kellermann
2016-08-09 21:32 ` [PATCH 05/12] [media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations Max Kellermann
2016-08-09 23:01   ` kbuild test robot
2016-08-10 11:56     ` Max Kellermann
2016-08-09 23:19   ` kbuild test robot
2016-08-09 21:32 ` [PATCH 06/12] [media] dvb_frontend: tuner_ops.release returns void Max Kellermann
2016-08-09 21:32 ` [PATCH 07/12] [media] dvb_frontend: merge the two dvb_frontend_detach() versions Max Kellermann
2016-08-09 21:32 ` [PATCH 08/12] [media] dvb_frontend: add "detach" callback Max Kellermann
2016-08-09 21:32 ` [PATCH 09/12] [media] stb0899: move code to " Max Kellermann
2016-08-09 21:32 ` [PATCH 10/12] [media] dvb_frontend: move kref to struct dvb_frontend Max Kellermann
2016-08-09 21:32 ` [PATCH 11/12] [media] media-entity: clear media_gobj.mdev in _destroy() Max Kellermann
2016-08-09 21:33 ` [PATCH 12/12] drivers/media/media-device: fix double free bug in _unregister() Max Kellermann
2016-11-14 23:41 ` [PATCH 01/12] [media] rc-main: clear rc_map.name in ir_free_table() Shuah Khan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).