aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/omap2_mcspi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/omap2_mcspi.c')
-rw-r--r--drivers/spi/omap2_mcspi.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 36501adc125d..3a5ed06d3d2f 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -467,6 +467,9 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
467 rx_reg = base + OMAP2_MCSPI_RX0; 467 rx_reg = base + OMAP2_MCSPI_RX0;
468 chstat_reg = base + OMAP2_MCSPI_CHSTAT0; 468 chstat_reg = base + OMAP2_MCSPI_CHSTAT0;
469 469
470 if (c < (word_len>>3))
471 return 0;
472
470 if (word_len <= 8) { 473 if (word_len <= 8) {
471 u8 *rx; 474 u8 *rx;
472 const u8 *tx; 475 const u8 *tx;
@@ -514,7 +517,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
514 dev_vdbg(&spi->dev, "read-%d %02x\n", 517 dev_vdbg(&spi->dev, "read-%d %02x\n",
515 word_len, *(rx - 1)); 518 word_len, *(rx - 1));
516 } 519 }
517 } while (c); 520 } while (c > (word_len>>3));
518 } else if (word_len <= 16) { 521 } else if (word_len <= 16) {
519 u16 *rx; 522 u16 *rx;
520 const u16 *tx; 523 const u16 *tx;
@@ -561,7 +564,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
561 dev_vdbg(&spi->dev, "read-%d %04x\n", 564 dev_vdbg(&spi->dev, "read-%d %04x\n",
562 word_len, *(rx - 1)); 565 word_len, *(rx - 1));
563 } 566 }
564 } while (c); 567 } while (c > (word_len>>3));
565 } else if (word_len <= 32) { 568 } else if (word_len <= 32) {
566 u32 *rx; 569 u32 *rx;
567 const u32 *tx; 570 const u32 *tx;
@@ -608,7 +611,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
608 dev_vdbg(&spi->dev, "read-%d %08x\n", 611 dev_vdbg(&spi->dev, "read-%d %08x\n",
609 word_len, *(rx - 1)); 612 word_len, *(rx - 1));
610 } 613 }
611 } while (c); 614 } while (c > (word_len>>3));
612 } 615 }
613 616
614 /* for TX_ONLY mode, be sure all words have shifted out */ 617 /* for TX_ONLY mode, be sure all words have shifted out */
@@ -631,6 +634,17 @@ out:
631 return count - c; 634 return count - c;
632} 635}
633 636
637static u32 omap2_mcspi_calc_divisor(u32 speed_hz)
638{
639 u32 div;
640
641 for (div = 0; div < 15; div++)
642 if (speed_hz >= (OMAP2_MCSPI_MAX_FREQ >> div))
643 return div;
644
645 return 15;
646}
647
634/* called only when no transfer is active to this device */ 648/* called only when no transfer is active to this device */
635static int omap2_mcspi_setup_transfer(struct spi_device *spi, 649static int omap2_mcspi_setup_transfer(struct spi_device *spi,
636 struct spi_transfer *t) 650 struct spi_transfer *t)
@@ -653,12 +667,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
653 if (t && t->speed_hz) 667 if (t && t->speed_hz)
654 speed_hz = t->speed_hz; 668 speed_hz = t->speed_hz;
655 669
656 if (speed_hz) { 670 speed_hz = min_t(u32, speed_hz, OMAP2_MCSPI_MAX_FREQ);
657 while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div)) 671 div = omap2_mcspi_calc_divisor(speed_hz);
658 > speed_hz)
659 div++;
660 } else
661 div = 15;
662 672
663 l = mcspi_cached_chconf0(spi); 673 l = mcspi_cached_chconf0(spi);
664 674
@@ -695,7 +705,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
695 mcspi_write_chconf0(spi, l); 705 mcspi_write_chconf0(spi, l);
696 706
697 dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", 707 dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
698 OMAP2_MCSPI_MAX_FREQ / (1 << div), 708 OMAP2_MCSPI_MAX_FREQ >> div,
699 (spi->mode & SPI_CPHA) ? "trailing" : "leading", 709 (spi->mode & SPI_CPHA) ? "trailing" : "leading",
700 (spi->mode & SPI_CPOL) ? "inverted" : "normal"); 710 (spi->mode & SPI_CPOL) ? "inverted" : "normal");
701 711
@@ -996,10 +1006,10 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)
996 t->bits_per_word); 1006 t->bits_per_word);
997 return -EINVAL; 1007 return -EINVAL;
998 } 1008 }
999 if (t->speed_hz && t->speed_hz < OMAP2_MCSPI_MAX_FREQ/(1<<16)) { 1009 if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) {
1000 dev_dbg(&spi->dev, "%d Hz max exceeds %d\n", 1010 dev_dbg(&spi->dev, "speed_hz %d below minimum %d Hz\n",
1001 t->speed_hz, 1011 t->speed_hz,
1002 OMAP2_MCSPI_MAX_FREQ/(1<<16)); 1012 OMAP2_MCSPI_MAX_FREQ >> 15);
1003 return -EINVAL; 1013 return -EINVAL;
1004 } 1014 }
1005 1015