Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: moxart: fix probe logic

Jonas Jensen wanted to submit a patch for these, but apparently
forgot about it. I stumbled over this symptom first:

drivers/built-in.o: In function `moxart_probe':
:(.text+0x2af128): undefined reference to `of_dma_request_slave_channel'

This is because of_dma_request_slave_channel is an internal helper
and not exported to loadable module. I'm changing the driver to
use dma_request_slave_channel_reason() instead.

Further problems from inspection:

* The remove function must not call kfree on the host pointer,
because it is allocated together with the mmc_host.

* The clock is never released

* The dma_cap_mask_t is completely unused and can be removed

* deferred probing does not work if the dma driver is loaded
after the mmc driver.

This patch should fix all of the above.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Arnd Bergmann and committed by
Ulf Hansson
3981c516 4febb7e2

+9 -11
+9 -11
drivers/mmc/host/moxart-mmc.c
··· 17 17 #include <linux/init.h> 18 18 #include <linux/platform_device.h> 19 19 #include <linux/delay.h> 20 + #include <linux/errno.h> 20 21 #include <linux/interrupt.h> 21 22 #include <linux/blkdev.h> 22 23 #include <linux/dma-mapping.h> ··· 563 562 struct dma_slave_config cfg; 564 563 struct clk *clk; 565 564 void __iomem *reg_mmc; 566 - dma_cap_mask_t mask; 567 565 int irq, ret; 568 566 u32 i; 569 567 ··· 586 586 goto out; 587 587 } 588 588 589 - clk = of_clk_get(node, 0); 589 + clk = devm_clk_get(dev, NULL); 590 590 if (IS_ERR(clk)) { 591 - dev_err(dev, "of_clk_get failed\n"); 592 591 ret = PTR_ERR(clk); 593 592 goto out; 594 593 } ··· 602 603 if (ret) 603 604 goto out; 604 605 605 - dma_cap_zero(mask); 606 - dma_cap_set(DMA_SLAVE, mask); 607 - 608 606 host = mmc_priv(mmc); 609 607 host->mmc = mmc; 610 608 host->base = reg_mmc; ··· 609 613 host->timeout = msecs_to_jiffies(1000); 610 614 host->sysclk = clk_get_rate(clk); 611 615 host->fifo_width = readl(host->base + REG_FEATURE) << 2; 612 - host->dma_chan_tx = of_dma_request_slave_channel(node, "tx"); 613 - host->dma_chan_rx = of_dma_request_slave_channel(node, "rx"); 616 + host->dma_chan_tx = dma_request_slave_channel_reason(dev, "tx"); 617 + host->dma_chan_rx = dma_request_slave_channel_reason(dev, "rx"); 614 618 615 619 spin_lock_init(&host->lock); 616 620 ··· 620 624 mmc->ocr_avail = 0xffff00; /* Support 2.0v - 3.6v power. */ 621 625 622 626 if (IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { 627 + if (PTR_ERR(host->dma_chan_tx) == -EPROBE_DEFER || 628 + PTR_ERR(host->dma_chan_rx) == -EPROBE_DEFER) { 629 + ret = -EPROBE_DEFER; 630 + goto out; 631 + } 623 632 dev_dbg(dev, "PIO mode transfer enabled\n"); 624 633 host->have_dma = false; 625 634 } else { ··· 703 702 writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF, 704 703 host->base + REG_CLOCK_CONTROL); 705 704 } 706 - 707 - kfree(host); 708 - 709 705 return 0; 710 706 } 711 707