diff options
Diffstat (limited to 'drivers/media/dvb-core/dvb_frontend.c')
-rw-r--r-- | drivers/media/dvb-core/dvb_frontend.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 2fcba1616168..9139d01ba7ed 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c | |||
@@ -141,22 +141,39 @@ struct dvb_frontend_private { | |||
141 | static void dvb_frontend_invoke_release(struct dvb_frontend *fe, | 141 | static void dvb_frontend_invoke_release(struct dvb_frontend *fe, |
142 | void (*release)(struct dvb_frontend *fe)); | 142 | void (*release)(struct dvb_frontend *fe)); |
143 | 143 | ||
144 | static void dvb_frontend_free(struct kref *ref) | 144 | static void __dvb_frontend_free(struct dvb_frontend *fe) |
145 | { | 145 | { |
146 | struct dvb_frontend *fe = | ||
147 | container_of(ref, struct dvb_frontend, refcount); | ||
148 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 146 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
149 | 147 | ||
148 | if (!fepriv) | ||
149 | return; | ||
150 | |||
150 | dvb_free_device(fepriv->dvbdev); | 151 | dvb_free_device(fepriv->dvbdev); |
151 | 152 | ||
152 | dvb_frontend_invoke_release(fe, fe->ops.release); | 153 | dvb_frontend_invoke_release(fe, fe->ops.release); |
153 | 154 | ||
154 | kfree(fepriv); | 155 | kfree(fepriv); |
156 | fe->frontend_priv = NULL; | ||
157 | } | ||
158 | |||
159 | static void dvb_frontend_free(struct kref *ref) | ||
160 | { | ||
161 | struct dvb_frontend *fe = | ||
162 | container_of(ref, struct dvb_frontend, refcount); | ||
163 | |||
164 | __dvb_frontend_free(fe); | ||
155 | } | 165 | } |
156 | 166 | ||
157 | static void dvb_frontend_put(struct dvb_frontend *fe) | 167 | static void dvb_frontend_put(struct dvb_frontend *fe) |
158 | { | 168 | { |
159 | kref_put(&fe->refcount, dvb_frontend_free); | 169 | /* |
170 | * Check if the frontend was registered, as otherwise | ||
171 | * kref was not initialized yet. | ||
172 | */ | ||
173 | if (fe->frontend_priv) | ||
174 | kref_put(&fe->refcount, dvb_frontend_free); | ||
175 | else | ||
176 | __dvb_frontend_free(fe); | ||
160 | } | 177 | } |
161 | 178 | ||
162 | static void dvb_frontend_get(struct dvb_frontend *fe) | 179 | static void dvb_frontend_get(struct dvb_frontend *fe) |