diff options
-rw-r--r-- | drivers/mmc/tifm_sd.c | 98 |
1 files changed, 50 insertions, 48 deletions
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c index 85a5974318b4..37fe0c3ecb85 100644 --- a/drivers/mmc/tifm_sd.c +++ b/drivers/mmc/tifm_sd.c | |||
@@ -118,7 +118,7 @@ static void tifm_sd_kunmap_atomic(char *buffer, struct mmc_data *data) | |||
118 | } | 118 | } |
119 | 119 | ||
120 | static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host, | 120 | static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host, |
121 | unsigned int host_status) | 121 | unsigned int host_status) |
122 | { | 122 | { |
123 | struct mmc_command *cmd = host->req->cmd; | 123 | struct mmc_command *cmd = host->req->cmd; |
124 | unsigned int t_val = 0, cnt = 0; | 124 | unsigned int t_val = 0, cnt = 0; |
@@ -159,7 +159,7 @@ static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host, | |||
159 | t_val |= ((buffer[host->buffer_pos++]) | 159 | t_val |= ((buffer[host->buffer_pos++]) |
160 | << 8) & 0xff00; | 160 | << 8) & 0xff00; |
161 | writel(t_val, | 161 | writel(t_val, |
162 | sock->addr + SOCK_MMCSD_DATA); | 162 | sock->addr + SOCK_MMCSD_DATA); |
163 | } | 163 | } |
164 | } | 164 | } |
165 | } | 165 | } |
@@ -220,7 +220,7 @@ static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd) | |||
220 | cmd_mask |= TIFM_MMCSD_READ; | 220 | cmd_mask |= TIFM_MMCSD_READ; |
221 | 221 | ||
222 | dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n", | 222 | dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n", |
223 | cmd->opcode, cmd->arg, cmd_mask); | 223 | cmd->opcode, cmd->arg, cmd_mask); |
224 | 224 | ||
225 | writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH); | 225 | writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH); |
226 | writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW); | 226 | writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW); |
@@ -324,7 +324,7 @@ change_state: | |||
324 | 324 | ||
325 | /* Called from interrupt handler */ | 325 | /* Called from interrupt handler */ |
326 | static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock, | 326 | static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock, |
327 | unsigned int sock_irq_status) | 327 | unsigned int sock_irq_status) |
328 | { | 328 | { |
329 | struct tifm_sd *host; | 329 | struct tifm_sd *host; |
330 | unsigned int host_status = 0, fifo_status = 0; | 330 | unsigned int host_status = 0, fifo_status = 0; |
@@ -350,11 +350,11 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock, | |||
350 | if (host_status & TIFM_MMCSD_ERRMASK) { | 350 | if (host_status & TIFM_MMCSD_ERRMASK) { |
351 | if (host_status & TIFM_MMCSD_CERR) | 351 | if (host_status & TIFM_MMCSD_CERR) |
352 | error_code = MMC_ERR_FAILED; | 352 | error_code = MMC_ERR_FAILED; |
353 | else if (host_status & | 353 | else if (host_status |
354 | (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO)) | 354 | & (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO)) |
355 | error_code = MMC_ERR_TIMEOUT; | 355 | error_code = MMC_ERR_TIMEOUT; |
356 | else if (host_status & | 356 | else if (host_status |
357 | (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC)) | 357 | & (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC)) |
358 | error_code = MMC_ERR_BADCRC; | 358 | error_code = MMC_ERR_BADCRC; |
359 | 359 | ||
360 | writel(TIFM_FIFO_INT_SETALL, | 360 | writel(TIFM_FIFO_INT_SETALL, |
@@ -382,8 +382,8 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock, | |||
382 | 382 | ||
383 | if (host_status & TIFM_MMCSD_CB) | 383 | if (host_status & TIFM_MMCSD_CB) |
384 | host->flags |= CARD_BUSY; | 384 | host->flags |= CARD_BUSY; |
385 | if ((host_status & TIFM_MMCSD_EOFB) && | 385 | if ((host_status & TIFM_MMCSD_EOFB) |
386 | (host->flags & CARD_BUSY)) { | 386 | && (host->flags & CARD_BUSY)) { |
387 | host->written_blocks++; | 387 | host->written_blocks++; |
388 | host->flags &= ~CARD_BUSY; | 388 | host->flags &= ~CARD_BUSY; |
389 | } | 389 | } |
@@ -393,22 +393,23 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock, | |||
393 | tifm_sd_process_cmd(sock, host, host_status); | 393 | tifm_sd_process_cmd(sock, host, host_status); |
394 | done: | 394 | done: |
395 | dev_dbg(&sock->dev, "host_status %x, fifo_status %x\n", | 395 | dev_dbg(&sock->dev, "host_status %x, fifo_status %x\n", |
396 | host_status, fifo_status); | 396 | host_status, fifo_status); |
397 | spin_unlock(&sock->lock); | 397 | spin_unlock(&sock->lock); |
398 | return sock_irq_status; | 398 | return sock_irq_status; |
399 | } | 399 | } |
400 | 400 | ||
401 | static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd) | 401 | static void tifm_sd_prepare_data(struct tifm_sd *host, struct mmc_command *cmd) |
402 | { | 402 | { |
403 | struct tifm_dev *sock = card->dev; | 403 | struct tifm_dev *sock = host->dev; |
404 | unsigned int dest_cnt; | 404 | unsigned int dest_cnt; |
405 | 405 | ||
406 | /* DMA style IO */ | 406 | /* DMA style IO */ |
407 | 407 | dev_dbg(&sock->dev, "setting dma for %d blocks\n", | |
408 | cmd->data->blocks); | ||
408 | writel(TIFM_FIFO_INT_SETALL, | 409 | writel(TIFM_FIFO_INT_SETALL, |
409 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | 410 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); |
410 | writel(ilog2(cmd->data->blksz) - 2, | 411 | writel(ilog2(cmd->data->blksz) - 2, |
411 | sock->addr + SOCK_FIFO_PAGE_SIZE); | 412 | sock->addr + SOCK_FIFO_PAGE_SIZE); |
412 | writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL); | 413 | writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL); |
413 | writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | 414 | writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); |
414 | 415 | ||
@@ -422,7 +423,7 @@ static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd) | |||
422 | if (cmd->data->flags & MMC_DATA_WRITE) { | 423 | if (cmd->data->flags & MMC_DATA_WRITE) { |
423 | writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | 424 | writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); |
424 | writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN, | 425 | writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN, |
425 | sock->addr + SOCK_DMA_CONTROL); | 426 | sock->addr + SOCK_DMA_CONTROL); |
426 | } else { | 427 | } else { |
427 | writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | 428 | writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); |
428 | writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL); | 429 | writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL); |
@@ -430,7 +431,7 @@ static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd) | |||
430 | } | 431 | } |
431 | 432 | ||
432 | static void tifm_sd_set_data_timeout(struct tifm_sd *host, | 433 | static void tifm_sd_set_data_timeout(struct tifm_sd *host, |
433 | struct mmc_data *data) | 434 | struct mmc_data *data) |
434 | { | 435 | { |
435 | struct tifm_dev *sock = host->dev; | 436 | struct tifm_dev *sock = host->dev; |
436 | unsigned int data_timeout = data->timeout_clks; | 437 | unsigned int data_timeout = data->timeout_clks; |
@@ -448,7 +449,7 @@ static void tifm_sd_set_data_timeout(struct tifm_sd *host, | |||
448 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | 449 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); |
449 | } else { | 450 | } else { |
450 | data_timeout = (data_timeout >> 10) + 1; | 451 | data_timeout = (data_timeout >> 10) + 1; |
451 | if(data_timeout > 0xffff) | 452 | if (data_timeout > 0xffff) |
452 | data_timeout = 0; /* set to unlimited */ | 453 | data_timeout = 0; /* set to unlimited */ |
453 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | 454 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); |
454 | writel(TIFM_MMCSD_DPE | 455 | writel(TIFM_MMCSD_DPE |
@@ -499,7 +500,7 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
499 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); | 500 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); |
500 | host->state = CMD; | 501 | host->state = CMD; |
501 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | 502 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), |
502 | sock->addr + SOCK_CONTROL); | 503 | sock->addr + SOCK_CONTROL); |
503 | tifm_sd_exec(host, mrq->cmd); | 504 | tifm_sd_exec(host, mrq->cmd); |
504 | spin_unlock_irqrestore(&sock->lock, flags); | 505 | spin_unlock_irqrestore(&sock->lock, flags); |
505 | return; | 506 | return; |
@@ -539,8 +540,8 @@ static void tifm_sd_end_cmd(unsigned long data) | |||
539 | r_data = mrq->cmd->data; | 540 | r_data = mrq->cmd->data; |
540 | if (r_data) { | 541 | if (r_data) { |
541 | if (r_data->flags & MMC_DATA_WRITE) { | 542 | if (r_data->flags & MMC_DATA_WRITE) { |
542 | r_data->bytes_xfered = host->written_blocks * | 543 | r_data->bytes_xfered = host->written_blocks |
543 | r_data->blksz; | 544 | * r_data->blksz; |
544 | } else { | 545 | } else { |
545 | r_data->bytes_xfered = r_data->blocks - | 546 | r_data->bytes_xfered = r_data->blocks - |
546 | readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; | 547 | readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; |
@@ -554,7 +555,7 @@ static void tifm_sd_end_cmd(unsigned long data) | |||
554 | } | 555 | } |
555 | 556 | ||
556 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | 557 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), |
557 | sock->addr + SOCK_CONTROL); | 558 | sock->addr + SOCK_CONTROL); |
558 | 559 | ||
559 | spin_unlock_irqrestore(&sock->lock, flags); | 560 | spin_unlock_irqrestore(&sock->lock, flags); |
560 | mmc_request_done(mmc, mrq); | 561 | mmc_request_done(mmc, mrq); |
@@ -582,14 +583,14 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq) | |||
582 | if (r_data) { | 583 | if (r_data) { |
583 | tifm_sd_set_data_timeout(host, r_data); | 584 | tifm_sd_set_data_timeout(host, r_data); |
584 | 585 | ||
585 | host->buffer_size = mrq->cmd->data->blocks * | 586 | host->buffer_size = mrq->cmd->data->blocks |
586 | mrq->cmd->data->blksz; | 587 | * mrq->cmd->data->blksz; |
587 | 588 | ||
588 | writel(TIFM_MMCSD_BUFINT | | 589 | writel(TIFM_MMCSD_BUFINT |
589 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | 590 | | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), |
590 | sock->addr + SOCK_MMCSD_INT_ENABLE); | 591 | sock->addr + SOCK_MMCSD_INT_ENABLE); |
591 | writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) | | 592 | writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) |
592 | (TIFM_MMCSD_FIFO_SIZE - 1), | 593 | | (TIFM_MMCSD_FIFO_SIZE - 1), |
593 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | 594 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); |
594 | 595 | ||
595 | host->written_blocks = 0; | 596 | host->written_blocks = 0; |
@@ -603,7 +604,7 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq) | |||
603 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); | 604 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); |
604 | host->state = CMD; | 605 | host->state = CMD; |
605 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | 606 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), |
606 | sock->addr + SOCK_CONTROL); | 607 | sock->addr + SOCK_CONTROL); |
607 | tifm_sd_exec(host, mrq->cmd); | 608 | tifm_sd_exec(host, mrq->cmd); |
608 | spin_unlock_irqrestore(&sock->lock, flags); | 609 | spin_unlock_irqrestore(&sock->lock, flags); |
609 | return; | 610 | return; |
@@ -642,8 +643,8 @@ static void tifm_sd_end_cmd_nodma(unsigned long data) | |||
642 | sock->addr + SOCK_MMCSD_INT_ENABLE); | 643 | sock->addr + SOCK_MMCSD_INT_ENABLE); |
643 | 644 | ||
644 | if (r_data->flags & MMC_DATA_WRITE) { | 645 | if (r_data->flags & MMC_DATA_WRITE) { |
645 | r_data->bytes_xfered = host->written_blocks * | 646 | r_data->bytes_xfered = host->written_blocks |
646 | r_data->blksz; | 647 | * r_data->blksz; |
647 | } else { | 648 | } else { |
648 | r_data->bytes_xfered = r_data->blocks - | 649 | r_data->bytes_xfered = r_data->blocks - |
649 | readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; | 650 | readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; |
@@ -656,7 +657,7 @@ static void tifm_sd_end_cmd_nodma(unsigned long data) | |||
656 | } | 657 | } |
657 | 658 | ||
658 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | 659 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), |
659 | sock->addr + SOCK_CONTROL); | 660 | sock->addr + SOCK_CONTROL); |
660 | 661 | ||
661 | spin_unlock_irqrestore(&sock->lock, flags); | 662 | spin_unlock_irqrestore(&sock->lock, flags); |
662 | 663 | ||
@@ -707,9 +708,9 @@ static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
707 | writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), | 708 | writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), |
708 | sock->addr + SOCK_MMCSD_CONFIG); | 709 | sock->addr + SOCK_MMCSD_CONFIG); |
709 | } else { | 710 | } else { |
710 | writel((~TIFM_MMCSD_4BBUS) & | 711 | writel((~TIFM_MMCSD_4BBUS) |
711 | readl(sock->addr + SOCK_MMCSD_CONFIG), | 712 | & readl(sock->addr + SOCK_MMCSD_CONFIG), |
712 | sock->addr + SOCK_MMCSD_CONFIG); | 713 | sock->addr + SOCK_MMCSD_CONFIG); |
713 | } | 714 | } |
714 | 715 | ||
715 | if (ios->clock) { | 716 | if (ios->clock) { |
@@ -728,23 +729,24 @@ static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
728 | if ((20000000 / clk_div1) > (24000000 / clk_div2)) { | 729 | if ((20000000 / clk_div1) > (24000000 / clk_div2)) { |
729 | host->clk_freq = 20000000; | 730 | host->clk_freq = 20000000; |
730 | host->clk_div = clk_div1; | 731 | host->clk_div = clk_div1; |
731 | writel((~TIFM_CTRL_FAST_CLK) & | 732 | writel((~TIFM_CTRL_FAST_CLK) |
732 | readl(sock->addr + SOCK_CONTROL), | 733 | & readl(sock->addr + SOCK_CONTROL), |
733 | sock->addr + SOCK_CONTROL); | 734 | sock->addr + SOCK_CONTROL); |
734 | } else { | 735 | } else { |
735 | host->clk_freq = 24000000; | 736 | host->clk_freq = 24000000; |
736 | host->clk_div = clk_div2; | 737 | host->clk_div = clk_div2; |
737 | writel(TIFM_CTRL_FAST_CLK | | 738 | writel(TIFM_CTRL_FAST_CLK |
738 | readl(sock->addr + SOCK_CONTROL), | 739 | | readl(sock->addr + SOCK_CONTROL), |
739 | sock->addr + SOCK_CONTROL); | 740 | sock->addr + SOCK_CONTROL); |
740 | } | 741 | } |
741 | } else { | 742 | } else { |
742 | host->clk_div = 0; | 743 | host->clk_div = 0; |
743 | } | 744 | } |
744 | host->clk_div &= TIFM_MMCSD_CLKMASK; | 745 | host->clk_div &= TIFM_MMCSD_CLKMASK; |
745 | writel(host->clk_div | ((~TIFM_MMCSD_CLKMASK) & | 746 | writel(host->clk_div |
746 | readl(sock->addr + SOCK_MMCSD_CONFIG)), | 747 | | ((~TIFM_MMCSD_CLKMASK) |
747 | sock->addr + SOCK_MMCSD_CONFIG); | 748 | & readl(sock->addr + SOCK_MMCSD_CONFIG)), |
749 | sock->addr + SOCK_MMCSD_CONFIG); | ||
748 | 750 | ||
749 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) | 751 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) |
750 | host->flags |= OPENDRAIN; | 752 | host->flags |= OPENDRAIN; |
@@ -855,8 +857,8 @@ static int tifm_sd_probe(struct tifm_dev *sock) | |||
855 | struct tifm_sd *host; | 857 | struct tifm_sd *host; |
856 | int rc = -EIO; | 858 | int rc = -EIO; |
857 | 859 | ||
858 | if (!(TIFM_SOCK_STATE_OCCUPIED & | 860 | if (!(TIFM_SOCK_STATE_OCCUPIED |
859 | readl(sock->addr + SOCK_PRESENT_STATE))) { | 861 | & readl(sock->addr + SOCK_PRESENT_STATE))) { |
860 | printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n"); | 862 | printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n"); |
861 | return rc; | 863 | return rc; |
862 | } | 864 | } |
@@ -914,7 +916,7 @@ static void tifm_sd_remove(struct tifm_dev *sock) | |||
914 | 916 | ||
915 | /* The meaning of the bit majority in this constant is unknown. */ | 917 | /* The meaning of the bit majority in this constant is unknown. */ |
916 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), | 918 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), |
917 | sock->addr + SOCK_CONTROL); | 919 | sock->addr + SOCK_CONTROL); |
918 | 920 | ||
919 | tifm_set_drvdata(sock, NULL); | 921 | tifm_set_drvdata(sock, NULL); |
920 | mmc_free_host(mmc); | 922 | mmc_free_host(mmc); |