diff options
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) | |||
34 | int status; | 34 | int status; |
35 | unsigned int val; | 35 | unsigned int val; |
36 | 36 | ||
37 | mutex_lock(&psc_dma->mutex); | ||
38 | |||
37 | /* Wait for command send status zero = ready */ | 39 | /* Wait for command send status zero = ready */ |
38 | status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & | 40 | status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & |
39 | MPC52xx_PSC_SR_CMDSEND), 100, 0); | 41 | MPC52xx_PSC_SR_CMDSEND), 100, 0); |
40 | if (status == 0) { | 42 | if (status == 0) { |
41 | pr_err("timeout on ac97 bus (rdy)\n"); | 43 | pr_err("timeout on ac97 bus (rdy)\n"); |
44 | mutex_unlock(&psc_dma->mutex); | ||
42 | return -ENODEV; | 45 | return -ENODEV; |
43 | } | 46 | } |
47 | |||
48 | /* Force clear the data valid bit */ | ||
49 | in_be32(&psc_dma->psc_regs->ac97_data); | ||
50 | |||
44 | /* Send the read */ | 51 | /* Send the read */ |
45 | out_be32(&psc_dma->psc_regs->ac97_cmd, (1<<31) | ((reg & 0x7f) << 24)); | 52 | out_be32(&psc_dma->psc_regs->ac97_cmd, (1<<31) | ((reg & 0x7f) << 24)); |
46 | 53 | ||
@@ -50,16 +57,19 @@ static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
50 | if (status == 0) { | 57 | if (status == 0) { |
51 | pr_err("timeout on ac97 read (val) %x\n", | 58 | pr_err("timeout on ac97 read (val) %x\n", |
52 | in_be16(&psc_dma->psc_regs->sr_csr.status)); | 59 | in_be16(&psc_dma->psc_regs->sr_csr.status)); |
60 | mutex_unlock(&psc_dma->mutex); | ||
53 | return -ENODEV; | 61 | return -ENODEV; |
54 | } | 62 | } |
55 | /* Get the data */ | 63 | /* Get the data */ |
56 | val = in_be32(&psc_dma->psc_regs->ac97_data); | 64 | val = in_be32(&psc_dma->psc_regs->ac97_data); |
57 | if (((val >> 24) & 0x7f) != reg) { | 65 | if (((val >> 24) & 0x7f) != reg) { |
58 | pr_err("reg echo error on ac97 read\n"); | 66 | pr_err("reg echo error on ac97 read\n"); |
67 | mutex_unlock(&psc_dma->mutex); | ||
59 | return -ENODEV; | 68 | return -ENODEV; |
60 | } | 69 | } |
61 | val = (val >> 8) & 0xffff; | 70 | val = (val >> 8) & 0xffff; |
62 | 71 | ||
72 | mutex_unlock(&psc_dma->mutex); | ||
63 | return (unsigned short) val; | 73 | return (unsigned short) val; |
64 | } | 74 | } |
65 | 75 | ||
@@ -68,16 +78,21 @@ static void psc_ac97_write(struct snd_ac97 *ac97, | |||
68 | { | 78 | { |
69 | int status; | 79 | int status; |
70 | 80 | ||
81 | mutex_lock(&psc_dma->mutex); | ||
82 | |||
71 | /* Wait for command status zero = ready */ | 83 | /* Wait for command status zero = ready */ |
72 | status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & | 84 | status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & |
73 | MPC52xx_PSC_SR_CMDSEND), 100, 0); | 85 | MPC52xx_PSC_SR_CMDSEND), 100, 0); |
74 | if (status == 0) { | 86 | if (status == 0) { |
75 | pr_err("timeout on ac97 bus (write)\n"); | 87 | pr_err("timeout on ac97 bus (write)\n"); |
76 | return; | 88 | goto out; |
77 | } | 89 | } |
78 | /* Write data */ | 90 | /* Write data */ |
79 | out_be32(&psc_dma->psc_regs->ac97_cmd, | 91 | out_be32(&psc_dma->psc_regs->ac97_cmd, |
80 | ((reg & 0x7f) << 24) | (val << 8)); | 92 | ((reg & 0x7f) << 24) | (val << 8)); |
93 | |||
94 | out: | ||
95 | mutex_unlock(&psc_dma->mutex); | ||
81 | } | 96 | } |
82 | 97 | ||
83 | static void psc_ac97_warm_reset(struct snd_ac97 *ac97) | 98 | static void psc_ac97_warm_reset(struct snd_ac97 *ac97) |