diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2014-08-19 13:29:17 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2014-09-11 02:18:13 -0400 |
commit | a15636e83eb0dedefcb1221be729023e4c281748 (patch) | |
tree | 71bbc5c36dbd708399de26de51338e4769a0dbc2 | |
parent | 4d130de20c3f39fc1a1aecd3969b50d49ff2e358 (diff) |
dmaengine: dw: move clock operations to platform.c
On BayTrail platform DMA is not functional in the PCI mode, whereby it always
failed and exit at the point when it tries to get a clock. It causes the PCI
mode probe to exit with the error message:
dw_dmac_pci: probe of 0000:00:1e.0 failed with error -2
This patch moves clock operations to where it belongs to. Thus, the clock is
provided only in ACPI / non-PCI cases.
Reported-by: Chew, Chiau Ee <chiau.ee.chew@intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r-- | drivers/dma/dw/core.c | 16 | ||||
-rw-r--r-- | drivers/dma/dw/internal.h | 2 | ||||
-rw-r--r-- | drivers/dma/dw/platform.c | 25 | ||||
-rw-r--r-- | drivers/dma/dw/regs.h | 1 |
4 files changed, 24 insertions, 20 deletions
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 10e43eae61a7..9546b1f599f0 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c | |||
@@ -11,7 +11,6 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/bitops.h> | 13 | #include <linux/bitops.h> |
14 | #include <linux/clk.h> | ||
15 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
16 | #include <linux/dmaengine.h> | 15 | #include <linux/dmaengine.h> |
17 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
@@ -1488,13 +1487,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) | |||
1488 | dw->regs = chip->regs; | 1487 | dw->regs = chip->regs; |
1489 | chip->dw = dw; | 1488 | chip->dw = dw; |
1490 | 1489 | ||
1491 | dw->clk = devm_clk_get(chip->dev, "hclk"); | ||
1492 | if (IS_ERR(dw->clk)) | ||
1493 | return PTR_ERR(dw->clk); | ||
1494 | err = clk_prepare_enable(dw->clk); | ||
1495 | if (err) | ||
1496 | return err; | ||
1497 | |||
1498 | dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); | 1490 | dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); |
1499 | autocfg = dw_params >> DW_PARAMS_EN & 0x1; | 1491 | autocfg = dw_params >> DW_PARAMS_EN & 0x1; |
1500 | 1492 | ||
@@ -1665,7 +1657,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) | |||
1665 | err_dma_register: | 1657 | err_dma_register: |
1666 | free_irq(chip->irq, dw); | 1658 | free_irq(chip->irq, dw); |
1667 | err_pdata: | 1659 | err_pdata: |
1668 | clk_disable_unprepare(dw->clk); | ||
1669 | return err; | 1660 | return err; |
1670 | } | 1661 | } |
1671 | EXPORT_SYMBOL_GPL(dw_dma_probe); | 1662 | EXPORT_SYMBOL_GPL(dw_dma_probe); |
@@ -1687,8 +1678,6 @@ int dw_dma_remove(struct dw_dma_chip *chip) | |||
1687 | channel_clear_bit(dw, CH_EN, dwc->mask); | 1678 | channel_clear_bit(dw, CH_EN, dwc->mask); |
1688 | } | 1679 | } |
1689 | 1680 | ||
1690 | clk_disable_unprepare(dw->clk); | ||
1691 | |||
1692 | return 0; | 1681 | return 0; |
1693 | } | 1682 | } |
1694 | EXPORT_SYMBOL_GPL(dw_dma_remove); | 1683 | EXPORT_SYMBOL_GPL(dw_dma_remove); |
@@ -1698,7 +1687,6 @@ void dw_dma_shutdown(struct dw_dma_chip *chip) | |||
1698 | struct dw_dma *dw = chip->dw; | 1687 | struct dw_dma *dw = chip->dw; |
1699 | 1688 | ||
1700 | dw_dma_off(dw); | 1689 | dw_dma_off(dw); |
1701 | clk_disable_unprepare(dw->clk); | ||
1702 | } | 1690 | } |
1703 | EXPORT_SYMBOL_GPL(dw_dma_shutdown); | 1691 | EXPORT_SYMBOL_GPL(dw_dma_shutdown); |
1704 | 1692 | ||
@@ -1709,8 +1697,6 @@ int dw_dma_suspend(struct dw_dma_chip *chip) | |||
1709 | struct dw_dma *dw = chip->dw; | 1697 | struct dw_dma *dw = chip->dw; |
1710 | 1698 | ||
1711 | dw_dma_off(dw); | 1699 | dw_dma_off(dw); |
1712 | clk_disable_unprepare(dw->clk); | ||
1713 | |||
1714 | return 0; | 1700 | return 0; |
1715 | } | 1701 | } |
1716 | EXPORT_SYMBOL_GPL(dw_dma_suspend); | 1702 | EXPORT_SYMBOL_GPL(dw_dma_suspend); |
@@ -1719,9 +1705,7 @@ int dw_dma_resume(struct dw_dma_chip *chip) | |||
1719 | { | 1705 | { |
1720 | struct dw_dma *dw = chip->dw; | 1706 | struct dw_dma *dw = chip->dw; |
1721 | 1707 | ||
1722 | clk_prepare_enable(dw->clk); | ||
1723 | dma_writel(dw, CFG, DW_CFG_DMA_EN); | 1708 | dma_writel(dw, CFG, DW_CFG_DMA_EN); |
1724 | |||
1725 | return 0; | 1709 | return 0; |
1726 | } | 1710 | } |
1727 | EXPORT_SYMBOL_GPL(dw_dma_resume); | 1711 | EXPORT_SYMBOL_GPL(dw_dma_resume); |
diff --git a/drivers/dma/dw/internal.h b/drivers/dma/dw/internal.h index 2c8d02f52737..82258a167a0e 100644 --- a/drivers/dma/dw/internal.h +++ b/drivers/dma/dw/internal.h | |||
@@ -21,12 +21,14 @@ | |||
21 | * @dev: struct device of the DMA controller | 21 | * @dev: struct device of the DMA controller |
22 | * @irq: irq line | 22 | * @irq: irq line |
23 | * @regs: memory mapped I/O space | 23 | * @regs: memory mapped I/O space |
24 | * @clk: hclk clock | ||
24 | * @dw: struct dw_dma that is filed by dw_dma_probe() | 25 | * @dw: struct dw_dma that is filed by dw_dma_probe() |
25 | */ | 26 | */ |
26 | struct dw_dma_chip { | 27 | struct dw_dma_chip { |
27 | struct device *dev; | 28 | struct device *dev; |
28 | int irq; | 29 | int irq; |
29 | void __iomem *regs; | 30 | void __iomem *regs; |
31 | struct clk *clk; | ||
30 | struct dw_dma *dw; | 32 | struct dw_dma *dw; |
31 | }; | 33 | }; |
32 | 34 | ||
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c index 860c9acf3fef..d50077e48187 100644 --- a/drivers/dma/dw/platform.c +++ b/drivers/dma/dw/platform.c | |||
@@ -178,10 +178,17 @@ static int dw_probe(struct platform_device *pdev) | |||
178 | 178 | ||
179 | chip->dev = dev; | 179 | chip->dev = dev; |
180 | 180 | ||
181 | err = dw_dma_probe(chip, pdata); | 181 | chip->clk = devm_clk_get(chip->dev, "hclk"); |
182 | if (IS_ERR(chip->clk)) | ||
183 | return PTR_ERR(chip->clk); | ||
184 | err = clk_prepare_enable(chip->clk); | ||
182 | if (err) | 185 | if (err) |
183 | return err; | 186 | return err; |
184 | 187 | ||
188 | err = dw_dma_probe(chip, pdata); | ||
189 | if (err) | ||
190 | goto err_dw_dma_probe; | ||
191 | |||
185 | platform_set_drvdata(pdev, chip); | 192 | platform_set_drvdata(pdev, chip); |
186 | 193 | ||
187 | if (pdev->dev.of_node) { | 194 | if (pdev->dev.of_node) { |
@@ -196,6 +203,10 @@ static int dw_probe(struct platform_device *pdev) | |||
196 | dw_dma_acpi_controller_register(chip->dw); | 203 | dw_dma_acpi_controller_register(chip->dw); |
197 | 204 | ||
198 | return 0; | 205 | return 0; |
206 | |||
207 | err_dw_dma_probe: | ||
208 | clk_disable_unprepare(chip->clk); | ||
209 | return err; | ||
199 | } | 210 | } |
200 | 211 | ||
201 | static int dw_remove(struct platform_device *pdev) | 212 | static int dw_remove(struct platform_device *pdev) |
@@ -205,7 +216,10 @@ static int dw_remove(struct platform_device *pdev) | |||
205 | if (pdev->dev.of_node) | 216 | if (pdev->dev.of_node) |
206 | of_dma_controller_free(pdev->dev.of_node); | 217 | of_dma_controller_free(pdev->dev.of_node); |
207 | 218 | ||
208 | return dw_dma_remove(chip); | 219 | dw_dma_remove(chip); |
220 | clk_disable_unprepare(chip->clk); | ||
221 | |||
222 | return 0; | ||
209 | } | 223 | } |
210 | 224 | ||
211 | static void dw_shutdown(struct platform_device *pdev) | 225 | static void dw_shutdown(struct platform_device *pdev) |
@@ -213,6 +227,7 @@ static void dw_shutdown(struct platform_device *pdev) | |||
213 | struct dw_dma_chip *chip = platform_get_drvdata(pdev); | 227 | struct dw_dma_chip *chip = platform_get_drvdata(pdev); |
214 | 228 | ||
215 | dw_dma_shutdown(chip); | 229 | dw_dma_shutdown(chip); |
230 | clk_disable_unprepare(chip->clk); | ||
216 | } | 231 | } |
217 | 232 | ||
218 | #ifdef CONFIG_OF | 233 | #ifdef CONFIG_OF |
@@ -238,7 +253,10 @@ static int dw_suspend_late(struct device *dev) | |||
238 | struct platform_device *pdev = to_platform_device(dev); | 253 | struct platform_device *pdev = to_platform_device(dev); |
239 | struct dw_dma_chip *chip = platform_get_drvdata(pdev); | 254 | struct dw_dma_chip *chip = platform_get_drvdata(pdev); |
240 | 255 | ||
241 | return dw_dma_suspend(chip); | 256 | dw_dma_suspend(chip); |
257 | clk_disable_unprepare(chip->clk); | ||
258 | |||
259 | return 0; | ||
242 | } | 260 | } |
243 | 261 | ||
244 | static int dw_resume_early(struct device *dev) | 262 | static int dw_resume_early(struct device *dev) |
@@ -246,6 +264,7 @@ static int dw_resume_early(struct device *dev) | |||
246 | struct platform_device *pdev = to_platform_device(dev); | 264 | struct platform_device *pdev = to_platform_device(dev); |
247 | struct dw_dma_chip *chip = platform_get_drvdata(pdev); | 265 | struct dw_dma_chip *chip = platform_get_drvdata(pdev); |
248 | 266 | ||
267 | clk_prepare_enable(chip->clk); | ||
249 | return dw_dma_resume(chip); | 268 | return dw_dma_resume(chip); |
250 | } | 269 | } |
251 | 270 | ||
diff --git a/drivers/dma/dw/regs.h b/drivers/dma/dw/regs.h index 0e82d9972c17..00d27a9d9c27 100644 --- a/drivers/dma/dw/regs.h +++ b/drivers/dma/dw/regs.h | |||
@@ -251,7 +251,6 @@ struct dw_dma { | |||
251 | void __iomem *regs; | 251 | void __iomem *regs; |
252 | struct dma_pool *desc_pool; | 252 | struct dma_pool *desc_pool; |
253 | struct tasklet_struct tasklet; | 253 | struct tasklet_struct tasklet; |
254 | struct clk *clk; | ||
255 | 254 | ||
256 | /* channels */ | 255 | /* channels */ |
257 | struct dw_dma_chan *chan; | 256 | struct dw_dma_chan *chan; |