[media] dib7000: export just one symbol
Exporting multiple symbols don't work as it causes compilation
breakages, due to the way dvb_attach() works.
This were reported several times, like:
drivers/built-in.o: In function `cxusb_dualdig4_rev2_tuner_attach':
>> cxusb.c:(.text+0x27d4b5): undefined reference to `dib7000p_get_i2c_master'
drivers/built-in.o: In function `dib7070_set_param_override':
cxusb.c:(.text+0x27d5a5): undefined reference to `dib0070_wbd_offset'
>> cxusb.c:(.text+0x27d5be): undefined reference to `dib7000p_set_wbd_ref'
drivers/built-in.o: In function `dib7070_tuner_reset':
>> cxusb.c:(.text+0x27d5f9): undefined reference to `dib7000p_set_gpio'
drivers/built-in.o: In function `cxusb_dualdig4_rev2_frontend_attach':
>> cxusb.c:(.text+0x27df5c): undefined reference to `dib7000p_i2c_enumeration'
In this specific report:
CONFIG_DVB_USB_CXUSB=y
CONFIG_DVB_DIB7000P=m
But the same type of bug can happen if:
CONFIG_DVB_DIB7000P=m
and one of the bridge drivers is compiled builtin (cxusb, cx23885-dvb
and/or dib0700).
As a bonus, dib7000p won't be loaded anymore if the device uses
a different frontend, reducing the memory footprint.
Tested with Hauppauge Nova-TD (2 frontends).
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index e81a2fd..6acde5e 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -1070,8 +1070,15 @@
.hostbus_diversity = 1,
};
+struct dib0700_adapter_state {
+ int (*set_param_save)(struct dvb_frontend *);
+ struct dib7000p_ops dib7000p_ops;
+};
+
static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
{
+ struct dib0700_adapter_state *state = adap->priv;
+
if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
err("set interface failed");
@@ -1079,14 +1086,17 @@
cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
- &cxusb_dualdig4_rev2_config) < 0) {
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &cxusb_dualdig4_rev2_config) < 0) {
printk(KERN_WARNING "Unable to enumerate dib7000p\n");
return -ENODEV;
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_init, &adap->dev->i2c_adap, 0x80,
- &cxusb_dualdig4_rev2_config);
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80,
+ &cxusb_dualdig4_rev2_config);
if (adap->fe_adap[0].fe == NULL)
return -EIO;
@@ -1095,7 +1105,10 @@
static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
{
- return dib7000p_set_gpio(fe, 8, 0, !onoff);
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff);
}
static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
@@ -1110,10 +1123,6 @@
.clock_khz = 12000,
};
-struct dib0700_adapter_state {
- int (*set_param_save) (struct dvb_frontend *);
-};
-
static int dib7070_set_param_override(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
@@ -1128,7 +1137,7 @@
case BAND_UHF: offset = 550; break;
}
- dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+ state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
return state->set_param_save(fe);
}
@@ -1136,8 +1145,14 @@
static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c =
- dib7000p_get_i2c_master(adap->fe_adap[0].fe,
+ struct i2c_adapter *tun_i2c;
+
+ /*
+ * No need to call dvb7000p_attach here, as it was called
+ * already, as frontend_attach method is called first, and
+ * tuner_attach is only called on sucess.
+ */
+ tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe,
DIBX000_I2C_INTERFACE_TUNER, 1);
if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,