diff options
author | Bryan Wu <bryan.wu@analog.com> | 2007-12-05 02:45:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-05 12:21:20 -0500 |
commit | 62310e51ac10c5e50998240e49a84d2e28377a48 (patch) | |
tree | bdb678ea08edb8bbe83ac77bd4432e1d1721e44e /drivers/spi | |
parent | c3061abb9e95920407288cba143dc1af0babf099 (diff) |
spi: spi_bfin: update handling of delay-after-deselect
Move cs_chg_udelay handling (specific to this driver) to cs_deactive(), fixing
a bug when some SPI LCD driver needs delay after cs_deactive.
Fix bug reported by Cameron Barfield <cbarfield@cyberdata.net>
https://blackfin.uclinux.org/gf/project/uclinux-dist/forum/?action=ForumBrowse&forum_id=39&_forum_action=ForumMessageBrowse&thread_id=23630&feedback=Message%20replied.
Cc: Cameron Barfield <cbarfield@cyberdata.net>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi_bfin5xx.c | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 25b0efc5910e..4dc7e6749322 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -132,7 +132,7 @@ struct chip_data { | |||
132 | u8 enable_dma; | 132 | u8 enable_dma; |
133 | u8 bits_per_word; /* 8 or 16 */ | 133 | u8 bits_per_word; /* 8 or 16 */ |
134 | u8 cs_change_per_word; | 134 | u8 cs_change_per_word; |
135 | u8 cs_chg_udelay; | 135 | u16 cs_chg_udelay; /* Some devices require > 255usec delay */ |
136 | void (*write) (struct driver_data *); | 136 | void (*write) (struct driver_data *); |
137 | void (*read) (struct driver_data *); | 137 | void (*read) (struct driver_data *); |
138 | void (*duplex) (struct driver_data *); | 138 | void (*duplex) (struct driver_data *); |
@@ -211,6 +211,10 @@ static void cs_deactive(struct driver_data *drv_data, struct chip_data *chip) | |||
211 | flag |= (chip->flag << 8); | 211 | flag |= (chip->flag << 8); |
212 | 212 | ||
213 | write_FLAG(drv_data, flag); | 213 | write_FLAG(drv_data, flag); |
214 | |||
215 | /* Move delay here for consistency */ | ||
216 | if (chip->cs_chg_udelay) | ||
217 | udelay(chip->cs_chg_udelay); | ||
214 | } | 218 | } |
215 | 219 | ||
216 | #define MAX_SPI_SSEL 7 | 220 | #define MAX_SPI_SSEL 7 |
@@ -307,10 +311,9 @@ static void u8_cs_chg_writer(struct driver_data *drv_data) | |||
307 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 311 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); |
308 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 312 | while (read_STAT(drv_data) & BIT_STAT_TXS) |
309 | continue; | 313 | continue; |
314 | |||
310 | cs_deactive(drv_data, chip); | 315 | cs_deactive(drv_data, chip); |
311 | 316 | ||
312 | if (chip->cs_chg_udelay) | ||
313 | udelay(chip->cs_chg_udelay); | ||
314 | ++drv_data->tx; | 317 | ++drv_data->tx; |
315 | } | 318 | } |
316 | } | 319 | } |
@@ -359,9 +362,6 @@ static void u8_cs_chg_reader(struct driver_data *drv_data) | |||
359 | while (drv_data->rx < drv_data->rx_end - 1) { | 362 | while (drv_data->rx < drv_data->rx_end - 1) { |
360 | cs_deactive(drv_data, chip); | 363 | cs_deactive(drv_data, chip); |
361 | 364 | ||
362 | if (chip->cs_chg_udelay) | ||
363 | udelay(chip->cs_chg_udelay); | ||
364 | |||
365 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 365 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
366 | continue; | 366 | continue; |
367 | cs_active(drv_data, chip); | 367 | cs_active(drv_data, chip); |
@@ -412,10 +412,9 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data) | |||
412 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 412 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
413 | continue; | 413 | continue; |
414 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 414 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); |
415 | |||
415 | cs_deactive(drv_data, chip); | 416 | cs_deactive(drv_data, chip); |
416 | 417 | ||
417 | if (chip->cs_chg_udelay) | ||
418 | udelay(chip->cs_chg_udelay); | ||
419 | ++drv_data->rx; | 418 | ++drv_data->rx; |
420 | ++drv_data->tx; | 419 | ++drv_data->tx; |
421 | } | 420 | } |
@@ -452,10 +451,9 @@ static void u16_cs_chg_writer(struct driver_data *drv_data) | |||
452 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 451 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
453 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) | 452 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) |
454 | continue; | 453 | continue; |
454 | |||
455 | cs_deactive(drv_data, chip); | 455 | cs_deactive(drv_data, chip); |
456 | 456 | ||
457 | if (chip->cs_chg_udelay) | ||
458 | udelay(chip->cs_chg_udelay); | ||
459 | drv_data->tx += 2; | 457 | drv_data->tx += 2; |
460 | } | 458 | } |
461 | } | 459 | } |
@@ -504,9 +502,6 @@ static void u16_cs_chg_reader(struct driver_data *drv_data) | |||
504 | while (drv_data->rx < drv_data->rx_end - 2) { | 502 | while (drv_data->rx < drv_data->rx_end - 2) { |
505 | cs_deactive(drv_data, chip); | 503 | cs_deactive(drv_data, chip); |
506 | 504 | ||
507 | if (chip->cs_chg_udelay) | ||
508 | udelay(chip->cs_chg_udelay); | ||
509 | |||
510 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 505 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
511 | continue; | 506 | continue; |
512 | cs_active(drv_data, chip); | 507 | cs_active(drv_data, chip); |
@@ -557,10 +552,9 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data) | |||
557 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 552 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
558 | continue; | 553 | continue; |
559 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 554 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); |
555 | |||
560 | cs_deactive(drv_data, chip); | 556 | cs_deactive(drv_data, chip); |
561 | 557 | ||
562 | if (chip->cs_chg_udelay) | ||
563 | udelay(chip->cs_chg_udelay); | ||
564 | drv_data->rx += 2; | 558 | drv_data->rx += 2; |
565 | drv_data->tx += 2; | 559 | drv_data->tx += 2; |
566 | } | 560 | } |