V4L/DVB (4432): Fix Circular dependencies

Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 52b6fb2..9f72b70 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1715,6 +1715,15 @@
 static void dst_release(struct dvb_frontend *fe)
 {
 	struct dst_state *state = fe->demodulator_priv;
+	if (state->dst_ca) {
+		dvb_unregister_device(state->dst_ca);
+#ifdef CONFIG_DVB_CORE_ATTACH
+		symbol_put(dst_ca_attach);
+#endif
+	}
+#ifdef CONFIG_DVB_CORE_ATTACH
+	symbol_put(dst_attach);
+#endif
 	kfree(state);
 }
 
@@ -1752,11 +1761,6 @@
 	}
 	state->frontend.demodulator_priv = state;
 
-	/*	Attach other DST peripherals if any		*/
-	/*	Conditional Access device			*/
-	if (state->dst_hw_cap & DST_TYPE_HAS_CA)
-		dst_ca_attach(state, dvb_adapter);
-
 	return state;				/*	Manu (DST is a card not a frontend)	*/
 }
 
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index df0f68f..240ad08 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -699,11 +699,17 @@
 	.fops = &dst_ca_fops
 };
 
-void dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
+struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
 {
 	struct dvb_device *dvbdev;
+
 	dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
-	dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA);
+	if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) {
+		dst->dst_ca = dvbdev;
+		return dst->dst_ca;
+	}
+
+	return NULL;
 }
 
 EXPORT_SYMBOL(dst_ca_attach);
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 66bc082..3bf084f 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -140,6 +140,7 @@
 	char *tuner_name;
 	struct mutex dst_mutex;
 	u8 fw_name[8];
+	struct dvb_device *dst_ca;
 };
 
 struct tuner_types {
@@ -178,7 +179,7 @@
 int read_dst(struct dst_state *state, u8 * ret, u8 len);
 u8 dst_check_sum(u8 * buf, u32 len);
 struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter);
-void dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
+struct dvb_device *dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
 int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay);
 
 int dst_command(struct dst_state* state, u8 * data, u8 len);
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index a19991f..fb6c4cc 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -669,13 +669,17 @@
 		state->config = &dst_config;
 		state->i2c = card->i2c_adapter;
 		state->bt = card->bt;
-
+		state->dst_ca = NULL;
 		/*	DST is not a frontend, attaching the ASIC	*/
 		if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) {
 			printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__);
 			break;
 		}
+		/*	Attach other DST peripherals if any		*/
+		/*	Conditional Access device			*/
 		card->fe = &state->frontend;
+		if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+			dvb_attach(dst_ca_attach, state, &card->dvb_adapter);
 		break;
 
 	case BTTV_BOARD_PINNACLESAT: