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

Commit 0827d6ba authored by Grant Likely's avatar Grant Likely Committed by Mark Brown
Browse files

ASoC: add locking to mpc5200-psc-ac97 driver



AC97 bus register read/write hooks need to provide locking, but the
mpc5200-psc-ac97 driver does not.  This patch adds a mutex around
the register access routines.

Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Acked-by: default avatarJon Smirl <jonsmirl@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 07573534
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -456,6 +456,7 @@ int mpc5200_audio_dma_create(struct of_device *op)
		return -ENODEV;

	spin_lock_init(&psc_dma->lock);
	mutex_init(&psc_dma->mutex);
	psc_dma->id = be32_to_cpu(*prop);
	psc_dma->irq = irq;
	psc_dma->psc_regs = regs;
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ struct psc_dma {
	unsigned int irq;
	struct device *dev;
	spinlock_t lock;
	struct mutex mutex;
	u32 sicr;
	uint sysclk;
	int imr;
+12 −1
Original line number Diff line number Diff line
@@ -34,11 +34,14 @@ static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
	int status;
	unsigned int val;

	mutex_lock(&psc_dma->mutex);

	/* Wait for command send status zero = ready */
	status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) &
				MPC52xx_PSC_SR_CMDSEND), 100, 0);
	if (status == 0) {
		pr_err("timeout on ac97 bus (rdy)\n");
		mutex_unlock(&psc_dma->mutex);
		return -ENODEV;
	}

@@ -54,16 +57,19 @@ static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
	if (status == 0) {
		pr_err("timeout on ac97 read (val) %x\n",
				in_be16(&psc_dma->psc_regs->sr_csr.status));
		mutex_unlock(&psc_dma->mutex);
		return -ENODEV;
	}
	/* Get the data */
	val = in_be32(&psc_dma->psc_regs->ac97_data);
	if (((val >> 24) & 0x7f) != reg) {
		pr_err("reg echo error on ac97 read\n");
		mutex_unlock(&psc_dma->mutex);
		return -ENODEV;
	}
	val = (val >> 8) & 0xffff;

	mutex_unlock(&psc_dma->mutex);
	return (unsigned short) val;
}

@@ -72,16 +78,21 @@ static void psc_ac97_write(struct snd_ac97 *ac97,
{
	int status;

	mutex_lock(&psc_dma->mutex);

	/* Wait for command status zero = ready */
	status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) &
				MPC52xx_PSC_SR_CMDSEND), 100, 0);
	if (status == 0) {
		pr_err("timeout on ac97 bus (write)\n");
		return;
		goto out;
	}
	/* Write data */
	out_be32(&psc_dma->psc_regs->ac97_cmd,
			((reg & 0x7f) << 24) | (val << 8));

 out:
	mutex_unlock(&psc_dma->mutex);
}

static void psc_ac97_warm_reset(struct snd_ac97 *ac97)