diff options
author | Dave Airlie <airlied@redhat.com> | 2015-03-09 19:58:30 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-03-09 19:58:30 +1000 |
commit | a8c6ecb3be7029881f7c95e5e201a629094a4e1a (patch) | |
tree | eb006541f40528f51334eefc725f155c4ce386a6 /sound/firewire/bebob/bebob.c | |
parent | 8dd0eb3566711d81bfbe2b4421b33f0dd723cec4 (diff) | |
parent | 9eccca0843205f87c00404b663188b88eb248051 (diff) |
Merge tag 'v4.0-rc3' into drm-next
Linux 4.0-rc3 backmerge to fix two i915 conflicts, and get
some mainline bug fixes needed for my testing box
Conflicts:
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_display.c
Diffstat (limited to 'sound/firewire/bebob/bebob.c')
-rw-r--r-- | sound/firewire/bebob/bebob.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c index fc19c99654aa..611b7dae7ee5 100644 --- a/sound/firewire/bebob/bebob.c +++ b/sound/firewire/bebob/bebob.c @@ -116,11 +116,22 @@ 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 bebob_card_free(struct snd_card *card) { struct snd_bebob *bebob = card->private_data; + snd_bebob_stream_destroy_duplex(bebob); + fw_unit_put(bebob->unit); + + kfree(bebob->maudio_special_quirk); + if (bebob->card_index >= 0) { mutex_lock(&devices_mutex); clear_bit(bebob->card_index, devices_used); @@ -205,7 +216,7 @@ bebob_probe(struct fw_unit *unit, card->private_free = bebob_card_free; bebob->card = card; - bebob->unit = unit; + bebob->unit = fw_unit_get(unit); bebob->spec = spec; mutex_init(&bebob->mutex); spin_lock_init(&bebob->lock); @@ -306,10 +317,11 @@ static void bebob_remove(struct fw_unit *unit) if (bebob == NULL) return; - kfree(bebob->maudio_special_quirk); + /* Awake bus-reset waiters. */ + if (!completion_done(&bebob->bus_reset)) + complete_all(&bebob->bus_reset); - snd_bebob_stream_destroy_duplex(bebob); - snd_card_disconnect(bebob->card); + /* No need to wait for releasing card object in this context. */ snd_card_free_when_closed(bebob->card); } |