aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/tifm_sd.c52
1 files changed, 25 insertions, 27 deletions
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index f22c3968f2d4..3e762770afcb 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -103,38 +103,51 @@ struct tifm_sd {
103 wait_queue_head_t can_eject; 103 wait_queue_head_t can_eject;
104 104
105 size_t written_blocks; 105 size_t written_blocks;
106 char *buffer;
107 size_t buffer_size; 106 size_t buffer_size;
108 size_t buffer_pos; 107 size_t buffer_pos;
109 108
110}; 109};
111 110
111static char* tifm_sd_kmap_atomic(struct mmc_data *data)
112{
113 return kmap_atomic(data->sg->page, KM_BIO_SRC_IRQ) + data->sg->offset;
114}
115
116static void tifm_sd_kunmap_atomic(char *buffer, struct mmc_data *data)
117{
118 kunmap_atomic(buffer - data->sg->offset, KM_BIO_SRC_IRQ);
119}
120
112static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host, 121static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host,
113 unsigned int host_status) 122 unsigned int host_status)
114{ 123{
115 struct mmc_command *cmd = host->req->cmd; 124 struct mmc_command *cmd = host->req->cmd;
116 unsigned int t_val = 0, cnt = 0; 125 unsigned int t_val = 0, cnt = 0;
126 char *buffer;
117 127
118 if (host_status & TIFM_MMCSD_BRS) { 128 if (host_status & TIFM_MMCSD_BRS) {
119 /* in non-dma rx mode BRS fires when fifo is still not empty */ 129 /* in non-dma rx mode BRS fires when fifo is still not empty */
120 if (host->buffer && (cmd->data->flags & MMC_DATA_READ)) { 130 if (no_dma && (cmd->data->flags & MMC_DATA_READ)) {
131 buffer = tifm_sd_kmap_atomic(host->req->data);
121 while (host->buffer_size > host->buffer_pos) { 132 while (host->buffer_size > host->buffer_pos) {
122 t_val = readl(sock->addr + SOCK_MMCSD_DATA); 133 t_val = readl(sock->addr + SOCK_MMCSD_DATA);
123 host->buffer[host->buffer_pos++] = t_val & 0xff; 134 buffer[host->buffer_pos++] = t_val & 0xff;
124 host->buffer[host->buffer_pos++] = 135 buffer[host->buffer_pos++] =
125 (t_val >> 8) & 0xff; 136 (t_val >> 8) & 0xff;
126 } 137 }
138 tifm_sd_kunmap_atomic(buffer, host->req->data);
127 } 139 }
128 return 1; 140 return 1;
129 } else if (host->buffer) { 141 } else if (no_dma) {
142 buffer = tifm_sd_kmap_atomic(host->req->data);
130 if ((cmd->data->flags & MMC_DATA_READ) && 143 if ((cmd->data->flags & MMC_DATA_READ) &&
131 (host_status & TIFM_MMCSD_AF)) { 144 (host_status & TIFM_MMCSD_AF)) {
132 for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { 145 for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) {
133 t_val = readl(sock->addr + SOCK_MMCSD_DATA); 146 t_val = readl(sock->addr + SOCK_MMCSD_DATA);
134 if (host->buffer_size > host->buffer_pos) { 147 if (host->buffer_size > host->buffer_pos) {
135 host->buffer[host->buffer_pos++] = 148 buffer[host->buffer_pos++] =
136 t_val & 0xff; 149 t_val & 0xff;
137 host->buffer[host->buffer_pos++] = 150 buffer[host->buffer_pos++] =
138 (t_val >> 8) & 0xff; 151 (t_val >> 8) & 0xff;
139 } 152 }
140 } 153 }
@@ -142,14 +155,16 @@ static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host,
142 && (host_status & TIFM_MMCSD_AE)) { 155 && (host_status & TIFM_MMCSD_AE)) {
143 for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { 156 for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) {
144 if (host->buffer_size > host->buffer_pos) { 157 if (host->buffer_size > host->buffer_pos) {
145 t_val = host->buffer[host->buffer_pos++] & 0x00ff; 158 t_val = buffer[host->buffer_pos++]
146 t_val |= ((host->buffer[host->buffer_pos++]) << 8) 159 & 0x00ff;
147 & 0xff00; 160 t_val |= ((buffer[host->buffer_pos++])
161 << 8) & 0xff00;
148 writel(t_val, 162 writel(t_val,
149 sock->addr + SOCK_MMCSD_DATA); 163 sock->addr + SOCK_MMCSD_DATA);
150 } 164 }
151 } 165 }
152 } 166 }
167 tifm_sd_kunmap_atomic(buffer, host->req->data);
153 } 168 }
154 return 0; 169 return 0;
155} 170}
@@ -561,15 +576,6 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
561 struct tifm_dev *sock = host->dev; 576 struct tifm_dev *sock = host->dev;
562 unsigned long flags; 577 unsigned long flags;
563 struct mmc_data *r_data = mrq->cmd->data; 578 struct mmc_data *r_data = mrq->cmd->data;
564 char *t_buffer = NULL;
565
566 if (r_data) {
567 t_buffer = kmap(r_data->sg->page);
568 if (!t_buffer) {
569 printk(KERN_ERR DRIVER_NAME ": kmap failed\n");
570 goto err_out;
571 }
572 }
573 579
574 spin_lock_irqsave(&sock->lock, flags); 580 spin_lock_irqsave(&sock->lock, flags);
575 if (host->flags & EJECT) { 581 if (host->flags & EJECT) {
@@ -586,7 +592,6 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
586 if (r_data) { 592 if (r_data) {
587 tifm_sd_set_data_timeout(host, r_data); 593 tifm_sd_set_data_timeout(host, r_data);
588 594
589 host->buffer = t_buffer + r_data->sg->offset;
590 host->buffer_size = mrq->cmd->data->blocks * 595 host->buffer_size = mrq->cmd->data->blocks *
591 mrq->cmd->data->blksz; 596 mrq->cmd->data->blksz;
592 597
@@ -615,9 +620,6 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
615 return; 620 return;
616 621
617err_out: 622err_out:
618 if (t_buffer)
619 kunmap(r_data->sg->page);
620
621 mrq->cmd->error = MMC_ERR_TIMEOUT; 623 mrq->cmd->error = MMC_ERR_TIMEOUT;
622 mmc_request_done(mmc, mrq); 624 mmc_request_done(mmc, mrq);
623} 625}
@@ -659,7 +661,6 @@ static void tifm_sd_end_cmd_nodma(struct work_struct *work)
659 r_data->bytes_xfered += r_data->blksz - 661 r_data->bytes_xfered += r_data->blksz -
660 readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; 662 readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
661 } 663 }
662 host->buffer = NULL;
663 host->buffer_pos = 0; 664 host->buffer_pos = 0;
664 host->buffer_size = 0; 665 host->buffer_size = 0;
665 } 666 }
@@ -669,9 +670,6 @@ static void tifm_sd_end_cmd_nodma(struct work_struct *work)
669 670
670 spin_unlock_irqrestore(&sock->lock, flags); 671 spin_unlock_irqrestore(&sock->lock, flags);
671 672
672 if (r_data)
673 kunmap(r_data->sg->page);
674
675 mmc_request_done(mmc, mrq); 673 mmc_request_done(mmc, mrq);
676} 674}
677 675