diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-05-08 15:41:14 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-05-08 15:41:14 -0400 |
| commit | 1b826a94b6ccc6ac6cf5ad3a36e0d5124146a333 (patch) | |
| tree | 0d039abfb727dae5e4f96663a57ab19fc0cf6c68 | |
| parent | 9f1eb57dc706b98bd775d613570f157b6d888c35 (diff) | |
| parent | 98fcc5762dcecbb264fa4af5a9ae51136858e299 (diff) | |
Merge tag 'mfd-mmc-fixes-3.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull mmc/rtsx revert from Lee Jones.
* tag 'mfd-mmc-fixes-3.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd:
mmc: rtsx: Revert "mmc: rtsx: add support for pre_req and post_req"
| -rw-r--r-- | drivers/mfd/rtsx_pcr.c | 132 | ||||
| -rw-r--r-- | drivers/mmc/host/rtsx_pci_sdmmc.c | 418 | ||||
| -rw-r--r-- | include/linux/mfd/rtsx_common.h | 1 | ||||
| -rw-r--r-- | include/linux/mfd/rtsx_pci.h | 6 |
4 files changed, 109 insertions, 448 deletions
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index c9de3d598ea5..1d15735f9ef9 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c | |||
| @@ -338,28 +338,58 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, | |||
| 338 | int num_sg, bool read, int timeout) | 338 | int num_sg, bool read, int timeout) |
| 339 | { | 339 | { |
| 340 | struct completion trans_done; | 340 | struct completion trans_done; |
| 341 | int err = 0, count; | 341 | u8 dir; |
| 342 | int err = 0, i, count; | ||
| 342 | long timeleft; | 343 | long timeleft; |
| 343 | unsigned long flags; | 344 | unsigned long flags; |
| 345 | struct scatterlist *sg; | ||
| 346 | enum dma_data_direction dma_dir; | ||
| 347 | u32 val; | ||
| 348 | dma_addr_t addr; | ||
| 349 | unsigned int len; | ||
| 350 | |||
| 351 | dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); | ||
| 352 | |||
| 353 | /* don't transfer data during abort processing */ | ||
| 354 | if (pcr->remove_pci) | ||
| 355 | return -EINVAL; | ||
| 356 | |||
| 357 | if ((sglist == NULL) || (num_sg <= 0)) | ||
| 358 | return -EINVAL; | ||
| 344 | 359 | ||
| 345 | count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read); | 360 | if (read) { |
| 361 | dir = DEVICE_TO_HOST; | ||
| 362 | dma_dir = DMA_FROM_DEVICE; | ||
| 363 | } else { | ||
| 364 | dir = HOST_TO_DEVICE; | ||
| 365 | dma_dir = DMA_TO_DEVICE; | ||
| 366 | } | ||
| 367 | |||
| 368 | count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); | ||
| 346 | if (count < 1) { | 369 | if (count < 1) { |
| 347 | dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); | 370 | dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); |
| 348 | return -EINVAL; | 371 | return -EINVAL; |
| 349 | } | 372 | } |
| 350 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); | 373 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); |
| 351 | 374 | ||
| 375 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; | ||
| 376 | pcr->sgi = 0; | ||
| 377 | for_each_sg(sglist, sg, count, i) { | ||
| 378 | addr = sg_dma_address(sg); | ||
| 379 | len = sg_dma_len(sg); | ||
| 380 | rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1); | ||
| 381 | } | ||
| 352 | 382 | ||
| 353 | spin_lock_irqsave(&pcr->lock, flags); | 383 | spin_lock_irqsave(&pcr->lock, flags); |
| 354 | 384 | ||
| 355 | pcr->done = &trans_done; | 385 | pcr->done = &trans_done; |
| 356 | pcr->trans_result = TRANS_NOT_READY; | 386 | pcr->trans_result = TRANS_NOT_READY; |
| 357 | init_completion(&trans_done); | 387 | init_completion(&trans_done); |
| 388 | rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr); | ||
| 389 | rtsx_pci_writel(pcr, RTSX_HDBCTLR, val); | ||
| 358 | 390 | ||
| 359 | spin_unlock_irqrestore(&pcr->lock, flags); | 391 | spin_unlock_irqrestore(&pcr->lock, flags); |
| 360 | 392 | ||
| 361 | rtsx_pci_dma_transfer(pcr, sglist, count, read); | ||
| 362 | |||
| 363 | timeleft = wait_for_completion_interruptible_timeout( | 393 | timeleft = wait_for_completion_interruptible_timeout( |
| 364 | &trans_done, msecs_to_jiffies(timeout)); | 394 | &trans_done, msecs_to_jiffies(timeout)); |
| 365 | if (timeleft <= 0) { | 395 | if (timeleft <= 0) { |
| @@ -383,7 +413,7 @@ out: | |||
| 383 | pcr->done = NULL; | 413 | pcr->done = NULL; |
| 384 | spin_unlock_irqrestore(&pcr->lock, flags); | 414 | spin_unlock_irqrestore(&pcr->lock, flags); |
| 385 | 415 | ||
| 386 | rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read); | 416 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); |
| 387 | 417 | ||
| 388 | if ((err < 0) && (err != -ENODEV)) | 418 | if ((err < 0) && (err != -ENODEV)) |
| 389 | rtsx_pci_stop_cmd(pcr); | 419 | rtsx_pci_stop_cmd(pcr); |
| @@ -395,73 +425,6 @@ out: | |||
| 395 | } | 425 | } |
| 396 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); | 426 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); |
| 397 | 427 | ||
| 398 | int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
| 399 | int num_sg, bool read) | ||
| 400 | { | ||
| 401 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
| 402 | |||
| 403 | if (pcr->remove_pci) | ||
| 404 | return -EINVAL; | ||
| 405 | |||
| 406 | if ((sglist == NULL) || num_sg < 1) | ||
| 407 | return -EINVAL; | ||
| 408 | |||
| 409 | return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir); | ||
| 410 | } | ||
| 411 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg); | ||
| 412 | |||
| 413 | int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
| 414 | int num_sg, bool read) | ||
| 415 | { | ||
| 416 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
| 417 | |||
| 418 | if (pcr->remove_pci) | ||
| 419 | return -EINVAL; | ||
| 420 | |||
| 421 | if (sglist == NULL || num_sg < 1) | ||
| 422 | return -EINVAL; | ||
| 423 | |||
| 424 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir); | ||
| 425 | return num_sg; | ||
| 426 | } | ||
| 427 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg); | ||
| 428 | |||
| 429 | int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
| 430 | int sg_count, bool read) | ||
| 431 | { | ||
| 432 | struct scatterlist *sg; | ||
| 433 | dma_addr_t addr; | ||
| 434 | unsigned int len; | ||
| 435 | int i; | ||
| 436 | u32 val; | ||
| 437 | u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE; | ||
| 438 | unsigned long flags; | ||
| 439 | |||
| 440 | if (pcr->remove_pci) | ||
| 441 | return -EINVAL; | ||
| 442 | |||
| 443 | if ((sglist == NULL) || (sg_count < 1)) | ||
| 444 | return -EINVAL; | ||
| 445 | |||
| 446 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; | ||
| 447 | pcr->sgi = 0; | ||
| 448 | for_each_sg(sglist, sg, sg_count, i) { | ||
| 449 | addr = sg_dma_address(sg); | ||
| 450 | len = sg_dma_len(sg); | ||
| 451 | rtsx_pci_add_sg_tbl(pcr, addr, len, i == sg_count - 1); | ||
| 452 | } | ||
| 453 | |||
| 454 | spin_lock_irqsave(&pcr->lock, flags); | ||
| 455 | |||
| 456 | rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr); | ||
| 457 | rtsx_pci_writel(pcr, RTSX_HDBCTLR, val); | ||
| 458 | |||
| 459 | spin_unlock_irqrestore(&pcr->lock, flags); | ||
| 460 | |||
| 461 | return 0; | ||
| 462 | } | ||
| 463 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer); | ||
| 464 | |||
| 465 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) | 428 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) |
| 466 | { | 429 | { |
| 467 | int err; | 430 | int err; |
| @@ -873,8 +836,6 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
| 873 | int_reg = rtsx_pci_readl(pcr, RTSX_BIPR); | 836 | int_reg = rtsx_pci_readl(pcr, RTSX_BIPR); |
| 874 | /* Clear interrupt flag */ | 837 | /* Clear interrupt flag */ |
| 875 | rtsx_pci_writel(pcr, RTSX_BIPR, int_reg); | 838 | rtsx_pci_writel(pcr, RTSX_BIPR, int_reg); |
| 876 | dev_dbg(&pcr->pci->dev, "=========== BIPR 0x%8x ==========\n", int_reg); | ||
| 877 | |||
| 878 | if ((int_reg & pcr->bier) == 0) { | 839 | if ((int_reg & pcr->bier) == 0) { |
| 879 | spin_unlock(&pcr->lock); | 840 | spin_unlock(&pcr->lock); |
| 880 | return IRQ_NONE; | 841 | return IRQ_NONE; |
| @@ -905,28 +866,17 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
| 905 | } | 866 | } |
| 906 | 867 | ||
| 907 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { | 868 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { |
| 908 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) | 869 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) { |
| 909 | pcr->trans_result = TRANS_RESULT_FAIL; | 870 | pcr->trans_result = TRANS_RESULT_FAIL; |
| 910 | else if (int_reg & TRANS_OK_INT) | 871 | if (pcr->done) |
| 872 | complete(pcr->done); | ||
| 873 | } else if (int_reg & TRANS_OK_INT) { | ||
| 911 | pcr->trans_result = TRANS_RESULT_OK; | 874 | pcr->trans_result = TRANS_RESULT_OK; |
| 912 | 875 | if (pcr->done) | |
| 913 | if (pcr->done) | 876 | complete(pcr->done); |
| 914 | complete(pcr->done); | ||
| 915 | |||
| 916 | if (int_reg & SD_EXIST) { | ||
| 917 | struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD]; | ||
| 918 | if (slot && slot->done_transfer) | ||
| 919 | slot->done_transfer(slot->p_dev); | ||
| 920 | } | ||
| 921 | |||
| 922 | if (int_reg & MS_EXIST) { | ||
| 923 | struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD]; | ||
| 924 | if (slot && slot->done_transfer) | ||
| 925 | slot->done_transfer(slot->p_dev); | ||
| 926 | } | 877 | } |
| 927 | } | 878 | } |
| 928 | 879 | ||
| 929 | |||
| 930 | if (pcr->card_inserted || pcr->card_removed) | 880 | if (pcr->card_inserted || pcr->card_removed) |
| 931 | schedule_delayed_work(&pcr->carddet_work, | 881 | schedule_delayed_work(&pcr->carddet_work, |
| 932 | msecs_to_jiffies(200)); | 882 | msecs_to_jiffies(200)); |
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 5fb994f9a653..0b9ded13a3ae 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c | |||
| @@ -31,28 +31,14 @@ | |||
| 31 | #include <linux/mfd/rtsx_pci.h> | 31 | #include <linux/mfd/rtsx_pci.h> |
| 32 | #include <asm/unaligned.h> | 32 | #include <asm/unaligned.h> |
| 33 | 33 | ||
| 34 | struct realtek_next { | ||
| 35 | unsigned int sg_count; | ||
| 36 | s32 cookie; | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct realtek_pci_sdmmc { | 34 | struct realtek_pci_sdmmc { |
| 40 | struct platform_device *pdev; | 35 | struct platform_device *pdev; |
| 41 | struct rtsx_pcr *pcr; | 36 | struct rtsx_pcr *pcr; |
| 42 | struct mmc_host *mmc; | 37 | struct mmc_host *mmc; |
| 43 | struct mmc_request *mrq; | 38 | struct mmc_request *mrq; |
| 44 | struct mmc_command *cmd; | 39 | |
| 45 | struct mmc_data *data; | 40 | struct mutex host_mutex; |
| 46 | 41 | ||
| 47 | spinlock_t lock; | ||
| 48 | struct timer_list timer; | ||
| 49 | struct tasklet_struct cmd_tasklet; | ||
| 50 | struct tasklet_struct data_tasklet; | ||
| 51 | struct tasklet_struct finish_tasklet; | ||
| 52 | |||
| 53 | u8 rsp_type; | ||
| 54 | u8 rsp_len; | ||
| 55 | int sg_count; | ||
| 56 | u8 ssc_depth; | 42 | u8 ssc_depth; |
| 57 | unsigned int clock; | 43 | unsigned int clock; |
| 58 | bool vpclk; | 44 | bool vpclk; |
| @@ -62,13 +48,8 @@ struct realtek_pci_sdmmc { | |||
| 62 | int power_state; | 48 | int power_state; |
| 63 | #define SDMMC_POWER_ON 1 | 49 | #define SDMMC_POWER_ON 1 |
| 64 | #define SDMMC_POWER_OFF 0 | 50 | #define SDMMC_POWER_OFF 0 |
| 65 | |||
| 66 | struct realtek_next next_data; | ||
| 67 | }; | 51 | }; |
| 68 | 52 | ||
| 69 | static int sd_start_multi_rw(struct realtek_pci_sdmmc *host, | ||
| 70 | struct mmc_request *mrq); | ||
| 71 | |||
| 72 | static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host) | 53 | static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host) |
| 73 | { | 54 | { |
| 74 | return &(host->pdev->dev); | 55 | return &(host->pdev->dev); |
| @@ -105,95 +86,6 @@ static void sd_print_debug_regs(struct realtek_pci_sdmmc *host) | |||
| 105 | #define sd_print_debug_regs(host) | 86 | #define sd_print_debug_regs(host) |
| 106 | #endif /* DEBUG */ | 87 | #endif /* DEBUG */ |
| 107 | 88 | ||
| 108 | static void sd_isr_done_transfer(struct platform_device *pdev) | ||
| 109 | { | ||
| 110 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); | ||
| 111 | |||
| 112 | spin_lock(&host->lock); | ||
| 113 | if (host->cmd) | ||
| 114 | tasklet_schedule(&host->cmd_tasklet); | ||
| 115 | if (host->data) | ||
| 116 | tasklet_schedule(&host->data_tasklet); | ||
| 117 | spin_unlock(&host->lock); | ||
| 118 | } | ||
| 119 | |||
| 120 | static void sd_request_timeout(unsigned long host_addr) | ||
| 121 | { | ||
| 122 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
| 123 | unsigned long flags; | ||
| 124 | |||
| 125 | spin_lock_irqsave(&host->lock, flags); | ||
| 126 | |||
| 127 | if (!host->mrq) { | ||
| 128 | dev_err(sdmmc_dev(host), "error: no request exist\n"); | ||
| 129 | goto out; | ||
| 130 | } | ||
| 131 | |||
| 132 | if (host->cmd) | ||
| 133 | host->cmd->error = -ETIMEDOUT; | ||
| 134 | if (host->data) | ||
| 135 | host->data->error = -ETIMEDOUT; | ||
| 136 | |||
| 137 | dev_dbg(sdmmc_dev(host), "timeout for request\n"); | ||
| 138 | |||
| 139 | out: | ||
| 140 | tasklet_schedule(&host->finish_tasklet); | ||
| 141 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 142 | } | ||
| 143 | |||
| 144 | static void sd_finish_request(unsigned long host_addr) | ||
| 145 | { | ||
| 146 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
| 147 | struct rtsx_pcr *pcr = host->pcr; | ||
| 148 | struct mmc_request *mrq; | ||
| 149 | struct mmc_command *cmd; | ||
| 150 | struct mmc_data *data; | ||
| 151 | unsigned long flags; | ||
| 152 | bool any_error; | ||
| 153 | |||
| 154 | spin_lock_irqsave(&host->lock, flags); | ||
| 155 | |||
| 156 | del_timer(&host->timer); | ||
| 157 | mrq = host->mrq; | ||
| 158 | if (!mrq) { | ||
| 159 | dev_err(sdmmc_dev(host), "error: no request need finish\n"); | ||
| 160 | goto out; | ||
| 161 | } | ||
| 162 | |||
| 163 | cmd = mrq->cmd; | ||
| 164 | data = mrq->data; | ||
| 165 | |||
| 166 | any_error = (mrq->sbc && mrq->sbc->error) || | ||
| 167 | (mrq->stop && mrq->stop->error) || | ||
| 168 | (cmd && cmd->error) || (data && data->error); | ||
| 169 | |||
| 170 | if (any_error) { | ||
| 171 | rtsx_pci_stop_cmd(pcr); | ||
| 172 | sd_clear_error(host); | ||
| 173 | } | ||
| 174 | |||
| 175 | if (data) { | ||
| 176 | if (any_error) | ||
| 177 | data->bytes_xfered = 0; | ||
| 178 | else | ||
| 179 | data->bytes_xfered = data->blocks * data->blksz; | ||
| 180 | |||
| 181 | if (!data->host_cookie) | ||
| 182 | rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len, | ||
| 183 | data->flags & MMC_DATA_READ); | ||
| 184 | |||
| 185 | } | ||
| 186 | |||
| 187 | host->mrq = NULL; | ||
| 188 | host->cmd = NULL; | ||
| 189 | host->data = NULL; | ||
| 190 | |||
| 191 | out: | ||
| 192 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 193 | mutex_unlock(&pcr->pcr_mutex); | ||
| 194 | mmc_request_done(host->mmc, mrq); | ||
| 195 | } | ||
| 196 | |||
| 197 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | 89 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, |
| 198 | u8 *buf, int buf_len, int timeout) | 90 | u8 *buf, int buf_len, int timeout) |
| 199 | { | 91 | { |
| @@ -311,7 +203,8 @@ static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | |||
| 311 | return 0; | 203 | return 0; |
| 312 | } | 204 | } |
| 313 | 205 | ||
| 314 | static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) | 206 | static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, |
| 207 | struct mmc_command *cmd) | ||
| 315 | { | 208 | { |
| 316 | struct rtsx_pcr *pcr = host->pcr; | 209 | struct rtsx_pcr *pcr = host->pcr; |
| 317 | u8 cmd_idx = (u8)cmd->opcode; | 210 | u8 cmd_idx = (u8)cmd->opcode; |
| @@ -319,14 +212,11 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) | |||
| 319 | int err = 0; | 212 | int err = 0; |
| 320 | int timeout = 100; | 213 | int timeout = 100; |
| 321 | int i; | 214 | int i; |
| 215 | u8 *ptr; | ||
| 216 | int stat_idx = 0; | ||
| 322 | u8 rsp_type; | 217 | u8 rsp_type; |
| 323 | int rsp_len = 5; | 218 | int rsp_len = 5; |
| 324 | unsigned long flags; | 219 | bool clock_toggled = false; |
| 325 | |||
| 326 | if (host->cmd) | ||
| 327 | dev_err(sdmmc_dev(host), "error: cmd already exist\n"); | ||
| 328 | |||
| 329 | host->cmd = cmd; | ||
| 330 | 220 | ||
| 331 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | 221 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", |
| 332 | __func__, cmd_idx, arg); | 222 | __func__, cmd_idx, arg); |
| @@ -361,8 +251,6 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) | |||
| 361 | err = -EINVAL; | 251 | err = -EINVAL; |
| 362 | goto out; | 252 | goto out; |
| 363 | } | 253 | } |
| 364 | host->rsp_type = rsp_type; | ||
| 365 | host->rsp_len = rsp_len; | ||
| 366 | 254 | ||
| 367 | if (rsp_type == SD_RSP_TYPE_R1b) | 255 | if (rsp_type == SD_RSP_TYPE_R1b) |
| 368 | timeout = 3000; | 256 | timeout = 3000; |
| @@ -372,6 +260,8 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) | |||
| 372 | 0xFF, SD_CLK_TOGGLE_EN); | 260 | 0xFF, SD_CLK_TOGGLE_EN); |
| 373 | if (err < 0) | 261 | if (err < 0) |
| 374 | goto out; | 262 | goto out; |
| 263 | |||
| 264 | clock_toggled = true; | ||
| 375 | } | 265 | } |
| 376 | 266 | ||
| 377 | rtsx_pci_init_cmd(pcr); | 267 | rtsx_pci_init_cmd(pcr); |
| @@ -395,60 +285,25 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) | |||
| 395 | /* Read data from ping-pong buffer */ | 285 | /* Read data from ping-pong buffer */ |
| 396 | for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) | 286 | for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) |
| 397 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); | 287 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); |
| 288 | stat_idx = 16; | ||
| 398 | } else if (rsp_type != SD_RSP_TYPE_R0) { | 289 | } else if (rsp_type != SD_RSP_TYPE_R0) { |
| 399 | /* Read data from SD_CMDx registers */ | 290 | /* Read data from SD_CMDx registers */ |
| 400 | for (i = SD_CMD0; i <= SD_CMD4; i++) | 291 | for (i = SD_CMD0; i <= SD_CMD4; i++) |
| 401 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); | 292 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); |
| 293 | stat_idx = 5; | ||
| 402 | } | 294 | } |
| 403 | 295 | ||
| 404 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); | 296 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); |
| 405 | 297 | ||
| 406 | mod_timer(&host->timer, jiffies + msecs_to_jiffies(timeout)); | 298 | err = rtsx_pci_send_cmd(pcr, timeout); |
| 407 | 299 | if (err < 0) { | |
| 408 | spin_lock_irqsave(&pcr->lock, flags); | 300 | sd_print_debug_regs(host); |
| 409 | pcr->trans_result = TRANS_NOT_READY; | 301 | sd_clear_error(host); |
| 410 | rtsx_pci_send_cmd_no_wait(pcr); | 302 | dev_dbg(sdmmc_dev(host), |
| 411 | spin_unlock_irqrestore(&pcr->lock, flags); | 303 | "rtsx_pci_send_cmd error (err = %d)\n", err); |
| 412 | |||
| 413 | return; | ||
| 414 | |||
| 415 | out: | ||
| 416 | cmd->error = err; | ||
| 417 | tasklet_schedule(&host->finish_tasklet); | ||
| 418 | } | ||
| 419 | |||
| 420 | static void sd_get_rsp(unsigned long host_addr) | ||
| 421 | { | ||
| 422 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
| 423 | struct rtsx_pcr *pcr = host->pcr; | ||
| 424 | struct mmc_command *cmd; | ||
| 425 | int i, err = 0, stat_idx; | ||
| 426 | u8 *ptr, rsp_type; | ||
| 427 | unsigned long flags; | ||
| 428 | |||
| 429 | spin_lock_irqsave(&host->lock, flags); | ||
| 430 | |||
| 431 | cmd = host->cmd; | ||
| 432 | host->cmd = NULL; | ||
| 433 | |||
| 434 | if (!cmd) { | ||
| 435 | dev_err(sdmmc_dev(host), "error: cmd not exist\n"); | ||
| 436 | goto out; | 304 | goto out; |
| 437 | } | 305 | } |
| 438 | 306 | ||
| 439 | spin_lock(&pcr->lock); | ||
| 440 | if (pcr->trans_result == TRANS_NO_DEVICE) | ||
| 441 | err = -ENODEV; | ||
| 442 | else if (pcr->trans_result != TRANS_RESULT_OK) | ||
| 443 | err = -EINVAL; | ||
| 444 | spin_unlock(&pcr->lock); | ||
| 445 | |||
| 446 | if (err < 0) | ||
| 447 | goto out; | ||
| 448 | |||
| 449 | rsp_type = host->rsp_type; | ||
| 450 | stat_idx = host->rsp_len; | ||
| 451 | |||
| 452 | if (rsp_type == SD_RSP_TYPE_R0) { | 307 | if (rsp_type == SD_RSP_TYPE_R0) { |
| 453 | err = 0; | 308 | err = 0; |
| 454 | goto out; | 309 | goto out; |
| @@ -485,106 +340,26 @@ static void sd_get_rsp(unsigned long host_addr) | |||
| 485 | cmd->resp[0]); | 340 | cmd->resp[0]); |
| 486 | } | 341 | } |
| 487 | 342 | ||
| 488 | if (cmd == host->mrq->sbc) { | ||
| 489 | sd_send_cmd(host, host->mrq->cmd); | ||
| 490 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 491 | return; | ||
| 492 | } | ||
| 493 | |||
| 494 | if (cmd == host->mrq->stop) | ||
| 495 | goto out; | ||
| 496 | |||
| 497 | if (cmd->data) { | ||
| 498 | sd_start_multi_rw(host, host->mrq); | ||
| 499 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 500 | return; | ||
| 501 | } | ||
| 502 | |||
| 503 | out: | 343 | out: |
| 504 | cmd->error = err; | 344 | cmd->error = err; |
| 505 | 345 | ||
| 506 | tasklet_schedule(&host->finish_tasklet); | 346 | if (err && clock_toggled) |
| 507 | spin_unlock_irqrestore(&host->lock, flags); | 347 | rtsx_pci_write_register(pcr, SD_BUS_STAT, |
| 508 | } | 348 | SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); |
| 509 | |||
| 510 | static int sd_pre_dma_transfer(struct realtek_pci_sdmmc *host, | ||
| 511 | struct mmc_data *data, struct realtek_next *next) | ||
| 512 | { | ||
| 513 | struct rtsx_pcr *pcr = host->pcr; | ||
| 514 | int read = data->flags & MMC_DATA_READ; | ||
| 515 | int sg_count = 0; | ||
| 516 | |||
| 517 | if (!next && data->host_cookie && | ||
| 518 | data->host_cookie != host->next_data.cookie) { | ||
| 519 | dev_err(sdmmc_dev(host), | ||
| 520 | "error: invalid cookie data[%d] host[%d]\n", | ||
| 521 | data->host_cookie, host->next_data.cookie); | ||
| 522 | data->host_cookie = 0; | ||
| 523 | } | ||
| 524 | |||
| 525 | if (next || (!next && data->host_cookie != host->next_data.cookie)) | ||
| 526 | sg_count = rtsx_pci_dma_map_sg(pcr, | ||
| 527 | data->sg, data->sg_len, read); | ||
| 528 | else | ||
| 529 | sg_count = host->next_data.sg_count; | ||
| 530 | |||
| 531 | if (next) { | ||
| 532 | next->sg_count = sg_count; | ||
| 533 | if (++next->cookie < 0) | ||
| 534 | next->cookie = 1; | ||
| 535 | data->host_cookie = next->cookie; | ||
| 536 | } | ||
| 537 | |||
| 538 | return sg_count; | ||
| 539 | } | ||
| 540 | |||
| 541 | static void sdmmc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
| 542 | bool is_first_req) | ||
| 543 | { | ||
| 544 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | ||
| 545 | struct mmc_data *data = mrq->data; | ||
| 546 | |||
| 547 | if (data->host_cookie) { | ||
| 548 | dev_err(sdmmc_dev(host), | ||
| 549 | "error: descard already cookie data[%d]\n", | ||
| 550 | data->host_cookie); | ||
| 551 | data->host_cookie = 0; | ||
| 552 | } | ||
| 553 | |||
| 554 | dev_dbg(sdmmc_dev(host), "dma sg prepared: %d\n", | ||
| 555 | sd_pre_dma_transfer(host, data, &host->next_data)); | ||
| 556 | } | ||
| 557 | |||
| 558 | static void sdmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
| 559 | int err) | ||
| 560 | { | ||
| 561 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | ||
| 562 | struct rtsx_pcr *pcr = host->pcr; | ||
| 563 | struct mmc_data *data = mrq->data; | ||
| 564 | int read = data->flags & MMC_DATA_READ; | ||
| 565 | |||
| 566 | rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len, read); | ||
| 567 | data->host_cookie = 0; | ||
| 568 | } | 349 | } |
| 569 | 350 | ||
| 570 | static int sd_start_multi_rw(struct realtek_pci_sdmmc *host, | 351 | static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) |
| 571 | struct mmc_request *mrq) | ||
| 572 | { | 352 | { |
| 573 | struct rtsx_pcr *pcr = host->pcr; | 353 | struct rtsx_pcr *pcr = host->pcr; |
| 574 | struct mmc_host *mmc = host->mmc; | 354 | struct mmc_host *mmc = host->mmc; |
| 575 | struct mmc_card *card = mmc->card; | 355 | struct mmc_card *card = mmc->card; |
| 576 | struct mmc_data *data = mrq->data; | 356 | struct mmc_data *data = mrq->data; |
| 577 | int uhs = mmc_card_uhs(card); | 357 | int uhs = mmc_card_uhs(card); |
| 578 | int read = data->flags & MMC_DATA_READ; | 358 | int read = (data->flags & MMC_DATA_READ) ? 1 : 0; |
| 579 | u8 cfg2, trans_mode; | 359 | u8 cfg2, trans_mode; |
| 580 | int err; | 360 | int err; |
| 581 | size_t data_len = data->blksz * data->blocks; | 361 | size_t data_len = data->blksz * data->blocks; |
| 582 | 362 | ||
| 583 | if (host->data) | ||
| 584 | dev_err(sdmmc_dev(host), "error: data already exist\n"); | ||
| 585 | |||
| 586 | host->data = data; | ||
| 587 | |||
| 588 | if (read) { | 363 | if (read) { |
| 589 | cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 364 | cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | |
| 590 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0; | 365 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0; |
| @@ -635,54 +410,15 @@ static int sd_start_multi_rw(struct realtek_pci_sdmmc *host, | |||
| 635 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | 410 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, |
| 636 | SD_TRANSFER_END, SD_TRANSFER_END); | 411 | SD_TRANSFER_END, SD_TRANSFER_END); |
| 637 | 412 | ||
| 638 | mod_timer(&host->timer, jiffies + 10 * HZ); | ||
| 639 | rtsx_pci_send_cmd_no_wait(pcr); | 413 | rtsx_pci_send_cmd_no_wait(pcr); |
| 640 | 414 | ||
| 641 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, read); | 415 | err = rtsx_pci_transfer_data(pcr, data->sg, data->sg_len, read, 10000); |
| 642 | if (err < 0) { | ||
| 643 | data->error = err; | ||
| 644 | tasklet_schedule(&host->finish_tasklet); | ||
| 645 | } | ||
| 646 | return 0; | ||
| 647 | } | ||
| 648 | |||
| 649 | static void sd_finish_multi_rw(unsigned long host_addr) | ||
| 650 | { | ||
| 651 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
| 652 | struct rtsx_pcr *pcr = host->pcr; | ||
| 653 | struct mmc_data *data; | ||
| 654 | int err = 0; | ||
| 655 | unsigned long flags; | ||
| 656 | |||
| 657 | spin_lock_irqsave(&host->lock, flags); | ||
| 658 | |||
| 659 | if (!host->data) { | ||
| 660 | dev_err(sdmmc_dev(host), "error: no data exist\n"); | ||
| 661 | goto out; | ||
| 662 | } | ||
| 663 | |||
| 664 | data = host->data; | ||
| 665 | host->data = NULL; | ||
| 666 | |||
| 667 | if (pcr->trans_result == TRANS_NO_DEVICE) | ||
| 668 | err = -ENODEV; | ||
| 669 | else if (pcr->trans_result != TRANS_RESULT_OK) | ||
| 670 | err = -EINVAL; | ||
| 671 | |||
| 672 | if (err < 0) { | 416 | if (err < 0) { |
| 673 | data->error = err; | 417 | sd_clear_error(host); |
| 674 | goto out; | 418 | return err; |
| 675 | } | ||
| 676 | |||
| 677 | if (!host->mrq->sbc && data->stop) { | ||
| 678 | sd_send_cmd(host, data->stop); | ||
| 679 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 680 | return; | ||
| 681 | } | 419 | } |
| 682 | 420 | ||
| 683 | out: | 421 | return 0; |
| 684 | tasklet_schedule(&host->finish_tasklet); | ||
| 685 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 686 | } | 422 | } |
| 687 | 423 | ||
| 688 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) | 424 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) |
| @@ -901,13 +637,6 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode) | |||
| 901 | return 0; | 637 | return 0; |
| 902 | } | 638 | } |
| 903 | 639 | ||
| 904 | static inline bool sd_use_muti_rw(struct mmc_command *cmd) | ||
| 905 | { | ||
| 906 | return mmc_op_multi(cmd->opcode) || | ||
| 907 | (cmd->opcode == MMC_READ_SINGLE_BLOCK) || | ||
| 908 | (cmd->opcode == MMC_WRITE_BLOCK); | ||
| 909 | } | ||
| 910 | |||
| 911 | static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | 640 | static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) |
| 912 | { | 641 | { |
| 913 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | 642 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); |
| @@ -916,14 +645,6 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 916 | struct mmc_data *data = mrq->data; | 645 | struct mmc_data *data = mrq->data; |
| 917 | unsigned int data_size = 0; | 646 | unsigned int data_size = 0; |
| 918 | int err; | 647 | int err; |
| 919 | unsigned long flags; | ||
| 920 | |||
| 921 | mutex_lock(&pcr->pcr_mutex); | ||
| 922 | spin_lock_irqsave(&host->lock, flags); | ||
| 923 | |||
| 924 | if (host->mrq) | ||
| 925 | dev_err(sdmmc_dev(host), "error: request already exist\n"); | ||
| 926 | host->mrq = mrq; | ||
| 927 | 648 | ||
| 928 | if (host->eject) { | 649 | if (host->eject) { |
| 929 | cmd->error = -ENOMEDIUM; | 650 | cmd->error = -ENOMEDIUM; |
| @@ -936,6 +657,8 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 936 | goto finish; | 657 | goto finish; |
| 937 | } | 658 | } |
| 938 | 659 | ||
| 660 | mutex_lock(&pcr->pcr_mutex); | ||
| 661 | |||
| 939 | rtsx_pci_start_run(pcr); | 662 | rtsx_pci_start_run(pcr); |
| 940 | 663 | ||
| 941 | rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth, | 664 | rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth, |
| @@ -944,28 +667,46 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 944 | rtsx_pci_write_register(pcr, CARD_SHARE_MODE, | 667 | rtsx_pci_write_register(pcr, CARD_SHARE_MODE, |
| 945 | CARD_SHARE_MASK, CARD_SHARE_48_SD); | 668 | CARD_SHARE_MASK, CARD_SHARE_48_SD); |
| 946 | 669 | ||
| 670 | mutex_lock(&host->host_mutex); | ||
| 671 | host->mrq = mrq; | ||
| 672 | mutex_unlock(&host->host_mutex); | ||
| 673 | |||
| 947 | if (mrq->data) | 674 | if (mrq->data) |
| 948 | data_size = data->blocks * data->blksz; | 675 | data_size = data->blocks * data->blksz; |
| 949 | 676 | ||
| 950 | if (sd_use_muti_rw(cmd)) | 677 | if (!data_size || mmc_op_multi(cmd->opcode) || |
| 951 | host->sg_count = sd_pre_dma_transfer(host, data, NULL); | 678 | (cmd->opcode == MMC_READ_SINGLE_BLOCK) || |
| 679 | (cmd->opcode == MMC_WRITE_BLOCK)) { | ||
| 680 | sd_send_cmd_get_rsp(host, cmd); | ||
| 952 | 681 | ||
| 953 | if (!data_size || sd_use_muti_rw(cmd)) { | 682 | if (!cmd->error && data_size) { |
| 954 | if (mrq->sbc) | 683 | sd_rw_multi(host, mrq); |
| 955 | sd_send_cmd(host, mrq->sbc); | 684 | |
| 956 | else | 685 | if (mmc_op_multi(cmd->opcode) && mrq->stop) |
| 957 | sd_send_cmd(host, cmd); | 686 | sd_send_cmd_get_rsp(host, mrq->stop); |
| 958 | spin_unlock_irqrestore(&host->lock, flags); | 687 | } |
| 959 | } else { | 688 | } else { |
| 960 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 961 | sd_normal_rw(host, mrq); | 689 | sd_normal_rw(host, mrq); |
| 962 | tasklet_schedule(&host->finish_tasklet); | ||
| 963 | } | 690 | } |
| 964 | return; | 691 | |
| 692 | if (mrq->data) { | ||
| 693 | if (cmd->error || data->error) | ||
| 694 | data->bytes_xfered = 0; | ||
| 695 | else | ||
| 696 | data->bytes_xfered = data->blocks * data->blksz; | ||
| 697 | } | ||
| 698 | |||
| 699 | mutex_unlock(&pcr->pcr_mutex); | ||
| 965 | 700 | ||
| 966 | finish: | 701 | finish: |
| 967 | tasklet_schedule(&host->finish_tasklet); | 702 | if (cmd->error) |
| 968 | spin_unlock_irqrestore(&host->lock, flags); | 703 | dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error); |
| 704 | |||
| 705 | mutex_lock(&host->host_mutex); | ||
| 706 | host->mrq = NULL; | ||
| 707 | mutex_unlock(&host->host_mutex); | ||
| 708 | |||
| 709 | mmc_request_done(mmc, mrq); | ||
| 969 | } | 710 | } |
| 970 | 711 | ||
| 971 | static int sd_set_bus_width(struct realtek_pci_sdmmc *host, | 712 | static int sd_set_bus_width(struct realtek_pci_sdmmc *host, |
| @@ -1400,8 +1141,6 @@ out: | |||
| 1400 | } | 1141 | } |
| 1401 | 1142 | ||
| 1402 | static const struct mmc_host_ops realtek_pci_sdmmc_ops = { | 1143 | static const struct mmc_host_ops realtek_pci_sdmmc_ops = { |
| 1403 | .pre_req = sdmmc_pre_req, | ||
| 1404 | .post_req = sdmmc_post_req, | ||
| 1405 | .request = sdmmc_request, | 1144 | .request = sdmmc_request, |
| 1406 | .set_ios = sdmmc_set_ios, | 1145 | .set_ios = sdmmc_set_ios, |
| 1407 | .get_ro = sdmmc_get_ro, | 1146 | .get_ro = sdmmc_get_ro, |
| @@ -1465,7 +1204,6 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
| 1465 | struct realtek_pci_sdmmc *host; | 1204 | struct realtek_pci_sdmmc *host; |
| 1466 | struct rtsx_pcr *pcr; | 1205 | struct rtsx_pcr *pcr; |
| 1467 | struct pcr_handle *handle = pdev->dev.platform_data; | 1206 | struct pcr_handle *handle = pdev->dev.platform_data; |
| 1468 | unsigned long host_addr; | ||
| 1469 | 1207 | ||
| 1470 | if (!handle) | 1208 | if (!handle) |
| 1471 | return -ENXIO; | 1209 | return -ENXIO; |
| @@ -1489,15 +1227,8 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
| 1489 | pcr->slots[RTSX_SD_CARD].p_dev = pdev; | 1227 | pcr->slots[RTSX_SD_CARD].p_dev = pdev; |
| 1490 | pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event; | 1228 | pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event; |
| 1491 | 1229 | ||
| 1492 | host_addr = (unsigned long)host; | 1230 | mutex_init(&host->host_mutex); |
| 1493 | host->next_data.cookie = 1; | ||
| 1494 | setup_timer(&host->timer, sd_request_timeout, host_addr); | ||
| 1495 | tasklet_init(&host->cmd_tasklet, sd_get_rsp, host_addr); | ||
| 1496 | tasklet_init(&host->data_tasklet, sd_finish_multi_rw, host_addr); | ||
| 1497 | tasklet_init(&host->finish_tasklet, sd_finish_request, host_addr); | ||
| 1498 | spin_lock_init(&host->lock); | ||
| 1499 | 1231 | ||
| 1500 | pcr->slots[RTSX_SD_CARD].done_transfer = sd_isr_done_transfer; | ||
| 1501 | realtek_init_host(host); | 1232 | realtek_init_host(host); |
| 1502 | 1233 | ||
| 1503 | mmc_add_host(mmc); | 1234 | mmc_add_host(mmc); |
| @@ -1510,8 +1241,6 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev) | |||
| 1510 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); | 1241 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); |
| 1511 | struct rtsx_pcr *pcr; | 1242 | struct rtsx_pcr *pcr; |
| 1512 | struct mmc_host *mmc; | 1243 | struct mmc_host *mmc; |
| 1513 | struct mmc_request *mrq; | ||
| 1514 | unsigned long flags; | ||
| 1515 | 1244 | ||
| 1516 | if (!host) | 1245 | if (!host) |
| 1517 | return 0; | 1246 | return 0; |
| @@ -1519,33 +1248,22 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev) | |||
| 1519 | pcr = host->pcr; | 1248 | pcr = host->pcr; |
| 1520 | pcr->slots[RTSX_SD_CARD].p_dev = NULL; | 1249 | pcr->slots[RTSX_SD_CARD].p_dev = NULL; |
| 1521 | pcr->slots[RTSX_SD_CARD].card_event = NULL; | 1250 | pcr->slots[RTSX_SD_CARD].card_event = NULL; |
| 1522 | pcr->slots[RTSX_SD_CARD].done_transfer = NULL; | ||
| 1523 | mmc = host->mmc; | 1251 | mmc = host->mmc; |
| 1524 | mrq = host->mrq; | ||
| 1525 | 1252 | ||
| 1526 | spin_lock_irqsave(&host->lock, flags); | 1253 | mutex_lock(&host->host_mutex); |
| 1527 | if (host->mrq) { | 1254 | if (host->mrq) { |
| 1528 | dev_dbg(&(pdev->dev), | 1255 | dev_dbg(&(pdev->dev), |
| 1529 | "%s: Controller removed during transfer\n", | 1256 | "%s: Controller removed during transfer\n", |
| 1530 | mmc_hostname(mmc)); | 1257 | mmc_hostname(mmc)); |
| 1531 | 1258 | ||
| 1532 | if (mrq->sbc) | 1259 | rtsx_pci_complete_unfinished_transfer(pcr); |
| 1533 | mrq->sbc->error = -ENOMEDIUM; | ||
| 1534 | if (mrq->cmd) | ||
| 1535 | mrq->cmd->error = -ENOMEDIUM; | ||
| 1536 | if (mrq->stop) | ||
| 1537 | mrq->stop->error = -ENOMEDIUM; | ||
| 1538 | if (mrq->data) | ||
| 1539 | mrq->data->error = -ENOMEDIUM; | ||
| 1540 | 1260 | ||
| 1541 | tasklet_schedule(&host->finish_tasklet); | 1261 | host->mrq->cmd->error = -ENOMEDIUM; |
| 1262 | if (host->mrq->stop) | ||
| 1263 | host->mrq->stop->error = -ENOMEDIUM; | ||
| 1264 | mmc_request_done(mmc, host->mrq); | ||
| 1542 | } | 1265 | } |
| 1543 | spin_unlock_irqrestore(&host->lock, flags); | 1266 | mutex_unlock(&host->host_mutex); |
| 1544 | |||
| 1545 | del_timer_sync(&host->timer); | ||
| 1546 | tasklet_kill(&host->cmd_tasklet); | ||
| 1547 | tasklet_kill(&host->data_tasklet); | ||
| 1548 | tasklet_kill(&host->finish_tasklet); | ||
| 1549 | 1267 | ||
| 1550 | mmc_remove_host(mmc); | 1268 | mmc_remove_host(mmc); |
| 1551 | host->eject = true; | 1269 | host->eject = true; |
diff --git a/include/linux/mfd/rtsx_common.h b/include/linux/mfd/rtsx_common.h index 7c36cc55d2c7..443176ee1ab0 100644 --- a/include/linux/mfd/rtsx_common.h +++ b/include/linux/mfd/rtsx_common.h | |||
| @@ -45,7 +45,6 @@ struct platform_device; | |||
| 45 | struct rtsx_slot { | 45 | struct rtsx_slot { |
| 46 | struct platform_device *p_dev; | 46 | struct platform_device *p_dev; |
| 47 | void (*card_event)(struct platform_device *p_dev); | 47 | void (*card_event)(struct platform_device *p_dev); |
| 48 | void (*done_transfer)(struct platform_device *p_dev); | ||
| 49 | }; | 48 | }; |
| 50 | 49 | ||
| 51 | #endif | 50 | #endif |
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index 8d6bbd609ad9..a3835976f7c6 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h | |||
| @@ -943,12 +943,6 @@ void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr); | |||
| 943 | int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout); | 943 | int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout); |
| 944 | int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, | 944 | int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, |
| 945 | int num_sg, bool read, int timeout); | 945 | int num_sg, bool read, int timeout); |
| 946 | int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
| 947 | int num_sg, bool read); | ||
| 948 | int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
| 949 | int num_sg, bool read); | ||
| 950 | int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
| 951 | int sg_count, bool read); | ||
| 952 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); | 946 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); |
| 953 | int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); | 947 | int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); |
| 954 | int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card); | 948 | int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card); |
