@@ -104,8 +104,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
104
104
static DEFINE_MUTEX (frontend_mutex );
105
105
106
106
struct dvb_frontend_private {
107
- struct kref refcount ;
108
-
109
107
/* thread/frontend values */
110
108
struct dvb_device * dvbdev ;
111
109
struct dvb_frontend_parameters parameters_out ;
@@ -143,21 +141,30 @@ struct dvb_frontend_private {
143
141
#endif
144
142
};
145
143
146
- static void dvb_frontend_private_free (struct kref * ref )
144
+ static void dvb_frontend_invoke_release (struct dvb_frontend * fe ,
145
+ void (* release )(struct dvb_frontend * fe ));
146
+
147
+ static void dvb_frontend_free (struct kref * ref )
147
148
{
148
- struct dvb_frontend_private * fepriv =
149
- container_of (ref , struct dvb_frontend_private , refcount );
149
+ struct dvb_frontend * fe =
150
+ container_of (ref , struct dvb_frontend , refcount );
151
+ struct dvb_frontend_private * fepriv = fe -> frontend_priv ;
152
+
153
+ dvb_free_device (fepriv -> dvbdev );
154
+
155
+ dvb_frontend_invoke_release (fe , fe -> ops .release );
156
+
150
157
kfree (fepriv );
151
158
}
152
159
153
- static void dvb_frontend_private_put (struct dvb_frontend_private * fepriv )
160
+ static void dvb_frontend_put (struct dvb_frontend * fe )
154
161
{
155
- kref_put (& fepriv -> refcount , dvb_frontend_private_free );
162
+ kref_put (& fe -> refcount , dvb_frontend_free );
156
163
}
157
164
158
- static void dvb_frontend_private_get (struct dvb_frontend_private * fepriv )
165
+ static void dvb_frontend_get (struct dvb_frontend * fe )
159
166
{
160
- kref_get (& fepriv -> refcount );
167
+ kref_get (& fe -> refcount );
161
168
}
162
169
163
170
static void dvb_frontend_wakeup (struct dvb_frontend * fe );
@@ -2555,7 +2562,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
2555
2562
fepriv -> events .eventr = fepriv -> events .eventw = 0 ;
2556
2563
}
2557
2564
2558
- dvb_frontend_private_get ( fepriv );
2565
+ dvb_frontend_get ( fe );
2559
2566
2560
2567
if (adapter -> mfe_shared )
2561
2568
mutex_unlock (& adapter -> mfe_lock );
@@ -2605,7 +2612,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
2605
2612
fe -> ops .ts_bus_ctrl (fe , 0 );
2606
2613
}
2607
2614
2608
- dvb_frontend_private_put ( fepriv );
2615
+ dvb_frontend_put ( fe );
2609
2616
2610
2617
return ret ;
2611
2618
}
@@ -2695,7 +2702,14 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
2695
2702
}
2696
2703
fepriv = fe -> frontend_priv ;
2697
2704
2698
- kref_init (& fepriv -> refcount );
2705
+ kref_init (& fe -> refcount );
2706
+
2707
+ /*
2708
+ * After initialization, there need to be two references: one
2709
+ * for dvb_unregister_frontend(), and another one for
2710
+ * dvb_frontend_detach().
2711
+ */
2712
+ dvb_frontend_get (fe );
2699
2713
2700
2714
sema_init (& fepriv -> sem , 1 );
2701
2715
init_waitqueue_head (& fepriv -> wait_queue );
@@ -2730,12 +2744,12 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
2730
2744
dev_dbg (fe -> dvb -> device , "%s:\n" , __func__ );
2731
2745
2732
2746
mutex_lock (& frontend_mutex );
2733
- dvb_frontend_stop (fe );
2734
- dvb_unregister_device (fepriv -> dvbdev );
2747
+ dvb_frontend_stop (fe );
2748
+ dvb_remove_device (fepriv -> dvbdev );
2735
2749
2736
2750
/* fe is invalid now */
2737
2751
mutex_unlock (& frontend_mutex );
2738
- dvb_frontend_private_put ( fepriv );
2752
+ dvb_frontend_put ( fe );
2739
2753
return 0 ;
2740
2754
}
2741
2755
EXPORT_SYMBOL (dvb_unregister_frontend );
@@ -2757,6 +2771,6 @@ void dvb_frontend_detach(struct dvb_frontend* fe)
2757
2771
dvb_frontend_invoke_release (fe , fe -> ops .tuner_ops .release );
2758
2772
dvb_frontend_invoke_release (fe , fe -> ops .analog_ops .release );
2759
2773
dvb_frontend_invoke_release (fe , fe -> ops .detach );
2760
- dvb_frontend_invoke_release (fe , fe -> ops . release );
2774
+ dvb_frontend_put (fe );
2761
2775
}
2762
2776
EXPORT_SYMBOL (dvb_frontend_detach );
0 commit comments