aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2007-04-12 02:59:24 -0400
committerPierre Ossman <drzeus@drzeus.cx>2007-05-01 07:04:14 -0400
commitdfef26d9aad4f983da232b259ee7f7faec479b2d (patch)
treea53b763a604766a593a3b9eb5e95605b4bcdbbde /drivers/mmc
parent0007d4837ac94d672f313cfc462f879b5d06f221 (diff)
tifm_sd: merge dma and pio request processing paths
To allow for switching of trasfer mode (dma/pio) on a per-request basis, pio and dma request issue and completion function are now merged. Signed-off-by: Alex Dubov <oakad@yahoo.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/tifm_sd.c198
1 files changed, 68 insertions, 130 deletions
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index fe8cb1aa681f..52499548abe8 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -484,19 +484,40 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
484 if (r_data) { 484 if (r_data) {
485 tifm_sd_set_data_timeout(host, r_data); 485 tifm_sd_set_data_timeout(host, r_data);
486 486
487 sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len, 487 if (host->no_dma) {
488 mrq->cmd->flags & MMC_DATA_WRITE 488 host->buffer_size = mrq->cmd->data->blocks
489 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); 489 * mrq->cmd->data->blksz;
490 if (sg_count != 1) { 490
491 printk(KERN_ERR DRIVER_NAME 491 writel(TIFM_MMCSD_BUFINT
492 ": scatterlist map failed\n"); 492 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
493 spin_unlock_irqrestore(&sock->lock, flags); 493 sock->addr + SOCK_MMCSD_INT_ENABLE);
494 goto err_out; 494 writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8)
495 } 495 | (TIFM_MMCSD_FIFO_SIZE - 1),
496 sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
497
498 host->written_blocks = 0;
499 host->cmd_flags &= ~CARD_BUSY;
500 host->buffer_pos = 0;
501 writel(r_data->blocks - 1,
502 sock->addr + SOCK_MMCSD_NUM_BLOCKS);
503 writel(r_data->blksz - 1,
504 sock->addr + SOCK_MMCSD_BLOCK_LEN);
505 } else {
506 sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len,
507 mrq->cmd->flags & MMC_DATA_WRITE
508 ? PCI_DMA_TODEVICE
509 : PCI_DMA_FROMDEVICE);
510 if (sg_count != 1) {
511 printk(KERN_ERR DRIVER_NAME
512 ": scatterlist map failed\n");
513 spin_unlock_irqrestore(&sock->lock, flags);
514 goto err_out;
515 }
496 516
497 host->written_blocks = 0; 517 host->written_blocks = 0;
498 host->cmd_flags &= ~CARD_BUSY; 518 host->cmd_flags &= ~CARD_BUSY;
499 tifm_sd_prepare_data(host, mrq->cmd); 519 tifm_sd_prepare_data(host, mrq->cmd);
520 }
500 } 521 }
501 522
502 host->req = mrq; 523 host->req = mrq;
@@ -542,128 +563,47 @@ static void tifm_sd_end_cmd(unsigned long data)
542 563
543 r_data = mrq->cmd->data; 564 r_data = mrq->cmd->data;
544 if (r_data) { 565 if (r_data) {
545 if (r_data->flags & MMC_DATA_WRITE) { 566 if (host->no_dma) {
546 r_data->bytes_xfered = host->written_blocks 567 writel((~TIFM_MMCSD_BUFINT) &
547 * r_data->blksz; 568 readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
548 } else { 569 sock->addr + SOCK_MMCSD_INT_ENABLE);
549 r_data->bytes_xfered = r_data->blocks - 570
550 readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; 571 if (r_data->flags & MMC_DATA_WRITE) {
551 r_data->bytes_xfered *= r_data->blksz; 572 r_data->bytes_xfered = host->written_blocks
552 r_data->bytes_xfered += r_data->blksz - 573 * r_data->blksz;
553 readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; 574 } else {
554 } 575 r_data->bytes_xfered = r_data->blocks -
555 tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, 576 readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS)
556 (r_data->flags & MMC_DATA_WRITE) 577 - 1;
557 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); 578 r_data->bytes_xfered *= r_data->blksz;
558 } 579 r_data->bytes_xfered += r_data->blksz
559 580 - readl(sock->addr + SOCK_MMCSD_BLOCK_LEN)
560 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), 581 + 1;
561 sock->addr + SOCK_CONTROL); 582 }
562 583 host->buffer_pos = 0;
563 spin_unlock_irqrestore(&sock->lock, flags); 584 host->buffer_size = 0;
564 mmc_request_done(mmc, mrq);
565}
566
567static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
568{
569 struct tifm_sd *host = mmc_priv(mmc);
570 struct tifm_dev *sock = host->dev;
571 unsigned long flags;
572 struct mmc_data *r_data = mrq->cmd->data;
573
574 spin_lock_irqsave(&sock->lock, flags);
575 if (host->eject) {
576 spin_unlock_irqrestore(&sock->lock, flags);
577 goto err_out;
578 }
579
580 if (host->req) {
581 printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n");
582 spin_unlock_irqrestore(&sock->lock, flags);
583 goto err_out;
584 }
585
586 if (r_data) {
587 tifm_sd_set_data_timeout(host, r_data);
588
589 host->buffer_size = mrq->cmd->data->blocks
590 * mrq->cmd->data->blksz;
591
592 writel(TIFM_MMCSD_BUFINT
593 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
594 sock->addr + SOCK_MMCSD_INT_ENABLE);
595 writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8)
596 | (TIFM_MMCSD_FIFO_SIZE - 1),
597 sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
598
599 host->written_blocks = 0;
600 host->cmd_flags &= ~CARD_BUSY;
601 host->buffer_pos = 0;
602 writel(r_data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
603 writel(r_data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN);
604 }
605
606 host->req = mrq;
607 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
608 host->state = CMD;
609 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
610 sock->addr + SOCK_CONTROL);
611 tifm_sd_exec(host, mrq->cmd);
612 spin_unlock_irqrestore(&sock->lock, flags);
613 return;
614
615err_out:
616 mrq->cmd->error = MMC_ERR_TIMEOUT;
617 mmc_request_done(mmc, mrq);
618}
619
620static void tifm_sd_end_cmd_nodma(unsigned long data)
621{
622 struct tifm_sd *host = (struct tifm_sd*)data;
623 struct tifm_dev *sock = host->dev;
624 struct mmc_host *mmc = tifm_get_drvdata(sock);
625 struct mmc_request *mrq;
626 struct mmc_data *r_data = NULL;
627 unsigned long flags;
628
629 spin_lock_irqsave(&sock->lock, flags);
630
631 del_timer(&host->timer);
632 mrq = host->req;
633 host->req = NULL;
634 host->state = IDLE;
635
636 if (!mrq) {
637 printk(KERN_ERR DRIVER_NAME ": no request to complete?\n");
638 spin_unlock_irqrestore(&sock->lock, flags);
639 return;
640 }
641
642 r_data = mrq->cmd->data;
643 if (r_data) {
644 writel((~TIFM_MMCSD_BUFINT) &
645 readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
646 sock->addr + SOCK_MMCSD_INT_ENABLE);
647
648 if (r_data->flags & MMC_DATA_WRITE) {
649 r_data->bytes_xfered = host->written_blocks
650 * r_data->blksz;
651 } else { 585 } else {
652 r_data->bytes_xfered = r_data->blocks - 586 if (r_data->flags & MMC_DATA_WRITE) {
653 readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; 587 r_data->bytes_xfered = host->written_blocks
654 r_data->bytes_xfered *= r_data->blksz; 588 * r_data->blksz;
655 r_data->bytes_xfered += r_data->blksz - 589 } else {
656 readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; 590 r_data->bytes_xfered = r_data->blocks -
591 readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
592 r_data->bytes_xfered *= r_data->blksz;
593 r_data->bytes_xfered += r_data->blksz -
594 readl(sock->addr + SOCK_MMCSD_BLOCK_LEN)
595 + 1;
596 }
597 tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
598 (r_data->flags & MMC_DATA_WRITE)
599 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
657 } 600 }
658 host->buffer_pos = 0;
659 host->buffer_size = 0;
660 } 601 }
661 602
662 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), 603 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
663 sock->addr + SOCK_CONTROL); 604 sock->addr + SOCK_CONTROL);
664 605
665 spin_unlock_irqrestore(&sock->lock, flags); 606 spin_unlock_irqrestore(&sock->lock, flags);
666
667 mmc_request_done(mmc, mrq); 607 mmc_request_done(mmc, mrq);
668} 608}
669 609
@@ -755,7 +695,7 @@ static int tifm_sd_ro(struct mmc_host *mmc)
755 return rc; 695 return rc;
756} 696}
757 697
758static struct mmc_host_ops tifm_sd_ops = { 698static const struct mmc_host_ops tifm_sd_ops = {
759 .request = tifm_sd_request, 699 .request = tifm_sd_request,
760 .set_ios = tifm_sd_ios, 700 .set_ios = tifm_sd_ios,
761 .get_ro = tifm_sd_ro 701 .get_ro = tifm_sd_ro
@@ -846,12 +786,10 @@ static int tifm_sd_probe(struct tifm_dev *sock)
846 host->dev = sock; 786 host->dev = sock;
847 host->timeout_jiffies = msecs_to_jiffies(1000); 787 host->timeout_jiffies = msecs_to_jiffies(1000);
848 788
849 tasklet_init(&host->finish_tasklet, 789 tasklet_init(&host->finish_tasklet, tifm_sd_end_cmd,
850 host->no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd,
851 (unsigned long)host); 790 (unsigned long)host);
852 setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host); 791 setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host);
853 792
854 tifm_sd_ops.request = host->no_dma ? tifm_sd_request_nodma : tifm_sd_request;
855 mmc->ops = &tifm_sd_ops; 793 mmc->ops = &tifm_sd_ops;
856 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 794 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
857 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; 795 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;