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

Commit 0c9af280 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'fix/misc' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: lx6464es - remove unused struct member
  ALSA: lx6464es - cleanup of rmh message bus function
  ALSA: pcm - Simplify snd_pcm_drain() implementation
parents fe61c99a 8fdc9e87
Loading
Loading
Loading
Loading
+20 −53
Original line number Diff line number Diff line
@@ -1387,11 +1387,6 @@ static struct action_ops snd_pcm_action_drain_init = {
	.post_action = snd_pcm_post_drain_init
};

struct drain_rec {
	struct snd_pcm_substream *substream;
	wait_queue_t wait;
};

static int snd_pcm_drop(struct snd_pcm_substream *substream);

/*
@@ -1407,10 +1402,9 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
	struct snd_card *card;
	struct snd_pcm_runtime *runtime;
	struct snd_pcm_substream *s;
	wait_queue_t wait;
	int result = 0;
	int i, num_drecs;
	int nonblock = 0;
	struct drain_rec *drec, drec_tmp, *d;

	card = substream->pcm->card;
	runtime = substream->runtime;
@@ -1433,38 +1427,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
	} else if (substream->f_flags & O_NONBLOCK)
		nonblock = 1;

	if (nonblock)
		goto lock; /* no need to allocate waitqueues */

	/* allocate temporary record for drain sync */
	down_read(&snd_pcm_link_rwsem);
	if (snd_pcm_stream_linked(substream)) {
		drec = kmalloc(substream->group->count * sizeof(*drec), GFP_KERNEL);
		if (! drec) {
			up_read(&snd_pcm_link_rwsem);
			snd_power_unlock(card);
			return -ENOMEM;
		}
	} else
		drec = &drec_tmp;

	/* count only playback streams */
	num_drecs = 0;
	snd_pcm_group_for_each_entry(s, substream) {
		runtime = s->runtime;
		if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			d = &drec[num_drecs++];
			d->substream = s;
			init_waitqueue_entry(&d->wait, current);
			add_wait_queue(&runtime->sleep, &d->wait);
		}
	}
	up_read(&snd_pcm_link_rwsem);

 lock:
	snd_pcm_stream_lock_irq(substream);
	/* resume pause */
	if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED)
	if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
		snd_pcm_pause(substream, 0);

	/* pre-start/stop - all running streams are changed to DRAINING state */
@@ -1479,25 +1445,35 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,

	for (;;) {
		long tout;
		struct snd_pcm_runtime *to_check;
		if (signal_pending(current)) {
			result = -ERESTARTSYS;
			break;
		}
		/* all finished? */
		for (i = 0; i < num_drecs; i++) {
			runtime = drec[i].substream->runtime;
			if (runtime->status->state == SNDRV_PCM_STATE_DRAINING)
		/* find a substream to drain */
		to_check = NULL;
		snd_pcm_group_for_each_entry(s, substream) {
			if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
				continue;
			runtime = s->runtime;
			if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
				to_check = runtime;
				break;
			}
		if (i == num_drecs)
			break; /* yes, all drained */

		}
		if (!to_check)
			break; /* all drained */
		init_waitqueue_entry(&wait, current);
		add_wait_queue(&to_check->sleep, &wait);
		set_current_state(TASK_INTERRUPTIBLE);
		snd_pcm_stream_unlock_irq(substream);
		up_read(&snd_pcm_link_rwsem);
		snd_power_unlock(card);
		tout = schedule_timeout(10 * HZ);
		snd_power_lock(card);
		down_read(&snd_pcm_link_rwsem);
		snd_pcm_stream_lock_irq(substream);
		remove_wait_queue(&to_check->sleep, &wait);
		if (tout == 0) {
			if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
				result = -ESTRPIPE;
@@ -1512,16 +1488,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,

 unlock:
	snd_pcm_stream_unlock_irq(substream);

	if (!nonblock) {
		for (i = 0; i < num_drecs; i++) {
			d = &drec[i];
			runtime = d->substream->runtime;
			remove_wait_queue(&runtime->sleep, &d->wait);
		}
		if (drec != &drec_tmp)
			kfree(drec);
	}
	up_read(&snd_pcm_link_rwsem);
	snd_power_unlock(card);

	return result;
+0 −2
Original line number Diff line number Diff line
@@ -86,7 +86,6 @@ struct lx6464es {

	/* messaging */
	spinlock_t		msg_lock;          /* message spinlock */
	atomic_t	        send_message_locked;
	struct lx_rmh           rmh;

	/* configuration */
@@ -95,7 +94,6 @@ struct lx6464es {
	uint                    hardware_running[2];
	u32                     board_sample_rate; /* sample rate read from
						    * board */
	u32                     sample_rate;	   /* our sample rate */
	u16                     pcm_granularity;   /* board blocksize */

	/* dma */
+1 −97
Original line number Diff line number Diff line
@@ -314,98 +314,6 @@ static inline void lx_message_dump(struct lx_rmh *rmh)
#define XILINX_POLL_NO_SLEEP    100
#define XILINX_POLL_ITERATIONS  150

#if 0 /* not used now */
static int lx_message_send(struct lx6464es *chip, struct lx_rmh *rmh)
{
	u32 reg = ED_DSP_TIMED_OUT;
	int dwloop;
	int answer_received;

	if (lx_dsp_reg_read(chip, eReg_CSM) & (Reg_CSM_MC | Reg_CSM_MR)) {
		snd_printk(KERN_ERR LXP "PIOSendMessage eReg_CSM %x\n", reg);
		return -EBUSY;
	}

	/* write command */
	lx_dsp_reg_writebuf(chip, eReg_CRM1, rmh->cmd, rmh->cmd_len);

	snd_BUG_ON(atomic_read(&chip->send_message_locked) != 0);
	atomic_set(&chip->send_message_locked, 1);

	/* MicoBlaze gogogo */
	lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC);

	/* wait for interrupt to answer */
	for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS; ++dwloop) {
		answer_received = atomic_read(&chip->send_message_locked);
		if (answer_received == 0)
			break;
		msleep(1);
	}

	if (answer_received == 0) {
		/* in Debug mode verify Reg_CSM_MR */
		snd_BUG_ON(!(lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR));

		/* command finished, read status */
		if (rmh->dsp_stat == 0)
			reg = lx_dsp_reg_read(chip, eReg_CRM1);
		else
			reg = 0;
	} else {
		int i;
		snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send! "
			   "Interrupts disabled?\n");

		/* attente bit Reg_CSM_MR */
		for (i = 0; i != XILINX_POLL_ITERATIONS; i++) {
			if ((lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR)) {
				if (rmh->dsp_stat == 0)
					reg = lx_dsp_reg_read(chip, eReg_CRM1);
				else
					reg = 0;
				goto polling_successful;
			}

			if (i > XILINX_POLL_NO_SLEEP)
				msleep(1);
		}
		snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send! "
			   "polling failed\n");

polling_successful:
		atomic_set(&chip->send_message_locked, 0);
	}

	if ((reg & ERROR_VALUE) == 0) {
		/* read response */
		if (rmh->stat_len) {
			snd_BUG_ON(rmh->stat_len >= (REG_CRM_NUMBER-1));

			lx_dsp_reg_readbuf(chip, eReg_CRM2, rmh->stat,
					   rmh->stat_len);
		}
	} else
		snd_printk(KERN_WARNING LXP "lx_message_send: error_value %x\n",
			   reg);

	/* clear Reg_CSM_MR */
	lx_dsp_reg_write(chip, eReg_CSM, 0);

	switch (reg) {
	case ED_DSP_TIMED_OUT:
		snd_printk(KERN_WARNING LXP "lx_message_send: dsp timeout\n");
		return -ETIMEDOUT;

	case ED_DSP_CRASHED:
		snd_printk(KERN_WARNING LXP "lx_message_send: dsp crashed\n");
		return -EAGAIN;
	}

	lx_message_dump(rmh);
	return 0;
}
#endif /* not used now */

static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh)
{
@@ -423,7 +331,7 @@ static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh)
	/* MicoBlaze gogogo */
	lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC);

	/* wait for interrupt to answer */
	/* wait for device to answer */
	for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS * 1000; ++dwloop) {
		if (lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR) {
			if (rmh->dsp_stat == 0)
@@ -1175,10 +1083,6 @@ static int lx_interrupt_ack(struct lx6464es *chip, u32 *r_irqsrc,
		*r_async_escmd = 1;
	}

	if (irqsrc & MASK_SYS_STATUS_CMD_DONE)
		/* xilinx command notification */
		atomic_set(&chip->send_message_locked, 0);

	if (irq_async) {
		/* snd_printd("interrupt: async event pending\n"); */
		*r_async_pending = 1;