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

Commit 6336c20c authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: lx6464es: Use nonatomic PCM ops



Like the other previous changes, this patch for lx6464es takes the
same strategy for converting to nonatomic PCM ops: replacing spinlock
with mutex, converting the irq tasklet to the threaded irq, and
merging the trigger tasklets back to the trigger callback.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 9bef72bd
Loading
Loading
Loading
Loading
+14 −29
Original line number Diff line number Diff line
@@ -279,7 +279,6 @@ static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream
{
	struct lx6464es *chip = snd_pcm_substream_chip(substream);
	snd_pcm_uframes_t pos;
	unsigned long flags;
	int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);

	struct lx_stream *lx_stream = is_capture ? &chip->capture_stream :
@@ -287,9 +286,9 @@ static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream

	dev_dbg(chip->card->dev, "->lx_pcm_stream_pointer\n");

	spin_lock_irqsave(&chip->lock, flags);
	mutex_lock(&chip->lock);
	pos = lx_stream->frame_pos * substream->runtime->period_size;
	spin_unlock_irqrestore(&chip->lock, flags);
	mutex_unlock(&chip->lock);

	dev_dbg(chip->card->dev, "stream_pointer at %ld\n", pos);
	return pos;
@@ -485,7 +484,7 @@ static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream)

}

static void lx_trigger_tasklet_dispatch_stream(struct lx6464es *chip,
static void lx_trigger_dispatch_stream(struct lx6464es *chip,
				       struct lx_stream *lx_stream)
{
	switch (lx_stream->status) {
@@ -502,24 +501,12 @@ static void lx_trigger_tasklet_dispatch_stream(struct lx6464es *chip,
	}
}

static void lx_trigger_tasklet(unsigned long data)
{
	struct lx6464es *chip = (struct lx6464es *)data;
	unsigned long flags;

	dev_dbg(chip->card->dev, "->lx_trigger_tasklet\n");

	spin_lock_irqsave(&chip->lock, flags);
	lx_trigger_tasklet_dispatch_stream(chip, &chip->capture_stream);
	lx_trigger_tasklet_dispatch_stream(chip, &chip->playback_stream);
	spin_unlock_irqrestore(&chip->lock, flags);
}

static int lx_pcm_trigger_dispatch(struct lx6464es *chip,
				   struct lx_stream *lx_stream, int cmd)
{
	int err = 0;

	mutex_lock(&chip->lock);
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN;
@@ -533,9 +520,12 @@ static int lx_pcm_trigger_dispatch(struct lx6464es *chip,
		err = -EINVAL;
		goto exit;
	}
	tasklet_schedule(&chip->trigger_tasklet);

	lx_trigger_dispatch_stream(chip, &chip->capture_stream);
	lx_trigger_dispatch_stream(chip, &chip->playback_stream);

exit:
	mutex_unlock(&chip->lock);
	return err;
}

@@ -861,6 +851,7 @@ static int lx_pcm_create(struct lx6464es *chip)
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &lx_ops_capture);

	pcm->info_flags = 0;
	pcm->nonatomic = true;
	strcpy(pcm->name, card_name);

	err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
@@ -1009,15 +1000,9 @@ static int snd_lx6464es_create(struct snd_card *card,
	chip->irq = -1;

	/* initialize synchronization structs */
	spin_lock_init(&chip->lock);
	spin_lock_init(&chip->msg_lock);
	mutex_init(&chip->lock);
	mutex_init(&chip->msg_lock);
	mutex_init(&chip->setup_mutex);
	tasklet_init(&chip->trigger_tasklet, lx_trigger_tasklet,
		     (unsigned long)chip);
	tasklet_init(&chip->tasklet_capture, lx_tasklet_capture,
		     (unsigned long)chip);
	tasklet_init(&chip->tasklet_playback, lx_tasklet_playback,
		     (unsigned long)chip);

	/* request resources */
	err = pci_request_regions(pci, card_name);
@@ -1032,8 +1017,8 @@ static int snd_lx6464es_create(struct snd_card *card,
	/* dsp port */
	chip->port_dsp_bar = pci_ioremap_bar(pci, 2);

	err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED,
			  KBUILD_MODNAME, chip);
	err = request_threaded_irq(pci->irq, lx_interrupt, lx_threaded_irq,
				   IRQF_SHARED, KBUILD_MODNAME, chip);
	if (err) {
		dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
		goto request_irq_failed;
+3 −6
Original line number Diff line number Diff line
@@ -71,14 +71,10 @@ struct lx6464es {

	u8			mac_address[6];

	spinlock_t		lock;        /* interrupt spinlock */
	struct mutex		lock;        /* interrupt lock */
	struct mutex            setup_mutex; /* mutex used in hw_params, open
					      * and close */

	struct tasklet_struct   trigger_tasklet; /* trigger tasklet */
	struct tasklet_struct   tasklet_capture;
	struct tasklet_struct   tasklet_playback;

	/* ports */
	unsigned long		port_plx;	   /* io port (size=256) */
	void __iomem           *port_plx_remapped; /* remapped plx port */
@@ -87,8 +83,9 @@ struct lx6464es {
						    * size=8K) */

	/* messaging */
	spinlock_t		msg_lock;          /* message spinlock */
	struct mutex		msg_lock;          /* message lock */
	struct lx_rmh           rmh;
	u32			irqsrc;

	/* configuration */
	uint			freq_ratio : 2;
+90 −162
Original line number Diff line number Diff line
@@ -332,27 +332,25 @@ static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh)
int lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version)
{
	u16 ret;
	unsigned long flags;

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);

	lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG);
	ret = lx_message_send_atomic(chip, &chip->rmh);

	*rdsp_version = chip->rmh.stat[1];
	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return ret;
}

int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
{
	u16 ret = 0;
	unsigned long flags;
	u32 freq_raw = 0;
	u32 freq = 0;
	u32 frequency = 0;

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);

	lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG);
	ret = lx_message_send_atomic(chip, &chip->rmh);
@@ -370,7 +368,7 @@ int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
			frequency = 48000;
	}

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);

	*rfreq = frequency * chip->freq_ratio;

@@ -398,25 +396,23 @@ int lx_dsp_get_mac(struct lx6464es *chip)

int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran)
{
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);

	lx_message_init(&chip->rmh, CMD_02_SET_GRANULARITY);
	chip->rmh.cmd[0] |= gran;

	ret = lx_message_send_atomic(chip, &chip->rmh);
	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return ret;
}

int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data)
{
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);

	lx_message_init(&chip->rmh, CMD_04_GET_EVENT);
	chip->rmh.stat_len = 9;	/* we don't necessarily need the full length */
@@ -426,7 +422,7 @@ int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data)
	if (!ret)
		memcpy(data, chip->rmh.stat, chip->rmh.stat_len * sizeof(u32));

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return ret;
}

@@ -440,18 +436,16 @@ int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture,
		     int channels)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_06_ALLOCATE_PIPE);

	chip->rmh.cmd[0] |= pipe_cmd;
	chip->rmh.cmd[0] |= channels;

	err = lx_message_send_atomic(chip, &chip->rmh);
	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);

	if (err != 0)
		dev_err(chip->card->dev, "could not allocate pipe\n");
@@ -462,17 +456,15 @@ int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture,
int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_07_RELEASE_PIPE);

	chip->rmh.cmd[0] |= pipe_cmd;

	err = lx_message_send_atomic(chip, &chip->rmh);
	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);

	return err;
}
@@ -481,8 +473,6 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
		  u32 *r_needed, u32 *r_freed, u32 *size_array)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

#ifdef CONFIG_SND_DEBUG
@@ -493,7 +483,7 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
	*r_needed = 0;
	*r_freed = 0;

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_08_ASK_BUFFERS);

	chip->rmh.cmd[0] |= pipe_cmd;
@@ -527,7 +517,7 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
		}
	}

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

@@ -535,36 +525,32 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_09_STOP_PIPE);

	chip->rmh.cmd[0] |= pipe_cmd;

	err = lx_message_send_atomic(chip, &chip->rmh);

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

static int lx_pipe_toggle_state(struct lx6464es *chip, u32 pipe, int is_capture)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_0B_TOGGLE_PIPE_STATE);

	chip->rmh.cmd[0] |= pipe_cmd;

	err = lx_message_send_atomic(chip, &chip->rmh);

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

@@ -600,11 +586,9 @@ int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture,
			 u64 *rsample_count)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT);

	chip->rmh.cmd[0] |= pipe_cmd;
@@ -621,18 +605,16 @@ int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture,
			+ chip->rmh.stat[1]; /* lo part */
	}

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT);

	chip->rmh.cmd[0] |= pipe_cmd;
@@ -644,7 +626,7 @@ int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate)
	else
		*rstate = (chip->rmh.stat[0] >> PSTATE_OFFSET) & 0x0F;

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

@@ -686,18 +668,16 @@ int lx_stream_set_state(struct lx6464es *chip, u32 pipe,
			       int is_capture, enum stream_state_t state)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_13_SET_STREAM_STATE);

	chip->rmh.cmd[0] |= pipe_cmd;
	chip->rmh.cmd[0] |= state;

	err = lx_message_send_atomic(chip, &chip->rmh);
	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);

	return err;
}
@@ -706,17 +686,14 @@ int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
			 u32 pipe, int is_capture)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	u32 channels = runtime->channels;

	if (runtime->channels != channels)
		dev_err(chip->card->dev, "channel count mismatch: %d vs %d",
			   runtime->channels, channels);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_0C_DEF_STREAM);

	chip->rmh.cmd[0] |= pipe_cmd;
@@ -732,7 +709,7 @@ int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
	chip->rmh.cmd[0] |= channels-1;

	err = lx_message_send_atomic(chip, &chip->rmh);
	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);

	return err;
}
@@ -741,11 +718,9 @@ int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,
		    int *rstate)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT);

	chip->rmh.cmd[0] |= pipe_cmd;
@@ -754,7 +729,7 @@ int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,

	*rstate = (chip->rmh.stat[0] & SF_START) ? START_STATE : PAUSE_STATE;

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

@@ -762,11 +737,9 @@ int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture,
			      u64 *r_bytepos)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT);

	chip->rmh.cmd[0] |= pipe_cmd;
@@ -777,7 +750,7 @@ int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture,
		      << 32)	     /* hi part */
		+ chip->rmh.stat[1]; /* lo part */

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

@@ -787,11 +760,9 @@ int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture,
		   u32 *r_buffer_index)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_0F_UPDATE_BUFFER);

	chip->rmh.cmd[0] |= pipe_cmd;
@@ -828,7 +799,7 @@ int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture,
			"lx_buffer_give EB_CMD_REFUSED\n");

 done:
	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

@@ -836,11 +807,9 @@ int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture,
		   u32 *r_buffer_size)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER);

	chip->rmh.cmd[0] |= pipe_cmd;
@@ -852,7 +821,7 @@ int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture,
	if (err == 0)
		*r_buffer_size = chip->rmh.stat[0]  & MASK_DATA_SIZE;

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

@@ -860,11 +829,9 @@ int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture,
		     u32 buffer_index)
{
	int err;
	unsigned long flags;

	u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER);

	chip->rmh.cmd[0] |= pipe_cmd;
@@ -872,7 +839,7 @@ int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture,

	err = lx_message_send_atomic(chip, &chip->rmh);

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

@@ -885,12 +852,10 @@ int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture,
int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute)
{
	int err;
	unsigned long flags;

	/* bit set to 1: channel muted */
	u64 mute_mask = unmute ? 0 : 0xFFFFFFFFFFFFFFFFLLU;

	spin_lock_irqsave(&chip->msg_lock, flags);
	mutex_lock(&chip->msg_lock);
	lx_message_init(&chip->rmh, CMD_0D_SET_MUTE);

	chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, 0);
@@ -904,7 +869,7 @@ int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute)

	err = lx_message_send_atomic(chip, &chip->rmh);

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

@@ -931,10 +896,9 @@ int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels,
		   u32 *r_levels)
{
	int err = 0;
	unsigned long flags;
	int i;
	spin_lock_irqsave(&chip->msg_lock, flags);

	mutex_lock(&chip->msg_lock);
	for (i = 0; i < channels; i += 4) {
		u32 s0, s1, s2, s3;

@@ -959,7 +923,7 @@ int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels,
		r_levels += 4;
	}

	spin_unlock_irqrestore(&chip->msg_lock, flags);
	mutex_unlock(&chip->msg_lock);
	return err;
}

@@ -1075,7 +1039,6 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip,
	struct snd_pcm_substream *substream = lx_stream->stream;
	const unsigned int is_capture = lx_stream->is_capture;
	int err;
	unsigned long flags;

	const u32 channels = substream->runtime->channels;
	const u32 bytes_per_frame = channels * 3;
@@ -1095,7 +1058,7 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip,

	dev_dbg(chip->card->dev, "->lx_interrupt_request_new_buffer\n");

	spin_lock_irqsave(&chip->lock, flags);
	mutex_lock(&chip->lock);

	err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array);
	dev_dbg(chip->card->dev,
@@ -1109,85 +1072,28 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip,
		    buffer_index, (unsigned long)buf, period_bytes);

	lx_stream->frame_pos = next_pos;
	spin_unlock_irqrestore(&chip->lock, flags);

	return err;
}

void lx_tasklet_playback(unsigned long data)
{
	struct lx6464es *chip = (struct lx6464es *)data;
	struct lx_stream *lx_stream = &chip->playback_stream;
	int err;

	dev_dbg(chip->card->dev, "->lx_tasklet_playback\n");

	err = lx_interrupt_request_new_buffer(chip, lx_stream);
	if (err < 0)
		dev_err(chip->card->dev,
			   "cannot request new buffer for playback\n");

	snd_pcm_period_elapsed(lx_stream->stream);
}

void lx_tasklet_capture(unsigned long data)
{
	struct lx6464es *chip = (struct lx6464es *)data;
	struct lx_stream *lx_stream = &chip->capture_stream;
	int err;

	dev_dbg(chip->card->dev, "->lx_tasklet_capture\n");
	err = lx_interrupt_request_new_buffer(chip, lx_stream);
	if (err < 0)
		dev_err(chip->card->dev,
			   "cannot request new buffer for capture\n");

	snd_pcm_period_elapsed(lx_stream->stream);
}



static int lx_interrupt_handle_audio_transfer(struct lx6464es *chip,
					      u64 notified_in_pipe_mask,
					      u64 notified_out_pipe_mask)
{
	int err = 0;

	if (notified_in_pipe_mask) {
		dev_dbg(chip->card->dev,
			"requesting audio transfer for capture\n");
		tasklet_hi_schedule(&chip->tasklet_capture);
	}

	if (notified_out_pipe_mask) {
		dev_dbg(chip->card->dev,
			"requesting audio transfer for playback\n");
		tasklet_hi_schedule(&chip->tasklet_playback);
	}
	mutex_unlock(&chip->lock);

	return err;
}


irqreturn_t lx_interrupt(int irq, void *dev_id)
{
	struct lx6464es *chip = dev_id;
	int async_pending, async_escmd;
	u32 irqsrc;

	spin_lock(&chip->lock);
	bool wake_thread = false;

	dev_dbg(chip->card->dev,
		"**************************************************\n");

	if (!lx_interrupt_ack(chip, &irqsrc, &async_pending, &async_escmd)) {
		spin_unlock(&chip->lock);
		dev_dbg(chip->card->dev, "IRQ_NONE\n");
		return IRQ_NONE; /* this device did not cause the interrupt */
	}

	if (irqsrc & MASK_SYS_STATUS_CMD_DONE)
		goto exit;
		return IRQ_HANDLED;

	if (irqsrc & MASK_SYS_STATUS_EOBI)
		dev_dbg(chip->card->dev, "interrupt: EOBI\n");
@@ -1202,42 +1108,64 @@ irqreturn_t lx_interrupt(int irq, void *dev_id)
		dev_dbg(chip->card->dev, "interrupt: ORUN\n");

	if (async_pending) {
		wake_thread = true;
		chip->irqsrc = irqsrc;
	}

	if (async_escmd) {
		/* backdoor for ethersound commands
		 *
		 * for now, we do not need this
		 *
		 * */

		dev_dbg(chip->card->dev, "interrupt requests escmd handling\n");
	}

	return wake_thread ? IRQ_WAKE_THREAD : IRQ_HANDLED;
}

irqreturn_t lx_threaded_irq(int irq, void *dev_id)
{
	struct lx6464es *chip = dev_id;
	u64 notified_in_pipe_mask = 0;
	u64 notified_out_pipe_mask = 0;
	int freq_changed;
	int err;

	/* handle async events */
		err = lx_interrupt_handle_async_events(chip, irqsrc,
	err = lx_interrupt_handle_async_events(chip, chip->irqsrc,
					       &freq_changed,
					       &notified_in_pipe_mask,
					       &notified_out_pipe_mask);
	if (err)
			dev_err(chip->card->dev,
				   "error handling async events\n");
		dev_err(chip->card->dev, "error handling async events\n");

		err = lx_interrupt_handle_audio_transfer(chip,
							 notified_in_pipe_mask,
							 notified_out_pipe_mask
			);
		if (err)
	if (notified_in_pipe_mask) {
		struct lx_stream *lx_stream = &chip->capture_stream;

		dev_dbg(chip->card->dev,
			"requesting audio transfer for capture\n");
		err = lx_interrupt_request_new_buffer(chip, lx_stream);
		if (err < 0)
			dev_err(chip->card->dev,
				   "error during audio transfer\n");
				"cannot request new buffer for capture\n");
		snd_pcm_period_elapsed(lx_stream->stream);
	}

	if (async_escmd) {
		/* backdoor for ethersound commands
		 *
		 * for now, we do not need this
		 *
		 * */
	if (notified_out_pipe_mask) {
		struct lx_stream *lx_stream = &chip->playback_stream;

		dev_dbg(chip->card->dev, "interrupt requests escmd handling\n");
		dev_dbg(chip->card->dev,
			"requesting audio transfer for playback\n");
		err = lx_interrupt_request_new_buffer(chip, lx_stream);
		if (err < 0)
			dev_err(chip->card->dev,
				"cannot request new buffer for playback\n");
		snd_pcm_period_elapsed(lx_stream->stream);
	}

exit:
	spin_unlock(&chip->lock);
	return IRQ_HANDLED;	/* this device caused the interrupt */
	return IRQ_HANDLED;
}


+1 −3
Original line number Diff line number Diff line
@@ -181,12 +181,10 @@ int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels,

/* interrupt handling */
irqreturn_t lx_interrupt(int irq, void *dev_id);
irqreturn_t lx_threaded_irq(int irq, void *dev_id);
void lx_irq_enable(struct lx6464es *chip);
void lx_irq_disable(struct lx6464es *chip);

void lx_tasklet_capture(unsigned long data);
void lx_tasklet_playback(unsigned long data);


/* Stream Format Header Defines (for LIN and IEEE754) */
#define HEADER_FMT_BASE		HEADER_FMT_BASE_LIN