aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/atmel-mci.c249
1 files changed, 145 insertions, 104 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 00008967ef7a..d834e3756aef 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -36,11 +36,17 @@
36 36
37enum { 37enum {
38 EVENT_CMD_COMPLETE = 0, 38 EVENT_CMD_COMPLETE = 0,
39 EVENT_DATA_ERROR,
40 EVENT_DATA_COMPLETE,
41 EVENT_STOP_SENT,
42 EVENT_STOP_COMPLETE,
43 EVENT_XFER_COMPLETE, 39 EVENT_XFER_COMPLETE,
40 EVENT_DATA_COMPLETE,
41 EVENT_DATA_ERROR,
42};
43
44enum atmel_mci_state {
45 STATE_SENDING_CMD = 0,
46 STATE_SENDING_DATA,
47 STATE_DATA_BUSY,
48 STATE_SENDING_STOP,
49 STATE_DATA_ERROR,
44}; 50};
45 51
46struct atmel_mci { 52struct atmel_mci {
@@ -56,7 +62,6 @@ struct atmel_mci {
56 62
57 u32 cmd_status; 63 u32 cmd_status;
58 u32 data_status; 64 u32 data_status;
59 u32 stop_status;
60 u32 stop_cmdr; 65 u32 stop_cmdr;
61 66
62 u32 mode_reg; 67 u32 mode_reg;
@@ -65,6 +70,7 @@ struct atmel_mci {
65 struct tasklet_struct tasklet; 70 struct tasklet_struct tasklet;
66 unsigned long pending_events; 71 unsigned long pending_events;
67 unsigned long completed_events; 72 unsigned long completed_events;
73 enum atmel_mci_state state;
68 74
69 int present; 75 int present;
70 int detect_pin; 76 int detect_pin;
@@ -79,18 +85,12 @@ struct atmel_mci {
79 struct platform_device *pdev; 85 struct platform_device *pdev;
80}; 86};
81 87
82#define atmci_is_completed(host, event) \
83 test_bit(event, &host->completed_events)
84#define atmci_test_and_clear_pending(host, event) \ 88#define atmci_test_and_clear_pending(host, event) \
85 test_and_clear_bit(event, &host->pending_events) 89 test_and_clear_bit(event, &host->pending_events)
86#define atmci_test_and_set_completed(host, event) \
87 test_and_set_bit(event, &host->completed_events)
88#define atmci_set_completed(host, event) \ 90#define atmci_set_completed(host, event) \
89 set_bit(event, &host->completed_events) 91 set_bit(event, &host->completed_events)
90#define atmci_set_pending(host, event) \ 92#define atmci_set_pending(host, event) \
91 set_bit(event, &host->pending_events) 93 set_bit(event, &host->pending_events)
92#define atmci_clear_pending(host, event) \
93 clear_bit(event, &host->pending_events)
94 94
95/* 95/*
96 * The debugfs stuff below is mostly optimized away when 96 * The debugfs stuff below is mostly optimized away when
@@ -258,6 +258,10 @@ static void atmci_init_debugfs(struct atmel_mci *host)
258 if (!node) 258 if (!node)
259 goto err; 259 goto err;
260 260
261 node = debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state);
262 if (!node)
263 goto err;
264
261 node = debugfs_create_x32("pending_events", S_IRUSR, root, 265 node = debugfs_create_x32("pending_events", S_IRUSR, root,
262 (u32 *)&host->pending_events); 266 (u32 *)&host->pending_events);
263 if (!node) 267 if (!node)
@@ -378,8 +382,6 @@ static void atmci_start_command(struct atmel_mci *host,
378 struct mmc_command *cmd, 382 struct mmc_command *cmd,
379 u32 cmd_flags) 383 u32 cmd_flags)
380{ 384{
381 /* Must read host->cmd after testing event flags */
382 smp_rmb();
383 WARN_ON(host->cmd); 385 WARN_ON(host->cmd);
384 host->cmd = cmd; 386 host->cmd = cmd;
385 387
@@ -472,6 +474,7 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
472 host->mrq = mrq; 474 host->mrq = mrq;
473 host->pending_events = 0; 475 host->pending_events = 0;
474 host->completed_events = 0; 476 host->completed_events = 0;
477 host->state = STATE_SENDING_CMD;
475 478
476 atmci_enable(host); 479 atmci_enable(host);
477 480
@@ -596,8 +599,10 @@ static struct mmc_host_ops atmci_ops = {
596}; 599};
597 600
598static void atmci_command_complete(struct atmel_mci *host, 601static void atmci_command_complete(struct atmel_mci *host,
599 struct mmc_command *cmd, u32 status) 602 struct mmc_command *cmd)
600{ 603{
604 u32 status = host->cmd_status;
605
601 /* Read the response from the card (up to 16 bytes) */ 606 /* Read the response from the card (up to 16 bytes) */
602 cmd->resp[0] = mci_readl(host, RSPR); 607 cmd->resp[0] = mci_readl(host, RSPR);
603 cmd->resp[1] = mci_readl(host, RSPR); 608 cmd->resp[1] = mci_readl(host, RSPR);
@@ -666,20 +671,32 @@ static void atmci_detect_change(unsigned long data)
666 * commands or data transfers. 671 * commands or data transfers.
667 */ 672 */
668 mci_writel(host, CR, MCI_CR_SWRST); 673 mci_writel(host, CR, MCI_CR_SWRST);
674 mci_readl(host, SR);
669 675
670 if (!atmci_is_completed(host, EVENT_CMD_COMPLETE)) 676 host->data = NULL;
671 mrq->cmd->error = -ENOMEDIUM; 677 host->cmd = NULL;
672 678
673 if (mrq->data && !atmci_is_completed(host, 679 switch (host->state) {
674 EVENT_DATA_COMPLETE)) { 680 case STATE_SENDING_CMD:
675 host->data = NULL; 681 mrq->cmd->error = -ENOMEDIUM;
682 if (!mrq->data)
683 break;
684 /* fall through */
685 case STATE_SENDING_DATA:
676 mrq->data->error = -ENOMEDIUM; 686 mrq->data->error = -ENOMEDIUM;
677 } 687 break;
678 if (mrq->stop && !atmci_is_completed(host, 688 case STATE_DATA_BUSY:
679 EVENT_STOP_COMPLETE)) 689 case STATE_DATA_ERROR:
690 if (mrq->data->error == -EINPROGRESS)
691 mrq->data->error = -ENOMEDIUM;
692 if (!mrq->stop)
693 break;
694 /* fall through */
695 case STATE_SENDING_STOP:
680 mrq->stop->error = -ENOMEDIUM; 696 mrq->stop->error = -ENOMEDIUM;
697 break;
698 }
681 699
682 host->cmd = NULL;
683 atmci_request_end(host->mmc, mrq); 700 atmci_request_end(host->mmc, mrq);
684 } 701 }
685 702
@@ -693,81 +710,116 @@ static void atmci_tasklet_func(unsigned long priv)
693 struct atmel_mci *host = mmc_priv(mmc); 710 struct atmel_mci *host = mmc_priv(mmc);
694 struct mmc_request *mrq = host->mrq; 711 struct mmc_request *mrq = host->mrq;
695 struct mmc_data *data = host->data; 712 struct mmc_data *data = host->data;
713 struct mmc_command *cmd = host->cmd;
714 enum atmel_mci_state state = host->state;
715 enum atmel_mci_state prev_state;
716 u32 status;
717
718 state = host->state;
696 719
697 dev_vdbg(&mmc->class_dev, 720 dev_vdbg(&mmc->class_dev,
698 "tasklet: pending/completed/mask %lx/%lx/%x\n", 721 "tasklet: state %u pending/completed/mask %lx/%lx/%x\n",
699 host->pending_events, host->completed_events, 722 state, host->pending_events, host->completed_events,
700 mci_readl(host, IMR)); 723 mci_readl(host, IMR));
701 724
702 if (atmci_test_and_clear_pending(host, EVENT_CMD_COMPLETE)) { 725 do {
703 /* 726 prev_state = state;
704 * host->cmd must be set to NULL before the interrupt
705 * handler sees EVENT_CMD_COMPLETE
706 */
707 host->cmd = NULL;
708 smp_wmb();
709 atmci_set_completed(host, EVENT_CMD_COMPLETE);
710 atmci_command_complete(host, mrq->cmd, host->cmd_status);
711
712 if (!mrq->cmd->error && mrq->stop
713 && atmci_is_completed(host, EVENT_XFER_COMPLETE)
714 && !atmci_test_and_set_completed(host,
715 EVENT_STOP_SENT))
716 send_stop_cmd(host->mmc, mrq->data);
717 }
718 if (atmci_test_and_clear_pending(host, EVENT_STOP_COMPLETE)) {
719 /*
720 * host->cmd must be set to NULL before the interrupt
721 * handler sees EVENT_STOP_COMPLETE
722 */
723 host->cmd = NULL;
724 smp_wmb();
725 atmci_set_completed(host, EVENT_STOP_COMPLETE);
726 atmci_command_complete(host, mrq->stop, host->stop_status);
727 }
728 if (atmci_test_and_clear_pending(host, EVENT_DATA_ERROR)) {
729 u32 status = host->data_status;
730 727
731 dev_vdbg(&mmc->class_dev, "data error: status=%08x\n", status); 728 switch (state) {
729 case STATE_SENDING_CMD:
730 if (!atmci_test_and_clear_pending(host,
731 EVENT_CMD_COMPLETE))
732 break;
732 733
733 atmci_set_completed(host, EVENT_DATA_ERROR); 734 host->cmd = NULL;
734 atmci_set_completed(host, EVENT_DATA_COMPLETE); 735 atmci_set_completed(host, EVENT_CMD_COMPLETE);
736 atmci_command_complete(host, mrq->cmd);
737 if (!mrq->data || cmd->error) {
738 atmci_request_end(mmc, host->mrq);
739 break;
740 }
735 741
736 if (status & MCI_DTOE) { 742 prev_state = state = STATE_SENDING_DATA;
737 dev_dbg(&mmc->class_dev, 743 /* fall through */
738 "data timeout error\n");
739 data->error = -ETIMEDOUT;
740 } else if (status & MCI_DCRCE) {
741 dev_dbg(&mmc->class_dev, "data CRC error\n");
742 data->error = -EILSEQ;
743 } else {
744 dev_dbg(&mmc->class_dev,
745 "data FIFO error (status=%08x)\n",
746 status);
747 data->error = -EIO;
748 }
749 744
750 if (host->present && data->stop 745 case STATE_SENDING_DATA:
751 && atmci_is_completed(host, EVENT_CMD_COMPLETE) 746 if (atmci_test_and_clear_pending(host,
752 && !atmci_test_and_set_completed( 747 EVENT_DATA_ERROR)) {
753 host, EVENT_STOP_SENT)) 748 if (data->stop)
754 send_stop_cmd(host->mmc, data); 749 send_stop_cmd(host->mmc, data);
750 state = STATE_DATA_ERROR;
751 break;
752 }
755 753
756 host->data = NULL; 754 if (!atmci_test_and_clear_pending(host,
757 } 755 EVENT_XFER_COMPLETE))
758 if (atmci_test_and_clear_pending(host, EVENT_DATA_COMPLETE)) { 756 break;
759 atmci_set_completed(host, EVENT_DATA_COMPLETE);
760 757
761 if (!atmci_is_completed(host, EVENT_DATA_ERROR)) { 758 atmci_set_completed(host, EVENT_XFER_COMPLETE);
762 data->bytes_xfered = data->blocks * data->blksz; 759 prev_state = state = STATE_DATA_BUSY;
763 data->error = 0; 760 /* fall through */
764 }
765 761
766 host->data = NULL; 762 case STATE_DATA_BUSY:
767 } 763 if (!atmci_test_and_clear_pending(host,
764 EVENT_DATA_COMPLETE))
765 break;
766
767 host->data = NULL;
768 atmci_set_completed(host, EVENT_DATA_COMPLETE);
769 status = host->data_status;
770 if (unlikely(status & ATMCI_DATA_ERROR_FLAGS)) {
771 if (status & MCI_DTOE) {
772 dev_dbg(&mmc->class_dev,
773 "data timeout error\n");
774 data->error = -ETIMEDOUT;
775 } else if (status & MCI_DCRCE) {
776 dev_dbg(&mmc->class_dev,
777 "data CRC error\n");
778 data->error = -EILSEQ;
779 } else {
780 dev_dbg(&mmc->class_dev,
781 "data FIFO error (status=%08x)\n",
782 status);
783 data->error = -EIO;
784 }
785 } else {
786 data->bytes_xfered = data->blocks * data->blksz;
787 data->error = 0;
788 }
789
790 if (!data->stop) {
791 atmci_request_end(mmc, host->mrq);
792 prev_state = state;
793 break;
794 }
768 795
769 if (host->mrq && !host->cmd && !host->data) 796 prev_state = state = STATE_SENDING_STOP;
770 atmci_request_end(mmc, host->mrq); 797 if (!data->error)
798 send_stop_cmd(host->mmc, data);
799 /* fall through */
800
801 case STATE_SENDING_STOP:
802 if (!atmci_test_and_clear_pending(host,
803 EVENT_CMD_COMPLETE))
804 break;
805
806 host->cmd = NULL;
807 atmci_command_complete(host, mrq->stop);
808 atmci_request_end(mmc, host->mrq);
809 prev_state = state;
810 break;
811
812 case STATE_DATA_ERROR:
813 if (!atmci_test_and_clear_pending(host,
814 EVENT_XFER_COMPLETE))
815 break;
816
817 state = STATE_DATA_BUSY;
818 break;
819 }
820 } while (state != prev_state);
821
822 host->state = state;
771} 823}
772 824
773static void atmci_read_data_pio(struct atmel_mci *host) 825static void atmci_read_data_pio(struct atmel_mci *host)
@@ -832,10 +884,7 @@ done:
832 mci_writel(host, IDR, MCI_RXRDY); 884 mci_writel(host, IDR, MCI_RXRDY);
833 mci_writel(host, IER, MCI_NOTBUSY); 885 mci_writel(host, IER, MCI_NOTBUSY);
834 data->bytes_xfered += nbytes; 886 data->bytes_xfered += nbytes;
835 atmci_set_completed(host, EVENT_XFER_COMPLETE); 887 atmci_set_pending(host, EVENT_XFER_COMPLETE);
836 if (data->stop && atmci_is_completed(host, EVENT_CMD_COMPLETE)
837 && !atmci_test_and_set_completed(host, EVENT_STOP_SENT))
838 send_stop_cmd(host->mmc, data);
839} 888}
840 889
841static void atmci_write_data_pio(struct atmel_mci *host) 890static void atmci_write_data_pio(struct atmel_mci *host)
@@ -903,10 +952,7 @@ done:
903 mci_writel(host, IDR, MCI_TXRDY); 952 mci_writel(host, IDR, MCI_TXRDY);
904 mci_writel(host, IER, MCI_NOTBUSY); 953 mci_writel(host, IER, MCI_NOTBUSY);
905 data->bytes_xfered += nbytes; 954 data->bytes_xfered += nbytes;
906 atmci_set_completed(host, EVENT_XFER_COMPLETE); 955 atmci_set_pending(host, EVENT_XFER_COMPLETE);
907 if (data->stop && atmci_is_completed(host, EVENT_CMD_COMPLETE)
908 && !atmci_test_and_set_completed(host, EVENT_STOP_SENT))
909 send_stop_cmd(host->mmc, data);
910} 956}
911 957
912static void atmci_cmd_interrupt(struct mmc_host *mmc, u32 status) 958static void atmci_cmd_interrupt(struct mmc_host *mmc, u32 status)
@@ -915,14 +961,8 @@ static void atmci_cmd_interrupt(struct mmc_host *mmc, u32 status)
915 961
916 mci_writel(host, IDR, MCI_CMDRDY); 962 mci_writel(host, IDR, MCI_CMDRDY);
917 963
918 if (atmci_is_completed(host, EVENT_STOP_SENT)) { 964 host->cmd_status = status;
919 host->stop_status = status; 965 atmci_set_pending(host, EVENT_CMD_COMPLETE);
920 atmci_set_pending(host, EVENT_STOP_COMPLETE);
921 } else {
922 host->cmd_status = status;
923 atmci_set_pending(host, EVENT_CMD_COMPLETE);
924 }
925
926 tasklet_schedule(&host->tasklet); 966 tasklet_schedule(&host->tasklet);
927} 967}
928 968
@@ -951,8 +991,9 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
951 tasklet_schedule(&host->tasklet); 991 tasklet_schedule(&host->tasklet);
952 } 992 }
953 if (pending & MCI_NOTBUSY) { 993 if (pending & MCI_NOTBUSY) {
954 mci_writel(host, IDR, (MCI_NOTBUSY 994 mci_writel(host, IDR,
955 | ATMCI_DATA_ERROR_FLAGS)); 995 ATMCI_DATA_ERROR_FLAGS | MCI_NOTBUSY);
996 host->data_status = status;
956 atmci_set_pending(host, EVENT_DATA_COMPLETE); 997 atmci_set_pending(host, EVENT_DATA_COMPLETE);
957 tasklet_schedule(&host->tasklet); 998 tasklet_schedule(&host->tasklet);
958 } 999 }