.. | .. |
---|
111 | 111 | #define CLK_DIV_MASK 0x7f |
---|
112 | 112 | |
---|
113 | 113 | /* REG_BUS_WIDTH */ |
---|
114 | | -#define BUS_WIDTH_8 BIT(2) |
---|
115 | | -#define BUS_WIDTH_4 BIT(1) |
---|
| 114 | +#define BUS_WIDTH_4_SUPPORT BIT(3) |
---|
| 115 | +#define BUS_WIDTH_4 BIT(2) |
---|
116 | 116 | #define BUS_WIDTH_1 BIT(0) |
---|
117 | 117 | |
---|
118 | 118 | #define MMC_VDD_360 23 |
---|
.. | .. |
---|
339 | 339 | return; |
---|
340 | 340 | } |
---|
341 | 341 | for (len = 0; len < remain && len < host->fifo_width;) { |
---|
342 | | - /* SCR data must be read in big endian. */ |
---|
343 | | - if (data->mrq->cmd->opcode == SD_APP_SEND_SCR) |
---|
344 | | - *sgp = ioread32be(host->base + |
---|
345 | | - REG_DATA_WINDOW); |
---|
346 | | - else |
---|
347 | | - *sgp = ioread32(host->base + |
---|
348 | | - REG_DATA_WINDOW); |
---|
| 342 | + *sgp = ioread32(host->base + REG_DATA_WINDOW); |
---|
349 | 343 | sgp++; |
---|
350 | 344 | len += 4; |
---|
351 | 345 | } |
---|
.. | .. |
---|
527 | 521 | case MMC_BUS_WIDTH_4: |
---|
528 | 522 | writel(BUS_WIDTH_4, host->base + REG_BUS_WIDTH); |
---|
529 | 523 | break; |
---|
530 | | - case MMC_BUS_WIDTH_8: |
---|
531 | | - writel(BUS_WIDTH_8, host->base + REG_BUS_WIDTH); |
---|
532 | | - break; |
---|
533 | 524 | default: |
---|
534 | 525 | writel(BUS_WIDTH_1, host->base + REG_BUS_WIDTH); |
---|
535 | 526 | break; |
---|
.. | .. |
---|
569 | 560 | if (!mmc) { |
---|
570 | 561 | dev_err(dev, "mmc_alloc_host failed\n"); |
---|
571 | 562 | ret = -ENOMEM; |
---|
572 | | - goto out; |
---|
| 563 | + goto out_mmc; |
---|
573 | 564 | } |
---|
574 | 565 | |
---|
575 | 566 | ret = of_address_to_resource(node, 0, &res_mmc); |
---|
576 | 567 | if (ret) { |
---|
577 | 568 | dev_err(dev, "of_address_to_resource failed\n"); |
---|
578 | | - goto out; |
---|
| 569 | + goto out_mmc; |
---|
579 | 570 | } |
---|
580 | 571 | |
---|
581 | 572 | irq = irq_of_parse_and_map(node, 0); |
---|
582 | 573 | if (irq <= 0) { |
---|
583 | 574 | dev_err(dev, "irq_of_parse_and_map failed\n"); |
---|
584 | 575 | ret = -EINVAL; |
---|
585 | | - goto out; |
---|
| 576 | + goto out_mmc; |
---|
586 | 577 | } |
---|
587 | 578 | |
---|
588 | 579 | clk = devm_clk_get(dev, NULL); |
---|
589 | 580 | if (IS_ERR(clk)) { |
---|
590 | 581 | ret = PTR_ERR(clk); |
---|
591 | | - goto out; |
---|
| 582 | + goto out_mmc; |
---|
592 | 583 | } |
---|
593 | 584 | |
---|
594 | 585 | reg_mmc = devm_ioremap_resource(dev, &res_mmc); |
---|
595 | 586 | if (IS_ERR(reg_mmc)) { |
---|
596 | 587 | ret = PTR_ERR(reg_mmc); |
---|
597 | | - goto out; |
---|
| 588 | + goto out_mmc; |
---|
598 | 589 | } |
---|
599 | 590 | |
---|
600 | 591 | ret = mmc_of_parse(mmc); |
---|
601 | 592 | if (ret) |
---|
602 | | - goto out; |
---|
| 593 | + goto out_mmc; |
---|
603 | 594 | |
---|
604 | 595 | host = mmc_priv(mmc); |
---|
605 | 596 | host->mmc = mmc; |
---|
.. | .. |
---|
608 | 599 | host->timeout = msecs_to_jiffies(1000); |
---|
609 | 600 | host->sysclk = clk_get_rate(clk); |
---|
610 | 601 | host->fifo_width = readl(host->base + REG_FEATURE) << 2; |
---|
611 | | - host->dma_chan_tx = dma_request_slave_channel_reason(dev, "tx"); |
---|
612 | | - host->dma_chan_rx = dma_request_slave_channel_reason(dev, "rx"); |
---|
| 602 | + host->dma_chan_tx = dma_request_chan(dev, "tx"); |
---|
| 603 | + host->dma_chan_rx = dma_request_chan(dev, "rx"); |
---|
613 | 604 | |
---|
614 | 605 | spin_lock_init(&host->lock); |
---|
615 | 606 | |
---|
.. | .. |
---|
623 | 614 | PTR_ERR(host->dma_chan_rx) == -EPROBE_DEFER) { |
---|
624 | 615 | ret = -EPROBE_DEFER; |
---|
625 | 616 | goto out; |
---|
| 617 | + } |
---|
| 618 | + if (!IS_ERR(host->dma_chan_tx)) { |
---|
| 619 | + dma_release_channel(host->dma_chan_tx); |
---|
| 620 | + host->dma_chan_tx = NULL; |
---|
| 621 | + } |
---|
| 622 | + if (!IS_ERR(host->dma_chan_rx)) { |
---|
| 623 | + dma_release_channel(host->dma_chan_rx); |
---|
| 624 | + host->dma_chan_rx = NULL; |
---|
626 | 625 | } |
---|
627 | 626 | dev_dbg(dev, "PIO mode transfer enabled\n"); |
---|
628 | 627 | host->have_dma = false; |
---|
.. | .. |
---|
646 | 645 | dmaengine_slave_config(host->dma_chan_rx, &cfg); |
---|
647 | 646 | } |
---|
648 | 647 | |
---|
649 | | - switch ((readl(host->base + REG_BUS_WIDTH) >> 3) & 3) { |
---|
650 | | - case 1: |
---|
| 648 | + if (readl(host->base + REG_BUS_WIDTH) & BUS_WIDTH_4_SUPPORT) |
---|
651 | 649 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
---|
652 | | - break; |
---|
653 | | - case 2: |
---|
654 | | - mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; |
---|
655 | | - break; |
---|
656 | | - default: |
---|
657 | | - break; |
---|
658 | | - } |
---|
659 | 650 | |
---|
660 | 651 | writel(0, host->base + REG_INTERRUPT_MASK); |
---|
661 | 652 | |
---|
.. | .. |
---|
671 | 662 | goto out; |
---|
672 | 663 | |
---|
673 | 664 | dev_set_drvdata(dev, mmc); |
---|
674 | | - mmc_add_host(mmc); |
---|
| 665 | + ret = mmc_add_host(mmc); |
---|
| 666 | + if (ret) |
---|
| 667 | + goto out; |
---|
675 | 668 | |
---|
676 | 669 | dev_dbg(dev, "IRQ=%d, FIFO is %d bytes\n", irq, host->fifo_width); |
---|
677 | 670 | |
---|
678 | 671 | return 0; |
---|
679 | 672 | |
---|
680 | 673 | out: |
---|
| 674 | + if (!IS_ERR_OR_NULL(host->dma_chan_tx)) |
---|
| 675 | + dma_release_channel(host->dma_chan_tx); |
---|
| 676 | + if (!IS_ERR_OR_NULL(host->dma_chan_rx)) |
---|
| 677 | + dma_release_channel(host->dma_chan_rx); |
---|
| 678 | +out_mmc: |
---|
681 | 679 | if (mmc) |
---|
682 | 680 | mmc_free_host(mmc); |
---|
683 | 681 | return ret; |
---|
.. | .. |
---|
690 | 688 | |
---|
691 | 689 | dev_set_drvdata(&pdev->dev, NULL); |
---|
692 | 690 | |
---|
693 | | - if (mmc) { |
---|
694 | | - if (!IS_ERR(host->dma_chan_tx)) |
---|
695 | | - dma_release_channel(host->dma_chan_tx); |
---|
696 | | - if (!IS_ERR(host->dma_chan_rx)) |
---|
697 | | - dma_release_channel(host->dma_chan_rx); |
---|
698 | | - mmc_remove_host(mmc); |
---|
| 691 | + if (!IS_ERR_OR_NULL(host->dma_chan_tx)) |
---|
| 692 | + dma_release_channel(host->dma_chan_tx); |
---|
| 693 | + if (!IS_ERR_OR_NULL(host->dma_chan_rx)) |
---|
| 694 | + dma_release_channel(host->dma_chan_rx); |
---|
| 695 | + mmc_remove_host(mmc); |
---|
699 | 696 | |
---|
700 | | - writel(0, host->base + REG_INTERRUPT_MASK); |
---|
701 | | - writel(0, host->base + REG_POWER_CONTROL); |
---|
702 | | - writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF, |
---|
703 | | - host->base + REG_CLOCK_CONTROL); |
---|
704 | | - mmc_free_host(mmc); |
---|
705 | | - } |
---|
| 697 | + writel(0, host->base + REG_INTERRUPT_MASK); |
---|
| 698 | + writel(0, host->base + REG_POWER_CONTROL); |
---|
| 699 | + writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF, |
---|
| 700 | + host->base + REG_CLOCK_CONTROL); |
---|
| 701 | + mmc_free_host(mmc); |
---|
| 702 | + |
---|
706 | 703 | return 0; |
---|
707 | 704 | } |
---|
708 | 705 | |
---|
.. | .. |
---|
718 | 715 | .remove = moxart_remove, |
---|
719 | 716 | .driver = { |
---|
720 | 717 | .name = "mmc-moxart", |
---|
| 718 | + .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
---|
721 | 719 | .of_match_table = moxart_mmc_match, |
---|
722 | 720 | }, |
---|
723 | 721 | }; |
---|