diff options
| -rw-r--r-- | sound/core/pcm_native.c | 2 | ||||
| -rw-r--r-- | sound/firewire/amdtp.c | 5 | ||||
| -rw-r--r-- | sound/firewire/bebob/bebob.c | 20 | ||||
| -rw-r--r-- | sound/firewire/bebob/bebob_stream.c | 16 | ||||
| -rw-r--r-- | sound/firewire/dice/dice-stream.c | 18 | ||||
| -rw-r--r-- | sound/firewire/dice/dice.c | 16 | ||||
| -rw-r--r-- | sound/firewire/fireworks/fireworks.c | 20 | ||||
| -rw-r--r-- | sound/firewire/fireworks/fireworks_stream.c | 19 | ||||
| -rw-r--r-- | sound/firewire/oxfw/oxfw-stream.c | 6 | ||||
| -rw-r--r-- | sound/firewire/oxfw/oxfw.c | 21 | ||||
| -rw-r--r-- | sound/pci/hda/hda_controller.c | 5 | ||||
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 2 | ||||
| -rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 17 |
13 files changed, 106 insertions, 61 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index b03a638b420c..279e24f61305 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
| @@ -1552,6 +1552,8 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state) | |||
| 1552 | if (! snd_pcm_playback_empty(substream)) { | 1552 | if (! snd_pcm_playback_empty(substream)) { |
| 1553 | snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING); | 1553 | snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING); |
| 1554 | snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING); | 1554 | snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING); |
| 1555 | } else { | ||
| 1556 | runtime->status->state = SNDRV_PCM_STATE_SETUP; | ||
| 1555 | } | 1557 | } |
| 1556 | break; | 1558 | break; |
| 1557 | case SNDRV_PCM_STATE_RUNNING: | 1559 | case SNDRV_PCM_STATE_RUNNING: |
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 0d580186ef1a..5cc356db5351 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | */ | 33 | */ |
| 34 | #define MAX_MIDI_RX_BLOCKS 8 | 34 | #define MAX_MIDI_RX_BLOCKS 8 |
| 35 | 35 | ||
| 36 | #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ | 36 | #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */ |
| 37 | 37 | ||
| 38 | /* isochronous header parameters */ | 38 | /* isochronous header parameters */ |
| 39 | #define ISO_DATA_LENGTH_SHIFT 16 | 39 | #define ISO_DATA_LENGTH_SHIFT 16 |
| @@ -78,7 +78,7 @@ static void pcm_period_tasklet(unsigned long data); | |||
| 78 | int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, | 78 | int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, |
| 79 | enum amdtp_stream_direction dir, enum cip_flags flags) | 79 | enum amdtp_stream_direction dir, enum cip_flags flags) |
| 80 | { | 80 | { |
| 81 | s->unit = fw_unit_get(unit); | 81 | s->unit = unit; |
| 82 | s->direction = dir; | 82 | s->direction = dir; |
| 83 | s->flags = flags; | 83 | s->flags = flags; |
| 84 | s->context = ERR_PTR(-1); | 84 | s->context = ERR_PTR(-1); |
| @@ -102,7 +102,6 @@ void amdtp_stream_destroy(struct amdtp_stream *s) | |||
| 102 | { | 102 | { |
| 103 | WARN_ON(amdtp_stream_running(s)); | 103 | WARN_ON(amdtp_stream_running(s)); |
| 104 | mutex_destroy(&s->mutex); | 104 | mutex_destroy(&s->mutex); |
| 105 | fw_unit_put(s->unit); | ||
| 106 | } | 105 | } |
| 107 | EXPORT_SYMBOL(amdtp_stream_destroy); | 106 | EXPORT_SYMBOL(amdtp_stream_destroy); |
| 108 | 107 | ||
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: | |||
| 116 | return err; | 116 | return err; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | /* | ||
| 120 | * This module releases the FireWire unit data after all ALSA character devices | ||
| 121 | * are released by applications. This is for releasing stream data or finishing | ||
| 122 | * transactions safely. Thus at returning from .remove(), this module still keep | ||
| 123 | * references for the unit. | ||
| 124 | */ | ||
| 119 | static void | 125 | static void |
| 120 | bebob_card_free(struct snd_card *card) | 126 | bebob_card_free(struct snd_card *card) |
| 121 | { | 127 | { |
| 122 | struct snd_bebob *bebob = card->private_data; | 128 | struct snd_bebob *bebob = card->private_data; |
| 123 | 129 | ||
| 130 | snd_bebob_stream_destroy_duplex(bebob); | ||
| 131 | fw_unit_put(bebob->unit); | ||
| 132 | |||
| 133 | kfree(bebob->maudio_special_quirk); | ||
| 134 | |||
| 124 | if (bebob->card_index >= 0) { | 135 | if (bebob->card_index >= 0) { |
| 125 | mutex_lock(&devices_mutex); | 136 | mutex_lock(&devices_mutex); |
| 126 | clear_bit(bebob->card_index, devices_used); | 137 | clear_bit(bebob->card_index, devices_used); |
| @@ -205,7 +216,7 @@ bebob_probe(struct fw_unit *unit, | |||
| 205 | card->private_free = bebob_card_free; | 216 | card->private_free = bebob_card_free; |
| 206 | 217 | ||
| 207 | bebob->card = card; | 218 | bebob->card = card; |
| 208 | bebob->unit = unit; | 219 | bebob->unit = fw_unit_get(unit); |
| 209 | bebob->spec = spec; | 220 | bebob->spec = spec; |
| 210 | mutex_init(&bebob->mutex); | 221 | mutex_init(&bebob->mutex); |
| 211 | spin_lock_init(&bebob->lock); | 222 | spin_lock_init(&bebob->lock); |
| @@ -306,10 +317,11 @@ static void bebob_remove(struct fw_unit *unit) | |||
| 306 | if (bebob == NULL) | 317 | if (bebob == NULL) |
| 307 | return; | 318 | return; |
| 308 | 319 | ||
| 309 | kfree(bebob->maudio_special_quirk); | 320 | /* Awake bus-reset waiters. */ |
| 321 | if (!completion_done(&bebob->bus_reset)) | ||
| 322 | complete_all(&bebob->bus_reset); | ||
| 310 | 323 | ||
| 311 | snd_bebob_stream_destroy_duplex(bebob); | 324 | /* No need to wait for releasing card object in this context. */ |
| 312 | snd_card_disconnect(bebob->card); | ||
| 313 | snd_card_free_when_closed(bebob->card); | 325 | snd_card_free_when_closed(bebob->card); |
| 314 | } | 326 | } |
| 315 | 327 | ||
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c index 0ebcabfdc7ce..98e4fc8121a1 100644 --- a/sound/firewire/bebob/bebob_stream.c +++ b/sound/firewire/bebob/bebob_stream.c | |||
| @@ -410,8 +410,6 @@ break_both_connections(struct snd_bebob *bebob) | |||
| 410 | static void | 410 | static void |
| 411 | destroy_both_connections(struct snd_bebob *bebob) | 411 | destroy_both_connections(struct snd_bebob *bebob) |
| 412 | { | 412 | { |
| 413 | break_both_connections(bebob); | ||
| 414 | |||
| 415 | cmp_connection_destroy(&bebob->in_conn); | 413 | cmp_connection_destroy(&bebob->in_conn); |
| 416 | cmp_connection_destroy(&bebob->out_conn); | 414 | cmp_connection_destroy(&bebob->out_conn); |
| 417 | } | 415 | } |
| @@ -712,22 +710,16 @@ void snd_bebob_stream_update_duplex(struct snd_bebob *bebob) | |||
| 712 | mutex_unlock(&bebob->mutex); | 710 | mutex_unlock(&bebob->mutex); |
| 713 | } | 711 | } |
| 714 | 712 | ||
| 713 | /* | ||
| 714 | * This function should be called before starting streams or after stopping | ||
| 715 | * streams. | ||
| 716 | */ | ||
| 715 | void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob) | 717 | void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob) |
| 716 | { | 718 | { |
| 717 | mutex_lock(&bebob->mutex); | ||
| 718 | |||
| 719 | amdtp_stream_pcm_abort(&bebob->rx_stream); | ||
| 720 | amdtp_stream_pcm_abort(&bebob->tx_stream); | ||
| 721 | |||
| 722 | amdtp_stream_stop(&bebob->rx_stream); | ||
| 723 | amdtp_stream_stop(&bebob->tx_stream); | ||
| 724 | |||
| 725 | amdtp_stream_destroy(&bebob->rx_stream); | 719 | amdtp_stream_destroy(&bebob->rx_stream); |
| 726 | amdtp_stream_destroy(&bebob->tx_stream); | 720 | amdtp_stream_destroy(&bebob->tx_stream); |
| 727 | 721 | ||
| 728 | destroy_both_connections(bebob); | 722 | destroy_both_connections(bebob); |
| 729 | |||
| 730 | mutex_unlock(&bebob->mutex); | ||
| 731 | } | 723 | } |
| 732 | 724 | ||
| 733 | /* | 725 | /* |
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c index fa9cf761b610..07dbd01d7a6b 100644 --- a/sound/firewire/dice/dice-stream.c +++ b/sound/firewire/dice/dice-stream.c | |||
| @@ -311,14 +311,21 @@ end: | |||
| 311 | return err; | 311 | return err; |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | /* | ||
| 315 | * This function should be called before starting streams or after stopping | ||
| 316 | * streams. | ||
| 317 | */ | ||
| 314 | static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream) | 318 | static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream) |
| 315 | { | 319 | { |
| 316 | amdtp_stream_destroy(stream); | 320 | struct fw_iso_resources *resources; |
| 317 | 321 | ||
| 318 | if (stream == &dice->tx_stream) | 322 | if (stream == &dice->tx_stream) |
| 319 | fw_iso_resources_destroy(&dice->tx_resources); | 323 | resources = &dice->tx_resources; |
| 320 | else | 324 | else |
| 321 | fw_iso_resources_destroy(&dice->rx_resources); | 325 | resources = &dice->rx_resources; |
| 326 | |||
| 327 | amdtp_stream_destroy(stream); | ||
| 328 | fw_iso_resources_destroy(resources); | ||
| 322 | } | 329 | } |
| 323 | 330 | ||
| 324 | int snd_dice_stream_init_duplex(struct snd_dice *dice) | 331 | int snd_dice_stream_init_duplex(struct snd_dice *dice) |
| @@ -332,6 +339,8 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice) | |||
| 332 | goto end; | 339 | goto end; |
| 333 | 340 | ||
| 334 | err = init_stream(dice, &dice->rx_stream); | 341 | err = init_stream(dice, &dice->rx_stream); |
| 342 | if (err < 0) | ||
| 343 | destroy_stream(dice, &dice->tx_stream); | ||
| 335 | end: | 344 | end: |
| 336 | return err; | 345 | return err; |
| 337 | } | 346 | } |
| @@ -340,10 +349,7 @@ void snd_dice_stream_destroy_duplex(struct snd_dice *dice) | |||
| 340 | { | 349 | { |
| 341 | snd_dice_transaction_clear_enable(dice); | 350 | snd_dice_transaction_clear_enable(dice); |
| 342 | 351 | ||
| 343 | stop_stream(dice, &dice->tx_stream); | ||
| 344 | destroy_stream(dice, &dice->tx_stream); | 352 | destroy_stream(dice, &dice->tx_stream); |
| 345 | |||
| 346 | stop_stream(dice, &dice->rx_stream); | ||
| 347 | destroy_stream(dice, &dice->rx_stream); | 353 | destroy_stream(dice, &dice->rx_stream); |
| 348 | 354 | ||
| 349 | dice->substreams_counter = 0; | 355 | dice->substreams_counter = 0; |
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c index 90d8f40ff727..70a111d7f428 100644 --- a/sound/firewire/dice/dice.c +++ b/sound/firewire/dice/dice.c | |||
| @@ -226,11 +226,20 @@ static void dice_card_strings(struct snd_dice *dice) | |||
| 226 | strcpy(card->mixername, "DICE"); | 226 | strcpy(card->mixername, "DICE"); |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | /* | ||
| 230 | * This module releases the FireWire unit data after all ALSA character devices | ||
| 231 | * are released by applications. This is for releasing stream data or finishing | ||
| 232 | * transactions safely. Thus at returning from .remove(), this module still keep | ||
| 233 | * references for the unit. | ||
| 234 | */ | ||
| 229 | static void dice_card_free(struct snd_card *card) | 235 | static void dice_card_free(struct snd_card *card) |
| 230 | { | 236 | { |
| 231 | struct snd_dice *dice = card->private_data; | 237 | struct snd_dice *dice = card->private_data; |
| 232 | 238 | ||
| 239 | snd_dice_stream_destroy_duplex(dice); | ||
| 233 | snd_dice_transaction_destroy(dice); | 240 | snd_dice_transaction_destroy(dice); |
| 241 | fw_unit_put(dice->unit); | ||
| 242 | |||
| 234 | mutex_destroy(&dice->mutex); | 243 | mutex_destroy(&dice->mutex); |
| 235 | } | 244 | } |
| 236 | 245 | ||
| @@ -251,7 +260,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) | |||
| 251 | 260 | ||
| 252 | dice = card->private_data; | 261 | dice = card->private_data; |
| 253 | dice->card = card; | 262 | dice->card = card; |
| 254 | dice->unit = unit; | 263 | dice->unit = fw_unit_get(unit); |
| 255 | card->private_free = dice_card_free; | 264 | card->private_free = dice_card_free; |
| 256 | 265 | ||
| 257 | spin_lock_init(&dice->lock); | 266 | spin_lock_init(&dice->lock); |
| @@ -305,10 +314,7 @@ static void dice_remove(struct fw_unit *unit) | |||
| 305 | { | 314 | { |
| 306 | struct snd_dice *dice = dev_get_drvdata(&unit->device); | 315 | struct snd_dice *dice = dev_get_drvdata(&unit->device); |
| 307 | 316 | ||
| 308 | snd_card_disconnect(dice->card); | 317 | /* No need to wait for releasing card object in this context. */ |
| 309 | |||
| 310 | snd_dice_stream_destroy_duplex(dice); | ||
| 311 | |||
| 312 | snd_card_free_when_closed(dice->card); | 318 | snd_card_free_when_closed(dice->card); |
| 313 | } | 319 | } |
| 314 | 320 | ||
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 | */ | ||
| 176 | static void | 182 | static void |
| 177 | efw_card_free(struct snd_card *card) | 183 | efw_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 | ||
| 191 | static int | 202 | static 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 | ||
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index 4f440e163667..c55db1bddc80 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c | |||
| @@ -100,17 +100,22 @@ end: | |||
| 100 | return err; | 100 | return err; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /* | ||
| 104 | * This function should be called before starting the stream or after stopping | ||
| 105 | * the streams. | ||
| 106 | */ | ||
| 103 | static void | 107 | static void |
| 104 | destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream) | 108 | destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream) |
| 105 | { | 109 | { |
| 106 | stop_stream(efw, stream); | 110 | struct cmp_connection *conn; |
| 107 | |||
| 108 | amdtp_stream_destroy(stream); | ||
| 109 | 111 | ||
| 110 | if (stream == &efw->tx_stream) | 112 | if (stream == &efw->tx_stream) |
| 111 | cmp_connection_destroy(&efw->out_conn); | 113 | conn = &efw->out_conn; |
| 112 | else | 114 | else |
| 113 | cmp_connection_destroy(&efw->in_conn); | 115 | conn = &efw->in_conn; |
| 116 | |||
| 117 | amdtp_stream_destroy(stream); | ||
| 118 | cmp_connection_destroy(&efw->out_conn); | ||
| 114 | } | 119 | } |
| 115 | 120 | ||
| 116 | static int | 121 | static int |
| @@ -319,12 +324,8 @@ void snd_efw_stream_update_duplex(struct snd_efw *efw) | |||
| 319 | 324 | ||
| 320 | void snd_efw_stream_destroy_duplex(struct snd_efw *efw) | 325 | void snd_efw_stream_destroy_duplex(struct snd_efw *efw) |
| 321 | { | 326 | { |
| 322 | mutex_lock(&efw->mutex); | ||
| 323 | |||
| 324 | destroy_stream(efw, &efw->rx_stream); | 327 | destroy_stream(efw, &efw->rx_stream); |
| 325 | destroy_stream(efw, &efw->tx_stream); | 328 | destroy_stream(efw, &efw->tx_stream); |
| 326 | |||
| 327 | mutex_unlock(&efw->mutex); | ||
| 328 | } | 329 | } |
| 329 | 330 | ||
| 330 | void snd_efw_stream_lock_changed(struct snd_efw *efw) | 331 | void snd_efw_stream_lock_changed(struct snd_efw *efw) |
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c index bda845afb470..29ccb3637164 100644 --- a/sound/firewire/oxfw/oxfw-stream.c +++ b/sound/firewire/oxfw/oxfw-stream.c | |||
| @@ -337,6 +337,10 @@ void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw, | |||
| 337 | stop_stream(oxfw, stream); | 337 | stop_stream(oxfw, stream); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | /* | ||
| 341 | * This function should be called before starting the stream or after stopping | ||
| 342 | * the streams. | ||
| 343 | */ | ||
| 340 | void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw, | 344 | void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw, |
| 341 | struct amdtp_stream *stream) | 345 | struct amdtp_stream *stream) |
| 342 | { | 346 | { |
| @@ -347,8 +351,6 @@ void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw, | |||
| 347 | else | 351 | else |
| 348 | conn = &oxfw->in_conn; | 352 | conn = &oxfw->in_conn; |
| 349 | 353 | ||
| 350 | stop_stream(oxfw, stream); | ||
| 351 | |||
| 352 | amdtp_stream_destroy(stream); | 354 | amdtp_stream_destroy(stream); |
| 353 | cmp_connection_destroy(conn); | 355 | cmp_connection_destroy(conn); |
| 354 | } | 356 | } |
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c index 60e5cad0531a..8c6ce019f437 100644 --- a/sound/firewire/oxfw/oxfw.c +++ b/sound/firewire/oxfw/oxfw.c | |||
| @@ -104,11 +104,23 @@ end: | |||
| 104 | return err; | 104 | return err; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | /* | ||
| 108 | * This module releases the FireWire unit data after all ALSA character devices | ||
| 109 | * are released by applications. This is for releasing stream data or finishing | ||
| 110 | * transactions safely. Thus at returning from .remove(), this module still keep | ||
| 111 | * references for the unit. | ||
| 112 | */ | ||
| 107 | static void oxfw_card_free(struct snd_card *card) | 113 | static void oxfw_card_free(struct snd_card *card) |
| 108 | { | 114 | { |
| 109 | struct snd_oxfw *oxfw = card->private_data; | 115 | struct snd_oxfw *oxfw = card->private_data; |
| 110 | unsigned int i; | 116 | unsigned int i; |
| 111 | 117 | ||
| 118 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); | ||
| 119 | if (oxfw->has_output) | ||
| 120 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); | ||
| 121 | |||
| 122 | fw_unit_put(oxfw->unit); | ||
| 123 | |||
| 112 | for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { | 124 | for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { |
| 113 | kfree(oxfw->tx_stream_formats[i]); | 125 | kfree(oxfw->tx_stream_formats[i]); |
| 114 | kfree(oxfw->rx_stream_formats[i]); | 126 | kfree(oxfw->rx_stream_formats[i]); |
| @@ -136,7 +148,7 @@ static int oxfw_probe(struct fw_unit *unit, | |||
| 136 | oxfw = card->private_data; | 148 | oxfw = card->private_data; |
| 137 | oxfw->card = card; | 149 | oxfw->card = card; |
| 138 | mutex_init(&oxfw->mutex); | 150 | mutex_init(&oxfw->mutex); |
| 139 | oxfw->unit = unit; | 151 | oxfw->unit = fw_unit_get(unit); |
| 140 | oxfw->device_info = (const struct device_info *)id->driver_data; | 152 | oxfw->device_info = (const struct device_info *)id->driver_data; |
| 141 | spin_lock_init(&oxfw->lock); | 153 | spin_lock_init(&oxfw->lock); |
| 142 | init_waitqueue_head(&oxfw->hwdep_wait); | 154 | init_waitqueue_head(&oxfw->hwdep_wait); |
| @@ -212,12 +224,7 @@ static void oxfw_remove(struct fw_unit *unit) | |||
| 212 | { | 224 | { |
| 213 | struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); | 225 | struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); |
| 214 | 226 | ||
| 215 | snd_card_disconnect(oxfw->card); | 227 | /* No need to wait for releasing card object in this context. */ |
| 216 | |||
| 217 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); | ||
| 218 | if (oxfw->has_output) | ||
| 219 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); | ||
| 220 | |||
| 221 | snd_card_free_when_closed(oxfw->card); | 228 | snd_card_free_when_closed(oxfw->card); |
| 222 | } | 229 | } |
| 223 | 230 | ||
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index dfcb5e929f9f..a2ce773bdc62 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
| @@ -961,7 +961,6 @@ static int azx_alloc_cmd_io(struct azx *chip) | |||
| 961 | dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n"); | 961 | dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n"); |
| 962 | return err; | 962 | return err; |
| 963 | } | 963 | } |
| 964 | EXPORT_SYMBOL_GPL(azx_alloc_cmd_io); | ||
| 965 | 964 | ||
| 966 | static void azx_init_cmd_io(struct azx *chip) | 965 | static void azx_init_cmd_io(struct azx *chip) |
| 967 | { | 966 | { |
| @@ -1026,7 +1025,6 @@ static void azx_init_cmd_io(struct azx *chip) | |||
| 1026 | azx_writeb(chip, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); | 1025 | azx_writeb(chip, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); |
| 1027 | spin_unlock_irq(&chip->reg_lock); | 1026 | spin_unlock_irq(&chip->reg_lock); |
| 1028 | } | 1027 | } |
| 1029 | EXPORT_SYMBOL_GPL(azx_init_cmd_io); | ||
| 1030 | 1028 | ||
| 1031 | static void azx_free_cmd_io(struct azx *chip) | 1029 | static void azx_free_cmd_io(struct azx *chip) |
| 1032 | { | 1030 | { |
| @@ -1036,7 +1034,6 @@ static void azx_free_cmd_io(struct azx *chip) | |||
| 1036 | azx_writeb(chip, CORBCTL, 0); | 1034 | azx_writeb(chip, CORBCTL, 0); |
| 1037 | spin_unlock_irq(&chip->reg_lock); | 1035 | spin_unlock_irq(&chip->reg_lock); |
| 1038 | } | 1036 | } |
| 1039 | EXPORT_SYMBOL_GPL(azx_free_cmd_io); | ||
| 1040 | 1037 | ||
| 1041 | static unsigned int azx_command_addr(u32 cmd) | 1038 | static unsigned int azx_command_addr(u32 cmd) |
| 1042 | { | 1039 | { |
| @@ -1316,7 +1313,6 @@ static int azx_send_cmd(struct hda_bus *bus, unsigned int val) | |||
| 1316 | else | 1313 | else |
| 1317 | return azx_corb_send_cmd(bus, val); | 1314 | return azx_corb_send_cmd(bus, val); |
| 1318 | } | 1315 | } |
| 1319 | EXPORT_SYMBOL_GPL(azx_send_cmd); | ||
| 1320 | 1316 | ||
| 1321 | /* get a response */ | 1317 | /* get a response */ |
| 1322 | static unsigned int azx_get_response(struct hda_bus *bus, | 1318 | static unsigned int azx_get_response(struct hda_bus *bus, |
| @@ -1330,7 +1326,6 @@ static unsigned int azx_get_response(struct hda_bus *bus, | |||
| 1330 | else | 1326 | else |
| 1331 | return azx_rirb_get_response(bus, addr); | 1327 | return azx_rirb_get_response(bus, addr); |
| 1332 | } | 1328 | } |
| 1333 | EXPORT_SYMBOL_GPL(azx_get_response); | ||
| 1334 | 1329 | ||
| 1335 | #ifdef CONFIG_SND_HDA_DSP_LOADER | 1330 | #ifdef CONFIG_SND_HDA_DSP_LOADER |
| 1336 | /* | 1331 | /* |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 36d2f20db7a4..4ca3d5d02436 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -1966,7 +1966,7 @@ static const struct pci_device_id azx_ids[] = { | |||
| 1966 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, | 1966 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, |
| 1967 | /* Panther Point */ | 1967 | /* Panther Point */ |
| 1968 | { PCI_DEVICE(0x8086, 0x1e20), | 1968 | { PCI_DEVICE(0x8086, 0x1e20), |
| 1969 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, | 1969 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, |
| 1970 | /* Lynx Point */ | 1970 | /* Lynx Point */ |
| 1971 | { PCI_DEVICE(0x8086, 0x8c20), | 1971 | { PCI_DEVICE(0x8086, 0x8c20), |
| 1972 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, | 1972 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6d36c5b78805..87eff3173ce9 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -79,6 +79,7 @@ enum { | |||
| 79 | STAC_ALIENWARE_M17X, | 79 | STAC_ALIENWARE_M17X, |
| 80 | STAC_92HD89XX_HP_FRONT_JACK, | 80 | STAC_92HD89XX_HP_FRONT_JACK, |
| 81 | STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK, | 81 | STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK, |
| 82 | STAC_92HD73XX_ASUS_MOBO, | ||
| 82 | STAC_92HD73XX_MODELS | 83 | STAC_92HD73XX_MODELS |
| 83 | }; | 84 | }; |
| 84 | 85 | ||
| @@ -1911,7 +1912,18 @@ static const struct hda_fixup stac92hd73xx_fixups[] = { | |||
| 1911 | [STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = { | 1912 | [STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = { |
| 1912 | .type = HDA_FIXUP_PINS, | 1913 | .type = HDA_FIXUP_PINS, |
| 1913 | .v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs, | 1914 | .v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs, |
| 1914 | } | 1915 | }, |
| 1916 | [STAC_92HD73XX_ASUS_MOBO] = { | ||
| 1917 | .type = HDA_FIXUP_PINS, | ||
| 1918 | .v.pins = (const struct hda_pintbl[]) { | ||
| 1919 | /* enable 5.1 and SPDIF out */ | ||
| 1920 | { 0x0c, 0x01014411 }, | ||
| 1921 | { 0x0d, 0x01014410 }, | ||
| 1922 | { 0x0e, 0x01014412 }, | ||
| 1923 | { 0x22, 0x014b1180 }, | ||
| 1924 | { } | ||
| 1925 | } | ||
| 1926 | }, | ||
| 1915 | }; | 1927 | }; |
| 1916 | 1928 | ||
| 1917 | static const struct hda_model_fixup stac92hd73xx_models[] = { | 1929 | static const struct hda_model_fixup stac92hd73xx_models[] = { |
| @@ -1923,6 +1935,7 @@ static const struct hda_model_fixup stac92hd73xx_models[] = { | |||
| 1923 | { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" }, | 1935 | { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" }, |
| 1924 | { .id = STAC_DELL_EQ, .name = "dell-eq" }, | 1936 | { .id = STAC_DELL_EQ, .name = "dell-eq" }, |
| 1925 | { .id = STAC_ALIENWARE_M17X, .name = "alienware" }, | 1937 | { .id = STAC_ALIENWARE_M17X, .name = "alienware" }, |
| 1938 | { .id = STAC_92HD73XX_ASUS_MOBO, .name = "asus-mobo" }, | ||
| 1926 | {} | 1939 | {} |
| 1927 | }; | 1940 | }; |
| 1928 | 1941 | ||
| @@ -1975,6 +1988,8 @@ static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = { | |||
| 1975 | "HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK), | 1988 | "HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK), |
| 1976 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17, | 1989 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17, |
| 1977 | "unknown HP", STAC_92HD89XX_HP_FRONT_JACK), | 1990 | "unknown HP", STAC_92HD89XX_HP_FRONT_JACK), |
| 1991 | SND_PCI_QUIRK(PCI_VENDOR_ID_ASUSTEK, 0x83f8, "ASUS AT4NM10", | ||
| 1992 | STAC_92HD73XX_ASUS_MOBO), | ||
| 1978 | {} /* terminator */ | 1993 | {} /* terminator */ |
| 1979 | }; | 1994 | }; |
| 1980 | 1995 | ||
