Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed42e71a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "Most of changes in this pull request are about the fixes of crash of
  FireWire drivers at hot-unplugging.  In addition, there are a few
  HD-audio fixes (removal of wrong static, a pin quirk for an ASUS mobo,
  a regression fix for runtime PM on Panther Point) and a long-standing
  (but fairly minor) bug of PCM core"

* tag 'sound-4.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - Disable runtime PM for Panther Point again
  ALSA: hda: controller code - do not export static functions
  ALSA: pcm: Don't leave PREPARED state after draining
  ALSA: fireworks/bebob/dice/oxfw: make it possible to shutdown safely
  ALSA: fireworks/bebob/dice/oxfw: allow stream destructor after releasing runtime
  ALSA: firewire-lib: remove reference counting
  ALSA: fireworks/bebob/dice/oxfw: add reference-counting for FireWire unit
  ALSA: hda - Add pin configs for ASUS mobo with IDT 92HD73XX codec
  ALSA: firewire-lib: fix an unexpected byte sequence for micro sign
parents 7dac5cb1 de5d0ad5
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -1552,6 +1552,8 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
			if (! snd_pcm_playback_empty(substream)) {
			if (! snd_pcm_playback_empty(substream)) {
				snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING);
				snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING);
				snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING);
				snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING);
			} else {
				runtime->status->state = SNDRV_PCM_STATE_SETUP;
			}
			}
			break;
			break;
		case SNDRV_PCM_STATE_RUNNING:
		case SNDRV_PCM_STATE_RUNNING:
+2 −3
Original line number Original line Diff line number Diff line
@@ -33,7 +33,7 @@
 */
 */
#define MAX_MIDI_RX_BLOCKS	8
#define MAX_MIDI_RX_BLOCKS	8


#define TRANSFER_DELAY_TICKS	0x2e00 /* 479.17 µs */
#define TRANSFER_DELAY_TICKS	0x2e00 /* 479.17 microseconds */


/* isochronous header parameters */
/* isochronous header parameters */
#define ISO_DATA_LENGTH_SHIFT	16
#define ISO_DATA_LENGTH_SHIFT	16
@@ -78,7 +78,7 @@ static void pcm_period_tasklet(unsigned long data);
int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
		      enum amdtp_stream_direction dir, enum cip_flags flags)
		      enum amdtp_stream_direction dir, enum cip_flags flags)
{
{
	s->unit = fw_unit_get(unit);
	s->unit = unit;
	s->direction = dir;
	s->direction = dir;
	s->flags = flags;
	s->flags = flags;
	s->context = ERR_PTR(-1);
	s->context = ERR_PTR(-1);
@@ -102,7 +102,6 @@ void amdtp_stream_destroy(struct amdtp_stream *s)
{
{
	WARN_ON(amdtp_stream_running(s));
	WARN_ON(amdtp_stream_running(s));
	mutex_destroy(&s->mutex);
	mutex_destroy(&s->mutex);
	fw_unit_put(s->unit);
}
}
EXPORT_SYMBOL(amdtp_stream_destroy);
EXPORT_SYMBOL(amdtp_stream_destroy);


+16 −4
Original line number Original line Diff line number Diff line
@@ -116,11 +116,22 @@ name_device(struct snd_bebob *bebob, unsigned int vendor_id)
	return err;
	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
static void
bebob_card_free(struct snd_card *card)
bebob_card_free(struct snd_card *card)
{
{
	struct snd_bebob *bebob = card->private_data;
	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) {
	if (bebob->card_index >= 0) {
		mutex_lock(&devices_mutex);
		mutex_lock(&devices_mutex);
		clear_bit(bebob->card_index, devices_used);
		clear_bit(bebob->card_index, devices_used);
@@ -205,7 +216,7 @@ bebob_probe(struct fw_unit *unit,
	card->private_free = bebob_card_free;
	card->private_free = bebob_card_free;


	bebob->card = card;
	bebob->card = card;
	bebob->unit = unit;
	bebob->unit = fw_unit_get(unit);
	bebob->spec = spec;
	bebob->spec = spec;
	mutex_init(&bebob->mutex);
	mutex_init(&bebob->mutex);
	spin_lock_init(&bebob->lock);
	spin_lock_init(&bebob->lock);
@@ -306,10 +317,11 @@ static void bebob_remove(struct fw_unit *unit)
	if (bebob == NULL)
	if (bebob == NULL)
		return;
		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);
	/* No need to wait for releasing card object in this context. */
	snd_card_disconnect(bebob->card);
	snd_card_free_when_closed(bebob->card);
	snd_card_free_when_closed(bebob->card);
}
}


+4 −12
Original line number Original line Diff line number Diff line
@@ -410,8 +410,6 @@ break_both_connections(struct snd_bebob *bebob)
static void
static void
destroy_both_connections(struct snd_bebob *bebob)
destroy_both_connections(struct snd_bebob *bebob)
{
{
	break_both_connections(bebob);

	cmp_connection_destroy(&bebob->in_conn);
	cmp_connection_destroy(&bebob->in_conn);
	cmp_connection_destroy(&bebob->out_conn);
	cmp_connection_destroy(&bebob->out_conn);
}
}
@@ -712,22 +710,16 @@ void snd_bebob_stream_update_duplex(struct snd_bebob *bebob)
	mutex_unlock(&bebob->mutex);
	mutex_unlock(&bebob->mutex);
}
}


/*
 * This function should be called before starting streams or after stopping
 * streams.
 */
void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob)
void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob)
{
{
	mutex_lock(&bebob->mutex);

	amdtp_stream_pcm_abort(&bebob->rx_stream);
	amdtp_stream_pcm_abort(&bebob->tx_stream);

	amdtp_stream_stop(&bebob->rx_stream);
	amdtp_stream_stop(&bebob->tx_stream);

	amdtp_stream_destroy(&bebob->rx_stream);
	amdtp_stream_destroy(&bebob->rx_stream);
	amdtp_stream_destroy(&bebob->tx_stream);
	amdtp_stream_destroy(&bebob->tx_stream);


	destroy_both_connections(bebob);
	destroy_both_connections(bebob);

	mutex_unlock(&bebob->mutex);
}
}


/*
/*
+12 −6
Original line number Original line Diff line number Diff line
@@ -311,14 +311,21 @@ static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream)
	return err;
	return err;
}
}


/*
 * This function should be called before starting streams or after stopping
 * streams.
 */
static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream)
static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream)
{
{
	amdtp_stream_destroy(stream);
	struct fw_iso_resources *resources;


	if (stream == &dice->tx_stream)
	if (stream == &dice->tx_stream)
		fw_iso_resources_destroy(&dice->tx_resources);
		resources = &dice->tx_resources;
	else
	else
		fw_iso_resources_destroy(&dice->rx_resources);
		resources = &dice->rx_resources;

	amdtp_stream_destroy(stream);
	fw_iso_resources_destroy(resources);
}
}


int snd_dice_stream_init_duplex(struct snd_dice *dice)
int snd_dice_stream_init_duplex(struct snd_dice *dice)
@@ -332,6 +339,8 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice)
		goto end;
		goto end;


	err = init_stream(dice, &dice->rx_stream);
	err = init_stream(dice, &dice->rx_stream);
	if (err < 0)
		destroy_stream(dice, &dice->tx_stream);
end:
end:
	return err;
	return err;
}
}
@@ -340,10 +349,7 @@ void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
{
{
	snd_dice_transaction_clear_enable(dice);
	snd_dice_transaction_clear_enable(dice);


	stop_stream(dice, &dice->tx_stream);
	destroy_stream(dice, &dice->tx_stream);
	destroy_stream(dice, &dice->tx_stream);

	stop_stream(dice, &dice->rx_stream);
	destroy_stream(dice, &dice->rx_stream);
	destroy_stream(dice, &dice->rx_stream);


	dice->substreams_counter = 0;
	dice->substreams_counter = 0;
Loading