diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2012-12-12 09:38:11 -0500 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-02-11 13:28:16 -0500 |
commit | 5df460b15e10ffcf2c9a05d0c55b309568d330ea (patch) | |
tree | 99815d0aec3ed66676f5429661c95fc51001feb4 /drivers/mmc/host | |
parent | a812ba0fd031c14c7680c94a1a22d5c60c7b6e2b (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.c | 45 |
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 | ||
906 | static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) | 901 | static 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 | ||