aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2008-05-09 06:12:06 -0400
committerPaul Mackerras <paulus@samba.org>2008-05-09 06:12:06 -0400
commit2a5f2e3e6cd1ce9fb3f8b186b6bc9aa1f1497a92 (patch)
treeb2306840f227972a7c9d4a2b75e516fe81358ce8 /drivers/spi
parent02539d71fa98d5737bb668b02286c76241e4bac9 (diff)
parent78be76476a34a77f0ea9db2f78ba46a2b0fd5ab5 (diff)
Merge branch 'for-2.6.26' of master.kernel.org:/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx into merge
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/atmel_spi.c29
-rw-r--r--drivers/spi/spi_bfin5xx.c7
-rw-r--r--drivers/spi/spi_s3c24xx.c6
3 files changed, 28 insertions, 14 deletions
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 02c8e305b14f..e81d59d78910 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -497,7 +497,7 @@ static int atmel_spi_setup(struct spi_device *spi)
497 struct atmel_spi *as; 497 struct atmel_spi *as;
498 u32 scbr, csr; 498 u32 scbr, csr;
499 unsigned int bits = spi->bits_per_word; 499 unsigned int bits = spi->bits_per_word;
500 unsigned long bus_hz, sck_hz; 500 unsigned long bus_hz;
501 unsigned int npcs_pin; 501 unsigned int npcs_pin;
502 int ret; 502 int ret;
503 503
@@ -536,14 +536,25 @@ static int atmel_spi_setup(struct spi_device *spi)
536 return -EINVAL; 536 return -EINVAL;
537 } 537 }
538 538
539 /* speed zero convention is used by some upper layers */ 539 /*
540 * Pre-new_1 chips start out at half the peripheral
541 * bus speed.
542 */
540 bus_hz = clk_get_rate(as->clk); 543 bus_hz = clk_get_rate(as->clk);
544 if (!as->new_1)
545 bus_hz /= 2;
546
541 if (spi->max_speed_hz) { 547 if (spi->max_speed_hz) {
542 /* assume div32/fdiv/mbz == 0 */ 548 /*
543 if (!as->new_1) 549 * Calculate the lowest divider that satisfies the
544 bus_hz /= 2; 550 * constraint, assuming div32/fdiv/mbz == 0.
545 scbr = ((bus_hz + spi->max_speed_hz - 1) 551 */
546 / spi->max_speed_hz); 552 scbr = DIV_ROUND_UP(bus_hz, spi->max_speed_hz);
553
554 /*
555 * If the resulting divider doesn't fit into the
556 * register bitfield, we can't satisfy the constraint.
557 */
547 if (scbr >= (1 << SPI_SCBR_SIZE)) { 558 if (scbr >= (1 << SPI_SCBR_SIZE)) {
548 dev_dbg(&spi->dev, 559 dev_dbg(&spi->dev,
549 "setup: %d Hz too slow, scbr %u; min %ld Hz\n", 560 "setup: %d Hz too slow, scbr %u; min %ld Hz\n",
@@ -551,8 +562,8 @@ static int atmel_spi_setup(struct spi_device *spi)
551 return -EINVAL; 562 return -EINVAL;
552 } 563 }
553 } else 564 } else
565 /* speed zero means "as slow as possible" */
554 scbr = 0xff; 566 scbr = 0xff;
555 sck_hz = bus_hz / scbr;
556 567
557 csr = SPI_BF(SCBR, scbr) | SPI_BF(BITS, bits - 8); 568 csr = SPI_BF(SCBR, scbr) | SPI_BF(BITS, bits - 8);
558 if (spi->mode & SPI_CPOL) 569 if (spi->mode & SPI_CPOL)
@@ -589,7 +600,7 @@ static int atmel_spi_setup(struct spi_device *spi)
589 600
590 dev_dbg(&spi->dev, 601 dev_dbg(&spi->dev,
591 "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n", 602 "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n",
592 sck_hz, bits, spi->mode, spi->chip_select, csr); 603 bus_hz / scbr, bits, spi->mode, spi->chip_select, csr);
593 604
594 spi_writel(as, CSR0 + 4 * spi->chip_select, csr); 605 spi_writel(as, CSR0 + 4 * spi->chip_select, csr);
595 606
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index a9ac1fdb3094..7fea3cf4588a 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -608,6 +608,7 @@ static void pump_transfers(unsigned long data)
608 u8 width; 608 u8 width;
609 u16 cr, dma_width, dma_config; 609 u16 cr, dma_width, dma_config;
610 u32 tranf_success = 1; 610 u32 tranf_success = 1;
611 u8 full_duplex = 0;
611 612
612 /* Get current state information */ 613 /* Get current state information */
613 message = drv_data->cur_msg; 614 message = drv_data->cur_msg;
@@ -658,6 +659,7 @@ static void pump_transfers(unsigned long data)
658 } 659 }
659 660
660 if (transfer->rx_buf != NULL) { 661 if (transfer->rx_buf != NULL) {
662 full_duplex = transfer->tx_buf != NULL;
661 drv_data->rx = transfer->rx_buf; 663 drv_data->rx = transfer->rx_buf;
662 drv_data->rx_end = drv_data->rx + transfer->len; 664 drv_data->rx_end = drv_data->rx + transfer->len;
663 dev_dbg(&drv_data->pdev->dev, "rx_buf is %p, rx_end is %p\n", 665 dev_dbg(&drv_data->pdev->dev, "rx_buf is %p, rx_end is %p\n",
@@ -740,7 +742,8 @@ static void pump_transfers(unsigned long data)
740 * successful use different way to r/w according to 742 * successful use different way to r/w according to
741 * drv_data->cur_chip->enable_dma 743 * drv_data->cur_chip->enable_dma
742 */ 744 */
743 if (drv_data->cur_chip->enable_dma && drv_data->len > 6) { 745 if (!full_duplex && drv_data->cur_chip->enable_dma
746 && drv_data->len > 6) {
744 747
745 disable_dma(drv_data->dma_channel); 748 disable_dma(drv_data->dma_channel);
746 clear_dma_irqstat(drv_data->dma_channel); 749 clear_dma_irqstat(drv_data->dma_channel);
@@ -828,7 +831,7 @@ static void pump_transfers(unsigned long data)
828 /* IO mode write then read */ 831 /* IO mode write then read */
829 dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n"); 832 dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n");
830 833
831 if (drv_data->tx != NULL && drv_data->rx != NULL) { 834 if (full_duplex) {
832 /* full duplex mode */ 835 /* full duplex mode */
833 BUG_ON((drv_data->tx_end - drv_data->tx) != 836 BUG_ON((drv_data->tx_end - drv_data->tx) !=
834 (drv_data->rx_end - drv_data->rx)); 837 (drv_data->rx_end - drv_data->rx));
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index 34bfb7dd7764..0885cc357a37 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -125,10 +125,10 @@ static int s3c24xx_spi_setupxfer(struct spi_device *spi,
125 /* is clk = pclk / (2 * (pre+1)), or is it 125 /* is clk = pclk / (2 * (pre+1)), or is it
126 * clk = (pclk * 2) / ( pre + 1) */ 126 * clk = (pclk * 2) / ( pre + 1) */
127 127
128 div = (div / 2) - 1; 128 div /= 2;
129 129
130 if (div < 0) 130 if (div > 0)
131 div = 1; 131 div -= 1;
132 132
133 if (div > 255) 133 if (div > 255)
134 div = 255; 134 div = 255;