diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/mmc/host/atmel-mci.c | 60 |
1 files changed, 22 insertions, 38 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index d834e3756aef..14ab28da7fa8 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
| @@ -279,23 +279,6 @@ err: | |||
| 279 | "failed to initialize debugfs for controller\n"); | 279 | "failed to initialize debugfs for controller\n"); |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | static void atmci_enable(struct atmel_mci *host) | ||
| 283 | { | ||
| 284 | clk_enable(host->mck); | ||
| 285 | mci_writel(host, CR, MCI_CR_MCIEN); | ||
| 286 | mci_writel(host, MR, host->mode_reg); | ||
| 287 | mci_writel(host, SDCR, host->sdc_reg); | ||
| 288 | } | ||
| 289 | |||
| 290 | static void atmci_disable(struct atmel_mci *host) | ||
| 291 | { | ||
| 292 | mci_writel(host, CR, MCI_CR_SWRST); | ||
| 293 | |||
| 294 | /* Stall until write is complete, then disable the bus clock */ | ||
| 295 | mci_readl(host, SR); | ||
| 296 | clk_disable(host->mck); | ||
| 297 | } | ||
| 298 | |||
| 299 | static inline unsigned int ns_to_clocks(struct atmel_mci *host, | 282 | static inline unsigned int ns_to_clocks(struct atmel_mci *host, |
| 300 | unsigned int ns) | 283 | unsigned int ns) |
| 301 | { | 284 | { |
| @@ -408,8 +391,6 @@ static void atmci_request_end(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 408 | WARN_ON(host->cmd || host->data); | 391 | WARN_ON(host->cmd || host->data); |
| 409 | host->mrq = NULL; | 392 | host->mrq = NULL; |
| 410 | 393 | ||
| 411 | atmci_disable(host); | ||
| 412 | |||
| 413 | mmc_request_done(mmc, mrq); | 394 | mmc_request_done(mmc, mrq); |
| 414 | } | 395 | } |
| 415 | 396 | ||
| @@ -476,8 +457,6 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 476 | host->completed_events = 0; | 457 | host->completed_events = 0; |
| 477 | host->state = STATE_SENDING_CMD; | 458 | host->state = STATE_SENDING_CMD; |
| 478 | 459 | ||
| 479 | atmci_enable(host); | ||
| 480 | |||
| 481 | /* We don't support multiple blocks of weird lengths. */ | 460 | /* We don't support multiple blocks of weird lengths. */ |
| 482 | data = mrq->data; | 461 | data = mrq->data; |
| 483 | if (data) { | 462 | if (data) { |
| @@ -520,7 +499,6 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 520 | return; | 499 | return; |
| 521 | 500 | ||
| 522 | fail: | 501 | fail: |
| 523 | atmci_disable(host); | ||
| 524 | host->mrq = NULL; | 502 | host->mrq = NULL; |
| 525 | mrq->cmd->error = -EINVAL; | 503 | mrq->cmd->error = -EINVAL; |
| 526 | mmc_request_done(mmc, mrq); | 504 | mmc_request_done(mmc, mrq); |
| @@ -530,9 +508,21 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 530 | { | 508 | { |
| 531 | struct atmel_mci *host = mmc_priv(mmc); | 509 | struct atmel_mci *host = mmc_priv(mmc); |
| 532 | 510 | ||
| 511 | switch (ios->bus_width) { | ||
| 512 | case MMC_BUS_WIDTH_1: | ||
| 513 | host->sdc_reg = 0; | ||
| 514 | break; | ||
| 515 | case MMC_BUS_WIDTH_4: | ||
| 516 | host->sdc_reg = MCI_SDCBUS_4BIT; | ||
| 517 | break; | ||
| 518 | } | ||
| 519 | |||
| 533 | if (ios->clock) { | 520 | if (ios->clock) { |
| 534 | u32 clkdiv; | 521 | u32 clkdiv; |
| 535 | 522 | ||
| 523 | if (!host->mode_reg) | ||
| 524 | clk_enable(host->mck); | ||
| 525 | |||
| 536 | /* Set clock rate */ | 526 | /* Set clock rate */ |
| 537 | clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * ios->clock) - 1; | 527 | clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * ios->clock) - 1; |
| 538 | if (clkdiv > 255) { | 528 | if (clkdiv > 255) { |
| @@ -544,26 +534,20 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 544 | 534 | ||
| 545 | host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF | 535 | host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF |
| 546 | | MCI_MR_RDPROOF; | 536 | | MCI_MR_RDPROOF; |
| 547 | } | ||
| 548 | 537 | ||
| 549 | switch (ios->bus_width) { | 538 | mci_writel(host, CR, MCI_CR_MCIEN); |
| 550 | case MMC_BUS_WIDTH_1: | 539 | mci_writel(host, MR, host->mode_reg); |
| 551 | host->sdc_reg = 0; | 540 | mci_writel(host, SDCR, host->sdc_reg); |
| 552 | break; | 541 | } else { |
| 553 | case MMC_BUS_WIDTH_4: | 542 | mci_writel(host, CR, MCI_CR_MCIDIS); |
| 554 | host->sdc_reg = MCI_SDCBUS_4BIT; | 543 | if (host->mode_reg) { |
| 555 | break; | 544 | mci_readl(host, MR); |
| 545 | clk_disable(host->mck); | ||
| 546 | } | ||
| 547 | host->mode_reg = 0; | ||
| 556 | } | 548 | } |
| 557 | 549 | ||
| 558 | switch (ios->power_mode) { | 550 | switch (ios->power_mode) { |
| 559 | case MMC_POWER_ON: | ||
| 560 | /* Send init sequence (74 clock cycles) */ | ||
| 561 | atmci_enable(host); | ||
| 562 | mci_writel(host, CMDR, MCI_CMDR_SPCMD_INIT); | ||
| 563 | while (!(mci_readl(host, SR) & MCI_CMDRDY)) | ||
| 564 | cpu_relax(); | ||
| 565 | atmci_disable(host); | ||
| 566 | break; | ||
| 567 | default: | 551 | default: |
| 568 | /* | 552 | /* |
| 569 | * TODO: None of the currently available AVR32-based | 553 | * TODO: None of the currently available AVR32-based |
