diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/atmel_spi.c | 29 |
1 files changed, 20 insertions, 9 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 | ||