diff options
author | Arnd Bergmann <arnd@arndb.de> | 2015-02-03 10:55:54 -0500 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2015-02-04 03:42:29 -0500 |
commit | 3981c516664d81a3e83c1923fa1ab3988c529402 (patch) | |
tree | c7c43a53c07d85fe91eabe9dc508b191e256df8b | |
parent | 4febb7e20aa619e2b2845519dad247e4038dc383 (diff) |
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>
-rw-r--r-- | drivers/mmc/host/moxart-mmc.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c index d2a1ef61ec97..006f1862444b 100644 --- a/drivers/mmc/host/moxart-mmc.c +++ b/drivers/mmc/host/moxart-mmc.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/errno.h> | ||
20 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
21 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
22 | #include <linux/dma-mapping.h> | 23 | #include <linux/dma-mapping.h> |
@@ -562,7 +563,6 @@ static int moxart_probe(struct platform_device *pdev) | |||
562 | struct dma_slave_config cfg; | 563 | struct dma_slave_config cfg; |
563 | struct clk *clk; | 564 | struct clk *clk; |
564 | void __iomem *reg_mmc; | 565 | void __iomem *reg_mmc; |
565 | dma_cap_mask_t mask; | ||
566 | int irq, ret; | 566 | int irq, ret; |
567 | u32 i; | 567 | u32 i; |
568 | 568 | ||
@@ -586,9 +586,8 @@ static int moxart_probe(struct platform_device *pdev) | |||
586 | goto out; | 586 | goto out; |
587 | } | 587 | } |
588 | 588 | ||
589 | clk = of_clk_get(node, 0); | 589 | clk = devm_clk_get(dev, NULL); |
590 | if (IS_ERR(clk)) { | 590 | if (IS_ERR(clk)) { |
591 | dev_err(dev, "of_clk_get failed\n"); | ||
592 | ret = PTR_ERR(clk); | 591 | ret = PTR_ERR(clk); |
593 | goto out; | 592 | goto out; |
594 | } | 593 | } |
@@ -603,9 +602,6 @@ static int moxart_probe(struct platform_device *pdev) | |||
603 | if (ret) | 602 | if (ret) |
604 | goto out; | 603 | goto out; |
605 | 604 | ||
606 | dma_cap_zero(mask); | ||
607 | dma_cap_set(DMA_SLAVE, mask); | ||
608 | |||
609 | host = mmc_priv(mmc); | 605 | host = mmc_priv(mmc); |
610 | host->mmc = mmc; | 606 | host->mmc = mmc; |
611 | host->base = reg_mmc; | 607 | host->base = reg_mmc; |
@@ -613,8 +609,8 @@ static int moxart_probe(struct platform_device *pdev) | |||
613 | host->timeout = msecs_to_jiffies(1000); | 609 | host->timeout = msecs_to_jiffies(1000); |
614 | host->sysclk = clk_get_rate(clk); | 610 | host->sysclk = clk_get_rate(clk); |
615 | host->fifo_width = readl(host->base + REG_FEATURE) << 2; | 611 | host->fifo_width = readl(host->base + REG_FEATURE) << 2; |
616 | host->dma_chan_tx = of_dma_request_slave_channel(node, "tx"); | 612 | host->dma_chan_tx = dma_request_slave_channel_reason(dev, "tx"); |
617 | host->dma_chan_rx = of_dma_request_slave_channel(node, "rx"); | 613 | host->dma_chan_rx = dma_request_slave_channel_reason(dev, "rx"); |
618 | 614 | ||
619 | spin_lock_init(&host->lock); | 615 | spin_lock_init(&host->lock); |
620 | 616 | ||
@@ -624,6 +620,11 @@ static int moxart_probe(struct platform_device *pdev) | |||
624 | mmc->ocr_avail = 0xffff00; /* Support 2.0v - 3.6v power. */ | 620 | mmc->ocr_avail = 0xffff00; /* Support 2.0v - 3.6v power. */ |
625 | 621 | ||
626 | if (IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { | 622 | if (IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { |
623 | if (PTR_ERR(host->dma_chan_tx) == -EPROBE_DEFER || | ||
624 | PTR_ERR(host->dma_chan_rx) == -EPROBE_DEFER) { | ||
625 | ret = -EPROBE_DEFER; | ||
626 | goto out; | ||
627 | } | ||
627 | dev_dbg(dev, "PIO mode transfer enabled\n"); | 628 | dev_dbg(dev, "PIO mode transfer enabled\n"); |
628 | host->have_dma = false; | 629 | host->have_dma = false; |
629 | } else { | 630 | } else { |
@@ -702,9 +703,6 @@ static int moxart_remove(struct platform_device *pdev) | |||
702 | writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF, | 703 | writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF, |
703 | host->base + REG_CLOCK_CONTROL); | 704 | host->base + REG_CLOCK_CONTROL); |
704 | } | 705 | } |
705 | |||
706 | kfree(host); | ||
707 | |||
708 | return 0; | 706 | return 0; |
709 | } | 707 | } |
710 | 708 | ||