diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-07-06 21:49:35 +0100 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-07-06 21:49:35 +0100 |
commit | 4ec5c9693b46ab34976511cd43bf75c3a0fc704d (patch) | |
tree | 0d00f934a0c4544fa6430e8a38c2e2fb7a6ddba0 /sound/soc/fsl/mpc5200_psc_ac97.c | |
parent | 1e30a5828e4e9e49fcc6e471bf0d99d4fd273ba4 (diff) | |
parent | 637a935aaba2f05e2178c9d1b714d7a2c36c8b44 (diff) | |
download | blackbird-op-linux-4ec5c9693b46ab34976511cd43bf75c3a0fc704d.tar.gz blackbird-op-linux-4ec5c9693b46ab34976511cd43bf75c3a0fc704d.zip |
Merge branch 'for-2.6.31' into for-2.6.32
Diffstat (limited to 'sound/soc/fsl/mpc5200_psc_ac97.c')
-rw-r--r-- | sound/soc/fsl/mpc5200_psc_ac97.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 794a247b3eb5..7eb549985d49 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -34,13 +34,20 @@ 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; } + + /* Force clear the data valid bit */ + in_be32(&psc_dma->psc_regs->ac97_data); + /* Send the read */ out_be32(&psc_dma->psc_regs->ac97_cmd, (1<<31) | ((reg & 0x7f) << 24)); @@ -50,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; } @@ -68,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) |