| .. | .. |
|---|
| 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 |
|---|
| .. | .. |
|---|
| 527 | 527 | case MMC_BUS_WIDTH_4: |
|---|
| 528 | 528 | writel(BUS_WIDTH_4, host->base + REG_BUS_WIDTH); |
|---|
| 529 | 529 | break; |
|---|
| 530 | | - case MMC_BUS_WIDTH_8: |
|---|
| 531 | | - writel(BUS_WIDTH_8, host->base + REG_BUS_WIDTH); |
|---|
| 532 | | - break; |
|---|
| 533 | 530 | default: |
|---|
| 534 | 531 | writel(BUS_WIDTH_1, host->base + REG_BUS_WIDTH); |
|---|
| 535 | 532 | break; |
|---|
| .. | .. |
|---|
| 569 | 566 | if (!mmc) { |
|---|
| 570 | 567 | dev_err(dev, "mmc_alloc_host failed\n"); |
|---|
| 571 | 568 | ret = -ENOMEM; |
|---|
| 572 | | - goto out; |
|---|
| 569 | + goto out_mmc; |
|---|
| 573 | 570 | } |
|---|
| 574 | 571 | |
|---|
| 575 | 572 | ret = of_address_to_resource(node, 0, &res_mmc); |
|---|
| 576 | 573 | if (ret) { |
|---|
| 577 | 574 | dev_err(dev, "of_address_to_resource failed\n"); |
|---|
| 578 | | - goto out; |
|---|
| 575 | + goto out_mmc; |
|---|
| 579 | 576 | } |
|---|
| 580 | 577 | |
|---|
| 581 | 578 | irq = irq_of_parse_and_map(node, 0); |
|---|
| 582 | 579 | if (irq <= 0) { |
|---|
| 583 | 580 | dev_err(dev, "irq_of_parse_and_map failed\n"); |
|---|
| 584 | 581 | ret = -EINVAL; |
|---|
| 585 | | - goto out; |
|---|
| 582 | + goto out_mmc; |
|---|
| 586 | 583 | } |
|---|
| 587 | 584 | |
|---|
| 588 | 585 | clk = devm_clk_get(dev, NULL); |
|---|
| 589 | 586 | if (IS_ERR(clk)) { |
|---|
| 590 | 587 | ret = PTR_ERR(clk); |
|---|
| 591 | | - goto out; |
|---|
| 588 | + goto out_mmc; |
|---|
| 592 | 589 | } |
|---|
| 593 | 590 | |
|---|
| 594 | 591 | reg_mmc = devm_ioremap_resource(dev, &res_mmc); |
|---|
| 595 | 592 | if (IS_ERR(reg_mmc)) { |
|---|
| 596 | 593 | ret = PTR_ERR(reg_mmc); |
|---|
| 597 | | - goto out; |
|---|
| 594 | + goto out_mmc; |
|---|
| 598 | 595 | } |
|---|
| 599 | 596 | |
|---|
| 600 | 597 | ret = mmc_of_parse(mmc); |
|---|
| 601 | 598 | if (ret) |
|---|
| 602 | | - goto out; |
|---|
| 599 | + goto out_mmc; |
|---|
| 603 | 600 | |
|---|
| 604 | 601 | host = mmc_priv(mmc); |
|---|
| 605 | 602 | host->mmc = mmc; |
|---|
| .. | .. |
|---|
| 608 | 605 | host->timeout = msecs_to_jiffies(1000); |
|---|
| 609 | 606 | host->sysclk = clk_get_rate(clk); |
|---|
| 610 | 607 | 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"); |
|---|
| 608 | + host->dma_chan_tx = dma_request_chan(dev, "tx"); |
|---|
| 609 | + host->dma_chan_rx = dma_request_chan(dev, "rx"); |
|---|
| 613 | 610 | |
|---|
| 614 | 611 | spin_lock_init(&host->lock); |
|---|
| 615 | 612 | |
|---|
| .. | .. |
|---|
| 623 | 620 | PTR_ERR(host->dma_chan_rx) == -EPROBE_DEFER) { |
|---|
| 624 | 621 | ret = -EPROBE_DEFER; |
|---|
| 625 | 622 | goto out; |
|---|
| 623 | + } |
|---|
| 624 | + if (!IS_ERR(host->dma_chan_tx)) { |
|---|
| 625 | + dma_release_channel(host->dma_chan_tx); |
|---|
| 626 | + host->dma_chan_tx = NULL; |
|---|
| 627 | + } |
|---|
| 628 | + if (!IS_ERR(host->dma_chan_rx)) { |
|---|
| 629 | + dma_release_channel(host->dma_chan_rx); |
|---|
| 630 | + host->dma_chan_rx = NULL; |
|---|
| 626 | 631 | } |
|---|
| 627 | 632 | dev_dbg(dev, "PIO mode transfer enabled\n"); |
|---|
| 628 | 633 | host->have_dma = false; |
|---|
| .. | .. |
|---|
| 646 | 651 | dmaengine_slave_config(host->dma_chan_rx, &cfg); |
|---|
| 647 | 652 | } |
|---|
| 648 | 653 | |
|---|
| 649 | | - switch ((readl(host->base + REG_BUS_WIDTH) >> 3) & 3) { |
|---|
| 650 | | - case 1: |
|---|
| 654 | + if (readl(host->base + REG_BUS_WIDTH) & BUS_WIDTH_4_SUPPORT) |
|---|
| 651 | 655 | 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 | 656 | |
|---|
| 660 | 657 | writel(0, host->base + REG_INTERRUPT_MASK); |
|---|
| 661 | 658 | |
|---|
| .. | .. |
|---|
| 678 | 675 | return 0; |
|---|
| 679 | 676 | |
|---|
| 680 | 677 | out: |
|---|
| 678 | + if (!IS_ERR_OR_NULL(host->dma_chan_tx)) |
|---|
| 679 | + dma_release_channel(host->dma_chan_tx); |
|---|
| 680 | + if (!IS_ERR_OR_NULL(host->dma_chan_rx)) |
|---|
| 681 | + dma_release_channel(host->dma_chan_rx); |
|---|
| 682 | +out_mmc: |
|---|
| 681 | 683 | if (mmc) |
|---|
| 682 | 684 | mmc_free_host(mmc); |
|---|
| 683 | 685 | return ret; |
|---|
| .. | .. |
|---|
| 690 | 692 | |
|---|
| 691 | 693 | dev_set_drvdata(&pdev->dev, NULL); |
|---|
| 692 | 694 | |
|---|
| 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); |
|---|
| 695 | + if (!IS_ERR_OR_NULL(host->dma_chan_tx)) |
|---|
| 696 | + dma_release_channel(host->dma_chan_tx); |
|---|
| 697 | + if (!IS_ERR_OR_NULL(host->dma_chan_rx)) |
|---|
| 698 | + dma_release_channel(host->dma_chan_rx); |
|---|
| 699 | + mmc_remove_host(mmc); |
|---|
| 699 | 700 | |
|---|
| 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 | | - } |
|---|
| 701 | + writel(0, host->base + REG_INTERRUPT_MASK); |
|---|
| 702 | + writel(0, host->base + REG_POWER_CONTROL); |
|---|
| 703 | + writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF, |
|---|
| 704 | + host->base + REG_CLOCK_CONTROL); |
|---|
| 705 | + mmc_free_host(mmc); |
|---|
| 706 | + |
|---|
| 706 | 707 | return 0; |
|---|
| 707 | 708 | } |
|---|
| 708 | 709 | |
|---|
| .. | .. |
|---|
| 718 | 719 | .remove = moxart_remove, |
|---|
| 719 | 720 | .driver = { |
|---|
| 720 | 721 | .name = "mmc-moxart", |
|---|
| 722 | + .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
|---|
| 721 | 723 | .of_match_table = moxart_mmc_match, |
|---|
| 722 | 724 | }, |
|---|
| 723 | 725 | }; |
|---|