diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-18 18:11:04 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-18 18:11:04 -0700 |
commit | 52d589a01d4545ce1dc5c3892bb8c7b55edfe714 (patch) | |
tree | 864858dae5d01aae411497e926679cf92392b4f6 | |
parent | 0a582821d4f8edf41d9b56ae057ee2002fc275f0 (diff) | |
parent | 6b997bab20448cfe85456e4789d5d9222ab6b830 (diff) |
Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma
Pull slave-dmaengine updates from Vinod Koul:
"For dmaengine contributions we have:
- designware cleanup by Andy
- my series moving device_control users to dmanegine_xxx APIs for
later removal of device_control API
- minor fixes spread over drivers mainly mv_xor, pl330, mmp, imx-sdma
etc"
* 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma: (60 commits)
serial: atmel: add missing dmaengine header
dmaengine: remove FSLDMA_EXTERNAL_START
dmaengine: freescale: remove FSLDMA_EXTERNAL_START control method
carma-fpga: move to fsl_dma_external_start()
carma-fpga: use dmaengine_xxx() API
dmaengine: freescale: add and export fsl_dma_external_start()
dmaengine: add dmaengine_prep_dma_sg() helper
video: mx3fb: use dmaengine_terminate_all() API
serial: sh-sci: use dmaengine_terminate_all() API
net: ks8842: use dmaengine_terminate_all() API
mtd: sh_flctl: use dmaengine_terminate_all() API
mtd: fsmc_nand: use dmaengine_terminate_all() API
V4L2: mx3_camer: use dmaengine_pause() API
dmaengine: coh901318: use dmaengine_terminate_all() API
pata_arasan_cf: use dmaengine_terminate_all() API
dmaengine: edma: check for echan->edesc => NULL in edma_dma_pause()
dmaengine: dw: export probe()/remove() and Co to users
dmaengine: dw: enable and disable controller when needed
dmaengine: dw: always export dw_dma_{en,dis}able
dmaengine: dw: introduce dw_dma_on() helper
...
50 files changed, 835 insertions, 692 deletions
diff --git a/Documentation/devicetree/bindings/dma/qcom_adm.txt b/Documentation/devicetree/bindings/dma/qcom_adm.txt new file mode 100644 index 000000000000..9bcab9115982 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/qcom_adm.txt @@ -0,0 +1,62 @@ +QCOM ADM DMA Controller + +Required properties: +- compatible: must contain "qcom,adm" for IPQ/APQ8064 and MSM8960 +- reg: Address range for DMA registers +- interrupts: Should contain one interrupt shared by all channels +- #dma-cells: must be <2>. First cell denotes the channel number. Second cell + denotes CRCI (client rate control interface) flow control assignment. +- clocks: Should contain the core clock and interface clock. +- clock-names: Must contain "core" for the core clock and "iface" for the + interface clock. +- resets: Must contain an entry for each entry in reset names. +- reset-names: Must include the following entries: + - clk + - c0 + - c1 + - c2 +- qcom,ee: indicates the security domain identifier used in the secure world. + +Example: + adm_dma: dma@18300000 { + compatible = "qcom,adm"; + reg = <0x18300000 0x100000>; + interrupts = <0 170 0>; + #dma-cells = <2>; + + clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>; + clock-names = "core", "iface"; + + resets = <&gcc ADM0_RESET>, + <&gcc ADM0_C0_RESET>, + <&gcc ADM0_C1_RESET>, + <&gcc ADM0_C2_RESET>; + reset-names = "clk", "c0", "c1", "c2"; + qcom,ee = <0>; + }; + +DMA clients must use the format descripted in the dma.txt file, using a three +cell specifier for each channel. + +Each dmas request consists of 3 cells: + 1. phandle pointing to the DMA controller + 2. channel number + 3. CRCI assignment, if applicable. If no CRCI flow control is required, use 0. + The CRCI is used for flow control. It identifies the peripheral device that + is the source/destination for the transferred data. + +Example: + + spi4: spi@1a280000 { + status = "ok"; + spi-max-frequency = <50000000>; + + pinctrl-0 = <&spi_pins>; + pinctrl-names = "default"; + + cs-gpios = <&qcom_pinmux 20 0>; + + dmas = <&adm_dma 6 9>, + <&adm_dma 5 10>; + dma-names = "rx", "tx"; + }; diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt new file mode 100644 index 000000000000..2291c4098730 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt @@ -0,0 +1,65 @@ +Xilinx AXI DMA engine, it does transfers between memory and AXI4 stream +target devices. It can be configured to have one channel or two channels. +If configured as two channels, one is to transmit to the device and another +is to receive from the device. + +Required properties: +- compatible: Should be "xlnx,axi-dma-1.00.a" +- #dma-cells: Should be <1>, see "dmas" property below +- reg: Should contain DMA registers location and length. +- dma-channel child node: Should have atleast one channel and can have upto + two channels per device. This node specifies the properties of each + DMA channel (see child node properties below). + +Optional properties: +- xlnx,include-sg: Tells whether configured for Scatter-mode in + the hardware. + +Required child node properties: +- compatible: It should be either "xlnx,axi-dma-mm2s-channel" or + "xlnx,axi-dma-s2mm-channel". +- interrupts: Should contain per channel DMA interrupts. +- xlnx,datawidth: Should contain the stream data width, take values + {32,64...1024}. + +Option child node properties: +- xlnx,include-dre: Tells whether hardware is configured for Data + Realignment Engine. + +Example: +++++++++ + +axi_dma_0: axidma@40400000 { + compatible = "xlnx,axi-dma-1.00.a"; + #dma_cells = <1>; + reg = < 0x40400000 0x10000 >; + dma-channel@40400000 { + compatible = "xlnx,axi-dma-mm2s-channel"; + interrupts = < 0 59 4 >; + xlnx,datawidth = <0x40>; + } ; + dma-channel@40400030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupts = < 0 58 4 >; + xlnx,datawidth = <0x40>; + } ; +} ; + + +* DMA client + +Required properties: +- dmas: a list of <[DMA device phandle] [Channel ID]> pairs, + where Channel ID is '0' for write/tx and '1' for read/rx + channel. +- dma-names: a list of DMA channel names, one per "dmas" entry + +Example: +++++++++ + +dmatest_0: dmatest@0 { + compatible ="xlnx,axi-dma-test-1.00.a"; + dmas = <&axi_dma_0 0 + &axi_dma_0 1>; + dma-names = "dma0", "dma1"; +} ; diff --git a/Documentation/dmaengine.txt b/Documentation/dmaengine.txt index 573e28ce9751..11fb87ff6cd0 100644 --- a/Documentation/dmaengine.txt +++ b/Documentation/dmaengine.txt @@ -98,7 +98,7 @@ The slave DMA usage consists of following steps: unsigned long flags); The peripheral driver is expected to have mapped the scatterlist for - the DMA operation prior to calling device_prep_slave_sg, and must + the DMA operation prior to calling dmaengine_prep_slave_sg(), and must keep the scatterlist mapped until the DMA operation has completed. The scatterlist must be mapped using the DMA struct device. If a mapping needs to be synchronized later, dma_sync_*_for_*() must be @@ -195,5 +195,5 @@ Further APIs: Note: Not all DMA engine drivers can return reliable information for a running DMA channel. It is recommended that DMA engine users - pause or stop (via dmaengine_terminate_all) the channel before + pause or stop (via dmaengine_terminate_all()) the channel before using this API. diff --git a/MAINTAINERS b/MAINTAINERS index 6c59c6697a54..33c0d433d554 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8062,7 +8062,7 @@ SYNOPSYS DESIGNWARE DMAC DRIVER M: Viresh Kumar <viresh.linux@gmail.com> M: Andy Shevchenko <andriy.shevchenko@linux.intel.com> S: Maintained -F: include/linux/dw_dmac.h +F: include/linux/platform_data/dma-dw.h F: drivers/dma/dw/ SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index db85b5ec3351..37b75602adf6 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -7,7 +7,7 @@ */ #include <linux/clk.h> #include <linux/delay.h> -#include <linux/dw_dmac.h> +#include <linux/platform_data/dma-dw.h> #include <linux/fb.h> #include <linux/init.h> #include <linux/platform_device.h> @@ -1356,10 +1356,10 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) goto fail; slave->sdata.dma_dev = &dw_dmac0_device.dev; - slave->sdata.cfg_hi = (DWC_CFGH_SRC_PER(0) - | DWC_CFGH_DST_PER(1)); - slave->sdata.cfg_lo &= ~(DWC_CFGL_HS_DST_POL - | DWC_CFGL_HS_SRC_POL); + slave->sdata.src_id = 0; + slave->sdata.dst_id = 1; + slave->sdata.src_master = 1; + slave->sdata.dst_master = 0; data->dma_slave = slave; @@ -2052,8 +2052,7 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, /* Check if DMA slave interface for capture should be configured. */ if (flags & AC97C_CAPTURE) { rx_dws->dma_dev = &dw_dmac0_device.dev; - rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3); - rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + rx_dws->src_id = 3; rx_dws->src_master = 0; rx_dws->dst_master = 1; } @@ -2061,8 +2060,7 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, /* Check if DMA slave interface for playback should be configured. */ if (flags & AC97C_PLAYBACK) { tx_dws->dma_dev = &dw_dmac0_device.dev; - tx_dws->cfg_hi = DWC_CFGH_DST_PER(4); - tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + tx_dws->dst_id = 4; tx_dws->src_master = 0; tx_dws->dst_master = 1; } @@ -2134,8 +2132,7 @@ at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data) dws = &data->dws; dws->dma_dev = &dw_dmac0_device.dev; - dws->cfg_hi = DWC_CFGH_DST_PER(2); - dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + dws->dst_id = 2; dws->src_master = 0; dws->dst_master = 1; diff --git a/arch/avr32/mach-at32ap/include/mach/atmel-mci.h b/arch/avr32/mach-at32ap/include/mach/atmel-mci.h index 4bba58561d5c..11d7f4b28dc8 100644 --- a/arch/avr32/mach-at32ap/include/mach/atmel-mci.h +++ b/arch/avr32/mach-at32ap/include/mach/atmel-mci.h @@ -1,7 +1,7 @@ #ifndef __MACH_ATMEL_MCI_H #define __MACH_ATMEL_MCI_H -#include <linux/dw_dmac.h> +#include <linux/platform_data/dma-dw.h> /** * struct mci_dma_data - DMA data for MCI interface diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 4edb1a81f63f..38216b991474 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -420,7 +420,7 @@ dma_xfer(struct arasan_cf_dev *acdev, dma_addr_t src, dma_addr_t dest, u32 len) /* Wait for DMA to complete */ if (!wait_for_completion_timeout(&acdev->dma_completion, TIMEOUT)) { - chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(chan); dev_err(acdev->host->dev, "wait_for_completion_timeout\n"); return -ETIMEDOUT; } @@ -928,8 +928,7 @@ static int arasan_cf_suspend(struct device *dev) struct arasan_cf_dev *acdev = host->ports[0]->private_data; if (acdev->dma_chan) - acdev->dma_chan->device->device_control(acdev->dma_chan, - DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(acdev->dma_chan); cf_exit(acdev); return ata_host_suspend(host, PMSG_SUSPEND); diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index a016490c95ae..de469821bc1b 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -270,7 +270,7 @@ config IMX_SDMA select DMA_ENGINE help Support the i.MX SDMA engine. This engine is integrated into - Freescale i.MX25/31/35/51/53 chips. + Freescale i.MX25/31/35/51/53/6 chips. config IMX_DMA tristate "i.MX DMA support" diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 3c6716e0b78e..e88588d8ecd3 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -2156,7 +2156,7 @@ coh901318_free_chan_resources(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); - chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(chan); } diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index 8f8b0b608875..a58eec3b2cad 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -938,7 +938,7 @@ static int cppi41_dma_probe(struct platform_device *pdev) if (!glue_info) return -EINVAL; - cdd = kzalloc(sizeof(*cdd), GFP_KERNEL); + cdd = devm_kzalloc(&pdev->dev, sizeof(*cdd), GFP_KERNEL); if (!cdd) return -ENOMEM; @@ -959,10 +959,8 @@ static int cppi41_dma_probe(struct platform_device *pdev) cdd->qmgr_mem = of_iomap(dev->of_node, 3); if (!cdd->usbss_mem || !cdd->ctrl_mem || !cdd->sched_mem || - !cdd->qmgr_mem) { - ret = -ENXIO; - goto err_remap; - } + !cdd->qmgr_mem) + return -ENXIO; pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); @@ -989,7 +987,7 @@ static int cppi41_dma_probe(struct platform_device *pdev) cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); - ret = request_irq(irq, glue_info->isr, IRQF_SHARED, + ret = devm_request_irq(&pdev->dev, irq, glue_info->isr, IRQF_SHARED, dev_name(dev), cdd); if (ret) goto err_irq; @@ -1009,7 +1007,6 @@ static int cppi41_dma_probe(struct platform_device *pdev) err_of: dma_async_device_unregister(&cdd->ddev); err_dma_reg: - free_irq(irq, cdd); err_irq: cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); cleanup_chans(cdd); @@ -1023,8 +1020,6 @@ err_get_sync: iounmap(cdd->ctrl_mem); iounmap(cdd->sched_mem); iounmap(cdd->qmgr_mem); -err_remap: - kfree(cdd); return ret; } @@ -1036,7 +1031,7 @@ static int cppi41_dma_remove(struct platform_device *pdev) dma_async_device_unregister(&cdd->ddev); cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); - free_irq(cdd->irq, cdd); + devm_free_irq(&pdev->dev, cdd->irq, cdd); cleanup_chans(cdd); deinit_cppi41(&pdev->dev, cdd); iounmap(cdd->usbss_mem); @@ -1045,7 +1040,6 @@ static int cppi41_dma_remove(struct platform_device *pdev) iounmap(cdd->qmgr_mem); pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); - kfree(cdd); return 0; } diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 1af731b83b3f..244722170410 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -11,7 +11,6 @@ */ #include <linux/bitops.h> -#include <linux/clk.h> #include <linux/delay.h> #include <linux/dmaengine.h> #include <linux/dma-mapping.h> @@ -37,24 +36,6 @@ * support descriptor writeback. */ -static inline bool is_request_line_unset(struct dw_dma_chan *dwc) -{ - return dwc->request_line == (typeof(dwc->request_line))~0; -} - -static inline void dwc_set_masters(struct dw_dma_chan *dwc) -{ - struct dw_dma *dw = to_dw_dma(dwc->chan.device); - struct dw_dma_slave *dws = dwc->chan.private; - unsigned char mmax = dw->nr_masters - 1; - - if (!is_request_line_unset(dwc)) - return; - - dwc->src_master = min_t(unsigned char, mmax, dwc_get_sms(dws)); - dwc->dst_master = min_t(unsigned char, mmax, dwc_get_dms(dws)); -} - #define DWC_DEFAULT_CTLLO(_chan) ({ \ struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan); \ struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \ @@ -155,13 +136,11 @@ static void dwc_initialize(struct dw_dma_chan *dwc) */ BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev); - cfghi = dws->cfg_hi; - cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK; + cfghi |= DWC_CFGH_DST_PER(dws->dst_id); + cfghi |= DWC_CFGH_SRC_PER(dws->src_id); } else { - if (dwc->direction == DMA_MEM_TO_DEV) - cfghi = DWC_CFGH_DST_PER(dwc->request_line); - else if (dwc->direction == DMA_DEV_TO_MEM) - cfghi = DWC_CFGH_SRC_PER(dwc->request_line); + cfghi |= DWC_CFGH_DST_PER(dwc->dst_id); + cfghi |= DWC_CFGH_SRC_PER(dwc->src_id); } channel_writel(dwc, CFG_LO, cfglo); @@ -939,6 +918,26 @@ err_desc_get: return NULL; } +bool dw_dma_filter(struct dma_chan *chan, void *param) +{ + struct dw_dma_chan *dwc = to_dw_dma_chan(chan); + struct dw_dma_slave *dws = param; + + if (!dws || dws->dma_dev != chan->device->dev) + return false; + + /* We have to copy data since dws can be temporary storage */ + + dwc->src_id = dws->src_id; + dwc->dst_id = dws->dst_id; + + dwc->src_master = dws->src_master; + dwc->dst_master = dws->dst_master; + + return true; +} +EXPORT_SYMBOL_GPL(dw_dma_filter); + /* * Fix sconfig's burst size according to dw_dmac. We need to convert them as: * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3. @@ -967,10 +966,6 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig)); dwc->direction = sconfig->direction; - /* Take the request line from slave_id member */ - if (is_request_line_unset(dwc)) - dwc->request_line = sconfig->slave_id; - convert_burst(&dwc->dma_sconfig.src_maxburst); convert_burst(&dwc->dma_sconfig.dst_maxburst); @@ -1099,6 +1094,31 @@ static void dwc_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&dwc->lock, flags); } +/*----------------------------------------------------------------------*/ + +static void dw_dma_off(struct dw_dma *dw) +{ + int i; + + dma_writel(dw, CFG, 0); + + channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask); + channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask); + channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask); + channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask); + + while (dma_readl(dw, CFG) & DW_CFG_DMA_EN) + cpu_relax(); + + for (i = 0; i < dw->dma.chancnt; i++) + dw->chan[i].initialized = false; +} + +static void dw_dma_on(struct dw_dma *dw) +{ + dma_writel(dw, CFG, DW_CFG_DMA_EN); +} + static int dwc_alloc_chan_resources(struct dma_chan *chan) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); @@ -1123,7 +1143,10 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) * doesn't mean what you think it means), and status writeback. */ - dwc_set_masters(dwc); + /* Enable controller here if needed */ + if (!dw->in_use) + dw_dma_on(dw); + dw->in_use |= dwc->mask; spin_lock_irqsave(&dwc->lock, flags); i = dwc->descs_allocated; @@ -1182,7 +1205,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan) list_splice_init(&dwc->free_list, &list); dwc->descs_allocated = 0; dwc->initialized = false; - dwc->request_line = ~0; /* Disable interrupts */ channel_clear_bit(dw, MASK.XFER, dwc->mask); @@ -1190,6 +1212,11 @@ static void dwc_free_chan_resources(struct dma_chan *chan) spin_unlock_irqrestore(&dwc->lock, flags); + /* Disable controller in case it was a last user */ + dw->in_use &= ~dwc->mask; + if (!dw->in_use) + dw_dma_off(dw); + list_for_each_entry_safe(desc, _desc, &list, desc_node) { dev_vdbg(chan2dev(chan), " freeing descriptor %p\n", desc); dma_pool_free(dw->desc_pool, desc, desc->txd.phys); @@ -1460,24 +1487,6 @@ EXPORT_SYMBOL(dw_dma_cyclic_free); /*----------------------------------------------------------------------*/ -static void dw_dma_off(struct dw_dma *dw) -{ - int i; - - dma_writel(dw, CFG, 0); - - channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask); - channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask); - channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask); - channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask); - - while (dma_readl(dw, CFG) & DW_CFG_DMA_EN) - cpu_relax(); - - for (i = 0; i < dw->dma.chancnt; i++) - dw->chan[i].initialized = false; -} - int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) { struct dw_dma *dw; @@ -1495,13 +1504,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) dw->regs = chip->regs; chip->dw = dw; - dw->clk = devm_clk_get(chip->dev, "hclk"); - if (IS_ERR(dw->clk)) - return PTR_ERR(dw->clk); - err = clk_prepare_enable(dw->clk); - if (err) - return err; - dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); autocfg = dw_params >> DW_PARAMS_EN & 0x1; @@ -1604,7 +1606,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) channel_clear_bit(dw, CH_EN, dwc->mask); dwc->direction = DMA_TRANS_NONE; - dwc->request_line = ~0; /* Hardware configuration */ if (autocfg) { @@ -1659,8 +1660,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) dw->dma.device_tx_status = dwc_tx_status; dw->dma.device_issue_pending = dwc_issue_pending; - dma_writel(dw, CFG, DW_CFG_DMA_EN); - err = dma_async_device_register(&dw->dma); if (err) goto err_dma_register; @@ -1673,7 +1672,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) err_dma_register: free_irq(chip->irq, dw); err_pdata: - clk_disable_unprepare(dw->clk); return err; } EXPORT_SYMBOL_GPL(dw_dma_probe); @@ -1695,46 +1693,27 @@ int dw_dma_remove(struct dw_dma_chip *chip) channel_clear_bit(dw, CH_EN, dwc->mask); } - clk_disable_unprepare(dw->clk); - return 0; } EXPORT_SYMBOL_GPL(dw_dma_remove); -void dw_dma_shutdown(struct dw_dma_chip *chip) -{ - struct dw_dma *dw = chip->dw; - - dw_dma_off(dw); - clk_disable_unprepare(dw->clk); -} -EXPORT_SYMBOL_GPL(dw_dma_shutdown); - -#ifdef CONFIG_PM_SLEEP - -int dw_dma_suspend(struct dw_dma_chip *chip) +int dw_dma_disable(struct dw_dma_chip *chip) { struct dw_dma *dw = chip->dw; dw_dma_off(dw); - clk_disable_unprepare(dw->clk); - return 0; } -EXPORT_SYMBOL_GPL(dw_dma_suspend); +EXPORT_SYMBOL_GPL(dw_dma_disable); -int dw_dma_resume(struct dw_dma_chip *chip) +int dw_dma_enable(struct dw_dma_chip *chip) { struct dw_dma *dw = chip->dw; - clk_prepare_enable(dw->clk); - dma_writel(dw, CFG, DW_CFG_DMA_EN); - + dw_dma_on(dw); return 0; } -EXPORT_SYMBOL_GPL(dw_dma_resume); - -#endif /* CONFIG_PM_SLEEP */ +EXPORT_SYMBOL_GPL(dw_dma_enable); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller core driver"); diff --git a/drivers/dma/dw/internal.h b/drivers/dma/dw/internal.h index 32667f9e0dda..41439732ff6b 100644 --- a/drivers/dma/dw/internal.h +++ b/drivers/dma/dw/internal.h @@ -8,63 +8,16 @@ * published by the Free Software Foundation. */ -#ifndef _DW_DMAC_INTERNAL_H -#define _DW_DMAC_INTERNAL_H +#ifndef _DMA_DW_INTERNAL_H +#define _DMA_DW_INTERNAL_H -#include <linux/device.h> -#include <linux/dw_dmac.h> +#include <linux/dma/dw.h> #include "regs.h" -/** - * struct dw_dma_chip - representation of DesignWare DMA controller hardware - * @dev: struct device of the DMA controller - * @irq: irq line - * @regs: memory mapped I/O space - * @dw: struct dw_dma that is filed by dw_dma_probe() - */ -struct dw_dma_chip { - struct device *dev; |