|
15 | 15 | #include <linux/clk.h>
|
16 | 16 | #include <linux/pm_runtime.h>
|
17 | 17 | #include <linux/regmap.h>
|
| 18 | +#include <linux/spinlock.h> |
18 | 19 | #include <sound/pcm_params.h>
|
19 | 20 | #include <sound/dmaengine_pcm.h>
|
20 | 21 |
|
@@ -53,6 +54,7 @@ struct rk_i2s_dev {
|
53 | 54 | bool is_master_mode;
|
54 | 55 | const struct rk_i2s_pins *pins;
|
55 | 56 | unsigned int bclk_ratio;
|
| 57 | + spinlock_t lock; /* tx/rx lock */ |
56 | 58 | };
|
57 | 59 |
|
58 | 60 | static int i2s_runtime_suspend(struct device *dev)
|
@@ -96,6 +98,7 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
|
96 | 98 | unsigned int val = 0;
|
97 | 99 | int retry = 10;
|
98 | 100 |
|
| 101 | + spin_lock(&i2s->lock); |
99 | 102 | if (on) {
|
100 | 103 | regmap_update_bits(i2s->regmap, I2S_DMACR,
|
101 | 104 | I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
|
@@ -136,13 +139,15 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
|
136 | 139 | }
|
137 | 140 | }
|
138 | 141 | }
|
| 142 | + spin_unlock(&i2s->lock); |
139 | 143 | }
|
140 | 144 |
|
141 | 145 | static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
|
142 | 146 | {
|
143 | 147 | unsigned int val = 0;
|
144 | 148 | int retry = 10;
|
145 | 149 |
|
| 150 | + spin_lock(&i2s->lock); |
146 | 151 | if (on) {
|
147 | 152 | regmap_update_bits(i2s->regmap, I2S_DMACR,
|
148 | 153 | I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
|
@@ -183,6 +188,7 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
|
183 | 188 | }
|
184 | 189 | }
|
185 | 190 | }
|
| 191 | + spin_unlock(&i2s->lock); |
186 | 192 | }
|
187 | 193 |
|
188 | 194 | static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
|
@@ -684,6 +690,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
|
684 | 690 | if (!i2s)
|
685 | 691 | return -ENOMEM;
|
686 | 692 |
|
| 693 | + spin_lock_init(&i2s->lock); |
687 | 694 | i2s->dev = &pdev->dev;
|
688 | 695 |
|
689 | 696 | i2s->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
|
|
0 commit comments