aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Wu <bryan.wu@analog.com>2007-12-05 02:45:20 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-12-05 12:21:20 -0500
commit62310e51ac10c5e50998240e49a84d2e28377a48 (patch)
treebdb678ea08edb8bbe83ac77bd4432e1d1721e44e
parentc3061abb9e95920407288cba143dc1af0babf099 (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>
-rw-r--r--drivers/spi/spi_bfin5xx.c24
-rw-r--r--include/asm-blackfin/bfin5xx_spi.h2
2 files changed, 10 insertions, 16 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 }
diff --git a/include/asm-blackfin/bfin5xx_spi.h b/include/asm-blackfin/bfin5xx_spi.h
index f617d8765451..d4485b37d8e2 100644
--- a/include/asm-blackfin/bfin5xx_spi.h
+++ b/include/asm-blackfin/bfin5xx_spi.h
@@ -162,7 +162,7 @@ struct bfin5xx_spi_chip {
162 u8 enable_dma; 162 u8 enable_dma;
163 u8 bits_per_word; 163 u8 bits_per_word;
164 u8 cs_change_per_word; 164 u8 cs_change_per_word;
165 u8 cs_chg_udelay; 165 u16 cs_chg_udelay; /* Some devices require 16-bit delays */
166}; 166};
167 167
168#endif /* _SPI_CHANNEL_H_ */ 168#endif /* _SPI_CHANNEL_H_ */