@@ -123,6 +123,7 @@ struct dvb_ca_slot {
123
123
124
124
/* Private CA-interface information */
125
125
struct dvb_ca_private {
126
+ struct kref refcount ;
126
127
127
128
/* pointer back to the public data structure */
128
129
struct dvb_ca_en50221 * pub ;
@@ -173,6 +174,22 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca)
173
174
kfree (ca );
174
175
}
175
176
177
+ static void dvb_ca_private_release (struct kref * ref )
178
+ {
179
+ struct dvb_ca_private * ca = container_of (ref , struct dvb_ca_private , refcount );
180
+ dvb_ca_private_free (ca );
181
+ }
182
+
183
+ static void dvb_ca_private_get (struct dvb_ca_private * ca )
184
+ {
185
+ kref_get (& ca -> refcount );
186
+ }
187
+
188
+ static void dvb_ca_private_put (struct dvb_ca_private * ca )
189
+ {
190
+ kref_put (& ca -> refcount , dvb_ca_private_release );
191
+ }
192
+
176
193
static void dvb_ca_en50221_thread_wakeup (struct dvb_ca_private * ca );
177
194
static int dvb_ca_en50221_read_data (struct dvb_ca_private * ca , int slot , u8 * ebuf , int ecount );
178
195
static int dvb_ca_en50221_write_data (struct dvb_ca_private * ca , int slot , u8 * ebuf , int ecount );
@@ -1570,6 +1587,8 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
1570
1587
dvb_ca_en50221_thread_update_delay (ca );
1571
1588
dvb_ca_en50221_thread_wakeup (ca );
1572
1589
1590
+ dvb_ca_private_get (ca );
1591
+
1573
1592
return 0 ;
1574
1593
}
1575
1594
@@ -1598,6 +1617,8 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
1598
1617
1599
1618
module_put (ca -> pub -> owner );
1600
1619
1620
+ dvb_ca_private_put (ca );
1621
+
1601
1622
return err ;
1602
1623
}
1603
1624
@@ -1693,6 +1714,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
1693
1714
ret = - ENOMEM ;
1694
1715
goto exit ;
1695
1716
}
1717
+ kref_init (& ca -> refcount );
1696
1718
ca -> pub = pubca ;
1697
1719
ca -> flags = flags ;
1698
1720
ca -> slot_count = slot_count ;
@@ -1772,6 +1794,6 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
1772
1794
for (i = 0 ; i < ca -> slot_count ; i ++ ) {
1773
1795
dvb_ca_en50221_slot_shutdown (ca , i );
1774
1796
}
1775
- dvb_ca_private_free (ca );
1797
+ dvb_ca_private_put (ca );
1776
1798
pubca -> private = NULL ;
1777
1799
}
0 commit comments