summaryrefslogtreecommitdiff
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.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
index 3e2ed8e82cbc..1e33394d8a93 100644
--- a/sound/firewire/fireworks/fireworks.c
+++ b/sound/firewire/fireworks/fireworks.c
@@ -173,11 +173,19 @@ end:
return err;
}
+/*
+ * This module releases the FireWire unit data after all ALSA character devices
+ * are released by applications. This is for releasing stream data or finishing
+ * transactions safely. Thus at returning from .remove(), this module still keep
+ * references for the unit.
+ */
static void
efw_card_free(struct snd_card *card)
{
struct snd_efw *efw = card->private_data;
+ fw_unit_put(efw->unit);
+
if (efw->card_index >= 0) {
mutex_lock(&devices_mutex);
clear_bit(efw->card_index, devices_used);
@@ -218,7 +226,7 @@ efw_probe(struct fw_unit *unit,
card->private_free = efw_card_free;
efw->card = card;
- efw->unit = unit;
+ efw->unit = fw_unit_get(unit);
mutex_init(&efw->mutex);
spin_lock_init(&efw->lock);
init_waitqueue_head(&efw->hwdep_wait);
@@ -293,6 +301,8 @@ static void efw_remove(struct fw_unit *unit)
snd_efw_transaction_remove_instance(efw);
snd_card_disconnect(efw->card);
+
+ /* No need to wait for releasing card object in this context. */
snd_card_free_when_closed(efw->card);
}