diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2009-07-02 13:57:25 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-07-03 05:41:47 -0400 |
commit | 0827d6ba0b76be398a3c4298afd41f4965d2cdcb (patch) | |
tree | e0346a66b752b89381103ee50008d532d207262e | |
parent | 07573534b0b030226ee5ab560e53aac7e6c0dd84 (diff) |
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: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Jon Smirl <jonsmirl@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | sound/soc/fsl/mpc5200_dma.c | 1 | ||||
-rw-r--r-- | sound/soc/fsl/mpc5200_dma.h | 1 | ||||
-rw-r--r-- | sound/soc/fsl/mpc5200_psc_ac97.c | 13 |
3 files changed, 14 insertions, 1 deletions
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index efec33a1c5bd..f0a2d4071998 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c | |||
@@ -456,6 +456,7 @@ int mpc5200_audio_dma_create(struct of_device *op) | |||
456 | return -ENODEV; | 456 | return -ENODEV; |
457 | 457 | ||
458 | spin_lock_init(&psc_dma->lock); | 458 | spin_lock_init(&psc_dma->lock); |
459 | mutex_init(&psc_dma->mutex); | ||
459 | psc_dma->id = be32_to_cpu(*prop); | 460 | psc_dma->id = be32_to_cpu(*prop); |
460 | psc_dma->irq = irq; | 461 | psc_dma->irq = irq; |
461 | psc_dma->psc_regs = regs; | 462 | psc_dma->psc_regs = regs; |
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index 2000803f06a7..8d396bb9d9fe 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h | |||
@@ -55,6 +55,7 @@ struct psc_dma { | |||
55 | unsigned int irq; | 55 | unsigned int irq; |
56 | struct device *dev; | 56 | struct device *dev; |
57 | spinlock_t lock; | 57 | spinlock_t lock; |
58 | struct mutex mutex; | ||
58 | u32 sicr; | 59 | u32 sicr; |
59 | uint sysclk; | 60 | uint sysclk; |
60 | int imr; | 61 | int imr; |
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 9b8503f2d68c..7eb549985d49 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c | |||
@@ -34,11 +34,14 @@ 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 | } |
44 | 47 | ||
@@ -54,16 +57,19 @@ static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
54 | if (status == 0) { | 57 | if (status == 0) { |
55 | pr_err("timeout on ac97 read (val) %x\n", | 58 | pr_err("timeout on ac97 read (val) %x\n", |
56 | 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); | ||
57 | return -ENODEV; | 61 | return -ENODEV; |
58 | } | 62 | } |
59 | /* Get the data */ | 63 | /* Get the data */ |
60 | val = in_be32(&psc_dma->psc_regs->ac97_data); | 64 | val = in_be32(&psc_dma->psc_regs->ac97_data); |
61 | if (((val >> 24) & 0x7f) != reg) { | 65 | if (((val >> 24) & 0x7f) != reg) { |
62 | 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); | ||
63 | return -ENODEV; | 68 | return -ENODEV; |
64 | } | 69 | } |
65 | val = (val >> 8) & 0xffff; | 70 | val = (val >> 8) & 0xffff; |
66 | 71 | ||
72 | mutex_unlock(&psc_dma->mutex); | ||
67 | return (unsigned short) val; | 73 | return (unsigned short) val; |
68 | } | 74 | } |
69 | 75 | ||
@@ -72,16 +78,21 @@ static void psc_ac97_write(struct snd_ac97 *ac97, | |||
72 | { | 78 | { |
73 | int status; | 79 | int status; |
74 | 80 | ||
81 | mutex_lock(&psc_dma->mutex); | ||
82 | |||
75 | /* Wait for command status zero = ready */ | 83 | /* Wait for command status zero = ready */ |
76 | 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) & |
77 | MPC52xx_PSC_SR_CMDSEND), 100, 0); | 85 | MPC52xx_PSC_SR_CMDSEND), 100, 0); |
78 | if (status == 0) { | 86 | if (status == 0) { |
79 | pr_err("timeout on ac97 bus (write)\n"); | 87 | pr_err("timeout on ac97 bus (write)\n"); |
80 | return; | 88 | goto out; |
81 | } | 89 | } |
82 | /* Write data */ | 90 | /* Write data */ |
83 | out_be32(&psc_dma->psc_regs->ac97_cmd, | 91 | out_be32(&psc_dma->psc_regs->ac97_cmd, |
84 | ((reg & 0x7f) << 24) | (val << 8)); | 92 | ((reg & 0x7f) << 24) | (val << 8)); |
93 | |||
94 | out: | ||
95 | mutex_unlock(&psc_dma->mutex); | ||
85 | } | 96 | } |
86 | 97 | ||
87 | static void psc_ac97_warm_reset(struct snd_ac97 *ac97) | 98 | static void psc_ac97_warm_reset(struct snd_ac97 *ac97) |