aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2012-12-12 09:38:11 -0500
committerChris Ball <cjb@laptop.org>2013-02-11 13:28:16 -0500
commit5df460b15e10ffcf2c9a05d0c55b309568d330ea (patch)
tree99815d0aec3ed66676f5429661c95fc51001feb4 /drivers/mmc/host
parenta812ba0fd031c14c7680c94a1a22d5c60c7b6e2b (diff)
mmc: sh_mmcif: fix missing and consolidate IO completion timeouts
Read block and write block operations are currently missing completion timeouts. Add missing timeouts and consolidate them at one location. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/sh_mmcif.c45
1 files changed, 22 insertions, 23 deletions
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 663b92b364bb..f4b10c8f6384 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -564,7 +564,6 @@ static void sh_mmcif_single_read(struct sh_mmcif_host *host,
564 BLOCK_SIZE_MASK) + 3; 564 BLOCK_SIZE_MASK) + 3;
565 565
566 host->wait_for = MMCIF_WAIT_FOR_READ; 566 host->wait_for = MMCIF_WAIT_FOR_READ;
567 schedule_delayed_work(&host->timeout_work, host->timeout);
568 567
569 /* buf read enable */ 568 /* buf read enable */
570 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); 569 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
@@ -606,7 +605,7 @@ static void sh_mmcif_multi_read(struct sh_mmcif_host *host,
606 host->sg_idx = 0; 605 host->sg_idx = 0;
607 host->sg_blkidx = 0; 606 host->sg_blkidx = 0;
608 host->pio_ptr = sg_virt(data->sg); 607 host->pio_ptr = sg_virt(data->sg);
609 schedule_delayed_work(&host->timeout_work, host->timeout); 608
610 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); 609 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
611} 610}
612 611
@@ -629,7 +628,6 @@ static bool sh_mmcif_mread_block(struct sh_mmcif_host *host)
629 if (!sh_mmcif_next_block(host, p)) 628 if (!sh_mmcif_next_block(host, p))
630 return false; 629 return false;
631 630
632 schedule_delayed_work(&host->timeout_work, host->timeout);
633 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); 631 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
634 632
635 return true; 633 return true;
@@ -642,7 +640,6 @@ static void sh_mmcif_single_write(struct sh_mmcif_host *host,
642 BLOCK_SIZE_MASK) + 3; 640 BLOCK_SIZE_MASK) + 3;
643 641
644 host->wait_for = MMCIF_WAIT_FOR_WRITE; 642 host->wait_for = MMCIF_WAIT_FOR_WRITE;
645 schedule_delayed_work(&host->timeout_work, host->timeout);
646 643
647 /* buf write enable */ 644 /* buf write enable */
648 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); 645 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
@@ -684,7 +681,7 @@ static void sh_mmcif_multi_write(struct sh_mmcif_host *host,
684 host->sg_idx = 0; 681 host->sg_idx = 0;
685 host->sg_blkidx = 0; 682 host->sg_blkidx = 0;
686 host->pio_ptr = sg_virt(data->sg); 683 host->pio_ptr = sg_virt(data->sg);
687 schedule_delayed_work(&host->timeout_work, host->timeout); 684
688 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); 685 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
689} 686}
690 687
@@ -707,7 +704,6 @@ static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host)
707 if (!sh_mmcif_next_block(host, p)) 704 if (!sh_mmcif_next_block(host, p))
708 return false; 705 return false;
709 706
710 schedule_delayed_work(&host->timeout_work, host->timeout);
711 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); 707 sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
712 708
713 return true; 709 return true;
@@ -900,7 +896,6 @@ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
900 } 896 }
901 897
902 host->wait_for = MMCIF_WAIT_FOR_STOP; 898 host->wait_for = MMCIF_WAIT_FOR_STOP;
903 schedule_delayed_work(&host->timeout_work, host->timeout);
904} 899}
905 900
906static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) 901static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -1121,6 +1116,7 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
1121{ 1116{
1122 struct sh_mmcif_host *host = dev_id; 1117 struct sh_mmcif_host *host = dev_id;
1123 struct mmc_request *mrq = host->mrq; 1118 struct mmc_request *mrq = host->mrq;
1119 bool wait = false;
1124 1120
1125 cancel_delayed_work_sync(&host->timeout_work); 1121 cancel_delayed_work_sync(&host->timeout_work);
1126 1122
@@ -1133,29 +1129,24 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
1133 /* We're too late, the timeout has already kicked in */ 1129 /* We're too late, the timeout has already kicked in */
1134 return IRQ_HANDLED; 1130 return IRQ_HANDLED;
1135 case MMCIF_WAIT_FOR_CMD: 1131 case MMCIF_WAIT_FOR_CMD:
1136 if (sh_mmcif_end_cmd(host)) 1132 /* Wait for data? */
1137 /* Wait for data */ 1133 wait = sh_mmcif_end_cmd(host);
1138 return IRQ_HANDLED;
1139 break; 1134 break;
1140 case MMCIF_WAIT_FOR_MREAD: 1135 case MMCIF_WAIT_FOR_MREAD:
1141 if (sh_mmcif_mread_block(host)) 1136 /* Wait for more data? */
1142 /* Wait for more data */ 1137 wait = sh_mmcif_mread_block(host);
1143 return IRQ_HANDLED;
1144 break; 1138 break;
1145 case MMCIF_WAIT_FOR_READ: 1139 case MMCIF_WAIT_FOR_READ:
1146 if (sh_mmcif_read_block(host)) 1140 /* Wait for data end? */
1147 /* Wait for data end */ 1141 wait = sh_mmcif_read_block(host);
1148 return IRQ_HANDLED;
1149 break; 1142 break;
1150 case MMCIF_WAIT_FOR_MWRITE: 1143 case MMCIF_WAIT_FOR_MWRITE:
1151 if (sh_mmcif_mwrite_block(host)) 1144 /* Wait data to write? */
1152 /* Wait data to write */ 1145 wait = sh_mmcif_mwrite_block(host);
1153 return IRQ_HANDLED;
1154 break; 1146 break;
1155 case MMCIF_WAIT_FOR_WRITE: 1147 case MMCIF_WAIT_FOR_WRITE:
1156 if (sh_mmcif_write_block(host)) 1148 /* Wait for data end? */
1157 /* Wait for data end */ 1149 wait = sh_mmcif_write_block(host);
1158 return IRQ_HANDLED;
1159 break; 1150 break;
1160 case MMCIF_WAIT_FOR_STOP: 1151 case MMCIF_WAIT_FOR_STOP:
1161 if (host->sd_error) { 1152 if (host->sd_error) {
@@ -1174,6 +1165,12 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
1174 BUG(); 1165 BUG();
1175 } 1166 }
1176 1167
1168 if (wait) {
1169 schedule_delayed_work(&host->timeout_work, host->timeout);
1170 /* Wait for more data */
1171 return IRQ_HANDLED;
1172 }
1173
1177 if (host->wait_for != MMCIF_WAIT_FOR_STOP) { 1174 if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
1178 struct mmc_data *data = mrq->data; 1175 struct mmc_data *data = mrq->data;
1179 if (!mrq->cmd->error && data && !data->error) 1176 if (!mrq->cmd->error && data && !data->error)
@@ -1182,8 +1179,10 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
1182 1179
1183 if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) { 1180 if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) {
1184 sh_mmcif_stop_cmd(host, mrq); 1181 sh_mmcif_stop_cmd(host, mrq);
1185 if (!mrq->stop->error) 1182 if (!mrq->stop->error) {
1183 schedule_delayed_work(&host->timeout_work, host->timeout);
1186 return IRQ_HANDLED; 1184 return IRQ_HANDLED;
1185 }
1187 } 1186 }
1188 } 1187 }
1189 1188