diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2015-08-16 23:52:54 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-09-17 07:13:40 -0400 |
commit | c15f6ed3a18f10cdc33f64906ab353f17a6df114 (patch) | |
tree | d31632b7d325d16e602437062832c01eabae2451 /drivers/spi/spi-bitbang.c | |
parent | 6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f (diff) |
spi: bitbang: Replace spinlock by mutex
chipselect (in the case of spi-gpio: spi_gpio_chipselect, which
calls gpiod_set_raw_value_cansleep) can sleep, so we should not
hold a spinlock while calling it from spi_bitbang_setup.
This issue was introduced by this commit, which converted spi-gpio
to cansleep variants:
d9dda5a191 "spi: spi-gpio: Use 'cansleep' variants to access GPIO"
Replacing the lock variable by a mutex fixes the issue: This is
safe as all instances where the lock is used are called from
contexts that can sleep.
Finally, update spi-ppc4xx and and spi-s3c24xx to use mutex
functions, as they directly hold the lock for similar purpose.
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-bitbang.c')
-rw-r--r-- | drivers/spi/spi-bitbang.c | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 840a4984d365..ef43ef507c9a 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c | |||
@@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi) | |||
180 | { | 180 | { |
181 | struct spi_bitbang_cs *cs = spi->controller_state; | 181 | struct spi_bitbang_cs *cs = spi->controller_state; |
182 | struct spi_bitbang *bitbang; | 182 | struct spi_bitbang *bitbang; |
183 | unsigned long flags; | ||
184 | 183 | ||
185 | bitbang = spi_master_get_devdata(spi->master); | 184 | bitbang = spi_master_get_devdata(spi->master); |
186 | 185 | ||
@@ -210,12 +209,12 @@ int spi_bitbang_setup(struct spi_device *spi) | |||
210 | */ | 209 | */ |
211 | 210 | ||
212 | /* deselect chip (low or high) */ | 211 | /* deselect chip (low or high) */ |
213 | spin_lock_irqsave(&bitbang->lock, flags); | 212 | mutex_lock(&bitbang->lock); |
214 | if (!bitbang->busy) { | 213 | if (!bitbang->busy) { |
215 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); | 214 | bitbang->chipselect(spi, BITBANG_CS_INACTIVE); |
216 | ndelay(cs->nsecs); | 215 | ndelay(cs->nsecs); |
217 | } | 216 | } |
218 | spin_unlock_irqrestore(&bitbang->lock, flags); | 217 | mutex_unlock(&bitbang->lock); |
219 | 218 | ||
220 | return 0; | 219 | return 0; |
221 | } | 220 | } |
@@ -255,13 +254,12 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
255 | static int spi_bitbang_prepare_hardware(struct spi_master *spi) | 254 | static int spi_bitbang_prepare_hardware(struct spi_master *spi) |
256 | { | 255 | { |
257 | struct spi_bitbang *bitbang; | 256 | struct spi_bitbang *bitbang; |
258 | unsigned long flags; | ||
259 | 257 | ||
260 | bitbang = spi_master_get_devdata(spi); | 258 | bitbang = spi_master_get_devdata(spi); |
261 | 259 | ||
262 | spin_lock_irqsave(&bitbang->lock, flags); | 260 | mutex_lock(&bitbang->lock); |
263 | bitbang->busy = 1; | 261 | bitbang->busy = 1; |
264 | spin_unlock_irqrestore(&bitbang->lock, flags); | 262 | mutex_unlock(&bitbang->lock); |
265 | 263 | ||
266 | return 0; | 264 | return 0; |
267 | } | 265 | } |
@@ -378,13 +376,12 @@ static int spi_bitbang_transfer_one(struct spi_master *master, | |||
378 | static int spi_bitbang_unprepare_hardware(struct spi_master *spi) | 376 | static int spi_bitbang_unprepare_hardware(struct spi_master *spi) |
379 | { | 377 | { |
380 | struct spi_bitbang *bitbang; | 378 | struct spi_bitbang *bitbang; |
381 | unsigned long flags; | ||
382 | 379 | ||
383 | bitbang = spi_master_get_devdata(spi); | 380 | bitbang = spi_master_get_devdata(spi); |
384 | 381 | ||
385 | spin_lock_irqsave(&bitbang->lock, flags); | 382 | mutex_lock(&bitbang->lock); |
386 | bitbang->busy = 0; | 383 | bitbang->busy = 0; |
387 | spin_unlock_irqrestore(&bitbang->lock, flags); | 384 | mutex_unlock(&bitbang->lock); |
388 | 385 | ||
389 | return 0; | 386 | return 0; |
390 | } | 387 | } |
@@ -427,7 +424,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) | |||
427 | if (!master || !bitbang->chipselect) | 424 | if (!master || !bitbang->chipselect) |
428 | return -EINVAL; | 425 | return -EINVAL; |
429 | 426 | ||
430 | spin_lock_init(&bitbang->lock); | 427 | mutex_init(&bitbang->lock); |
431 | 428 | ||
432 | if (!master->mode_bits) | 429 | if (!master->mode_bits) |
433 | master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; | 430 | master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; |