aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire/fireworks/fireworks.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/firewire/fireworks/fireworks.c')
-rw-r--r--sound/firewire/fireworks/fireworks.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
index 3e2ed8e82cbc..2682e7e3e5c9 100644
--- a/sound/firewire/fireworks/fireworks.c
+++ b/sound/firewire/fireworks/fireworks.c
@@ -173,11 +173,23 @@ end:
173 return err; 173 return err;
174} 174}
175 175
176/*
177 * This module releases the FireWire unit data after all ALSA character devices
178 * are released by applications. This is for releasing stream data or finishing
179 * transactions safely. Thus at returning from .remove(), this module still keep
180 * references for the unit.
181 */
176static void 182static void
177efw_card_free(struct snd_card *card) 183efw_card_free(struct snd_card *card)
178{ 184{
179 struct snd_efw *efw = card->private_data; 185 struct snd_efw *efw = card->private_data;
180 186
187 snd_efw_stream_destroy_duplex(efw);
188 snd_efw_transaction_remove_instance(efw);
189 fw_unit_put(efw->unit);
190
191 kfree(efw->resp_buf);
192
181 if (efw->card_index >= 0) { 193 if (efw->card_index >= 0) {
182 mutex_lock(&devices_mutex); 194 mutex_lock(&devices_mutex);
183 clear_bit(efw->card_index, devices_used); 195 clear_bit(efw->card_index, devices_used);
@@ -185,7 +197,6 @@ efw_card_free(struct snd_card *card)
185 } 197 }
186 198
187 mutex_destroy(&efw->mutex); 199 mutex_destroy(&efw->mutex);
188 kfree(efw->resp_buf);
189} 200}
190 201
191static int 202static int
@@ -218,7 +229,7 @@ efw_probe(struct fw_unit *unit,
218 card->private_free = efw_card_free; 229 card->private_free = efw_card_free;
219 230
220 efw->card = card; 231 efw->card = card;
221 efw->unit = unit; 232 efw->unit = fw_unit_get(unit);
222 mutex_init(&efw->mutex); 233 mutex_init(&efw->mutex);
223 spin_lock_init(&efw->lock); 234 spin_lock_init(&efw->lock);
224 init_waitqueue_head(&efw->hwdep_wait); 235 init_waitqueue_head(&efw->hwdep_wait);
@@ -289,10 +300,7 @@ static void efw_remove(struct fw_unit *unit)
289{ 300{
290 struct snd_efw *efw = dev_get_drvdata(&unit->device); 301 struct snd_efw *efw = dev_get_drvdata(&unit->device);
291 302
292 snd_efw_stream_destroy_duplex(efw); 303 /* No need to wait for releasing card object in this context. */
293 snd_efw_transaction_remove_instance(efw);
294
295 snd_card_disconnect(efw->card);
296 snd_card_free_when_closed(efw->card); 304 snd_card_free_when_closed(efw->card);
297} 305}
298 306