Merge tag 'dmaengine-4.10-rc1' of git://git.infradead.org/users/vkoul/slave-dma

Pull dmaengine updates from Vinod Koul:
 "Fairly routine update this time around with all changes specific to
  drivers:

   - New driver for STMicroelectronics FDMA
   - Memory-to-memory transfers on dw dmac
   - Support for slave maps on pl08x devices
   - Bunch of driver fixes to use dma_pool_zalloc
   - Bunch of compile and warning fixes spread across drivers"

[ The ST FDMA driver already came in earlier through the remoteproc tree ]

* tag 'dmaengine-4.10-rc1' of git://git.infradead.org/users/vkoul/slave-dma: (68 commits)
  dmaengine: sirf-dma: remove unused ‘sdesc’
  dmaengine: pl330: remove unused ‘regs’
  dmaengine: s3c24xx: remove unused ‘cdata’
  dmaengine: stm32-dma: remove unused ‘src_addr’
  dmaengine: stm32-dma: remove unused ‘dst_addr’
  dmaengine: stm32-dma: remove unused ‘sfcr’
  dmaengine: pch_dma: remove unused ‘cookie’
  dmaengine: mic_x100_dma: remove unused ‘data’
  dmaengine: img-mdc: remove unused ‘prev_phys’
  dmaengine: usb-dmac: remove unused ‘uchan’
  dmaengine: ioat: remove unused ‘res’
  dmaengine: ioat: remove unused ‘ioat_dma’
  dmaengine: ioat: remove unused ‘is_raid_device’
  dmaengine: pl330: do not generate unaligned access
  dmaengine: k3dma: move to dma_pool_zalloc
  dmaengine: at_hdmac: move to dma_pool_zalloc
  dmaengine: at_xdmac: don't restore unsaved status
  dmaengine: ioat: set error code on failures
  dmaengine: ioat: set error code on failures
  dmaengine: DW DMAC: add multi-block property to device tree
  ...
This commit is contained in:
Linus Torvalds committed 2016-12-14 20:42:45 -08:00
commit e3842cbfe0
53 files changed
+868 -349

No files matched your search

@@ -23,6 +23,14 @@ Required properties
#define NBPF_SLAVE_RQ_LEVEL 4
Optional properties:
- max-burst-mem-read: limit burst size for memory reads
(DMA_MEM_TO_MEM/DMA_MEM_TO_DEV) to this value, specified in bytes, rather
than using the maximum burst size allowed by the hardware's buffer size.
- max-burst-mem-write: limit burst size for memory writes
(DMA_DEV_TO_MEM/DMA_MEM_TO_MEM) to this value, specified in bytes, rather
than using the maximum burst size allowed by the hardware's buffer size.
If both max-burst-mem-read and max-burst-mem-write are set, DMA_MEM_TO_MEM
will use the lower value.
You can use dma-channels and dma-requests as described in dma.txt, although they
won't be used, this information is derived from the compatibility string.
@@ -5,13 +5,13 @@ memcpy and memset capabilities. It has been designed for virtualized
environments.
Each HIDMA HW instance consists of multiple DMA channels. These channels
share the same bandwidth. The bandwidth utilization can be parititioned
share the same bandwidth. The bandwidth utilization can be partitioned
among channels based on the priority and weight assignments.
There are only two priority levels and 15 weigh assignments possible.
Other parameters here determine how much of the system bus this HIDMA
instance can use like maximum read/write request and and number of bytes to
instance can use like maximum read/write request and number of bytes to
read/write in a single burst.
Main node required properties:
@@ -47,12 +47,18 @@ When the OS is not in control of the management interface (i.e. it's a guest),
the channel nodes appear on their own, not under a management node.
Required properties:
- compatible: must contain "qcom,hidma-1.0"
- compatible: must contain "qcom,hidma-1.0" for initial HW or "qcom,hidma-1.1"
for MSI capable HW.
- reg: Addresses for the transfer and event channel
- interrupts: Should contain the event interrupt
- desc-count: Number of asynchronous requests this channel can handle
- iommus: required a iommu node
Optional properties for MSI:
- msi-parent : See the generic MSI binding described in
devicetree/bindings/interrupt-controller/msi.txt for a description of the
msi-parent property.
Example:
Hypervisor OS configuration:
@@ -24,6 +24,7 @@ Required Properties:
- "renesas,dmac-r8a7793" (R-Car M2-N)
- "renesas,dmac-r8a7794" (R-Car E2)
- "renesas,dmac-r8a7795" (R-Car H3)
- "renesas,dmac-r8a7796" (R-Car M3-W)
- reg: base address and length of the registers block for the DMAC
@@ -27,6 +27,8 @@ Optional properties:
that services interrupts for this device
- is_private: The device channels should be marked as private and not for by the
general purpose DMA channel allocator. False if not passed.
- multi-block: Multi block transfers supported by hardware. Array property with
one cell per channel. 0: not supported, 1 (default): supported.
Example:
+8 -8
View File
@@ -37,8 +37,8 @@ The slave DMA usage consists of following steps:
2. Set slave and controller specific parameters
Next step is always to pass some specific information to the DMA
driver. Most of the generic information which a slave DMA can use
is in struct dma_slave_config. This allows the clients to specify
driver. Most of the generic information which a slave DMA can use
is in struct dma_slave_config. This allows the clients to specify
DMA direction, DMA addresses, bus widths, DMA burst lengths etc
for the peripheral.
@@ -52,7 +52,7 @@ The slave DMA usage consists of following steps:
struct dma_slave_config *config)
Please see the dma_slave_config structure definition in dmaengine.h
for a detailed explanation of the struct members. Please note
for a detailed explanation of the struct members. Please note
that the 'direction' member will be going away as it duplicates the
direction given in the prepare call.
@@ -101,7 +101,7 @@ The slave DMA usage consists of following steps:
desc = dmaengine_prep_slave_sg(chan, sgl, nr_sg, direction, flags);
Once a descriptor has been obtained, the callback information can be
added and the descriptor must then be submitted. Some DMA engine
added and the descriptor must then be submitted. Some DMA engine
drivers may hold a spinlock between a successful preparation and
submission so it is important that these two operations are closely
paired.
@@ -138,7 +138,7 @@ The slave DMA usage consists of following steps:
activity via other DMA engine calls not covered in this document.
dmaengine_submit() will not start the DMA operation, it merely adds
it to the pending queue. For this, see step 5, dma_async_issue_pending.
it to the pending queue. For this, see step 5, dma_async_issue_pending.
5. Issue pending DMA requests and wait for callback notification
@@ -184,13 +184,13 @@ Further APIs:
3. int dmaengine_resume(struct dma_chan *chan)
Resume a previously paused DMA channel. It is invalid to resume a
Resume a previously paused DMA channel. It is invalid to resume a
channel which is not currently paused.
4. enum dma_status dma_async_is_tx_complete(struct dma_chan *chan,
dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used)
This can be used to check the status of the channel. Please see
This can be used to check the status of the channel. Please see
the documentation in include/linux/dmaengine.h for a more complete
description of this API.
@@ -200,7 +200,7 @@ Further APIs:
Note:
Not all DMA engine drivers can return reliable information for
a running DMA channel. It is recommended that DMA engine users
a running DMA channel. It is recommended that DMA engine users
pause or stop (via dmaengine_terminate_all()) the channel before
using this API.
+5 -5
View File
@@ -34,7 +34,7 @@ command:
% ls -1 /sys/class/dma/
Once started a message like "dmatest: Started 1 threads using dma0chan0" is
emitted. After that only test failure messages are reported until the test
emitted. After that only test failure messages are reported until the test
stops.
Note that running a new test will not stop any in progress test.
@@ -43,11 +43,11 @@ The following command returns the state of the test.
% cat /sys/module/dmatest/parameters/run
To wait for test completion userpace can poll 'run' until it is false, or use
the wait parameter. Specifying 'wait=1' when loading the module causes module
the wait parameter. Specifying 'wait=1' when loading the module causes module
initialization to pause until a test run has completed, while reading
/sys/module/dmatest/parameters/wait waits for any running test to complete
before returning. For example, the following scripts wait for 42 tests
to complete before exiting. Note that if 'iterations' is set to 'infinite' then
before returning. For example, the following scripts wait for 42 tests
to complete before exiting. Note that if 'iterations' is set to 'infinite' then
waiting is disabled.
Example:
@@ -81,7 +81,7 @@ Example of output:
The message format is unified across the different types of errors. A number in
the parens represents additional information, e.g. error code, error counter,
or status. A test thread also emits a summary line at completion listing the
or status. A test thread also emits a summary line at completion listing the
number of tests executed, number that failed, and a result code.
Example:
+1 -1
View File
@@ -384,7 +384,7 @@ where to put them)
- The descriptor should be prepared for reuse by invoking
dmaengine_desc_set_reuse() which will set DMA_CTRL_REUSE.
- dmaengine_desc_set_reuse() will succeed only when channel support
reusable descriptor as exhibited by capablities
reusable descriptor as exhibited by capabilities
- As a consequence, if a device driver wants to skip the dma_map_sg() and
dma_unmap_sg() in between 2 transfers, because the DMA'd data wasn't used,
it can resubmit the transfer right after its completion.
+1 -1
View File
@@ -29,7 +29,7 @@ Constraints
d) Bandwidth guarantee
The PXA architecture has 4 levels of DMAs priorities : high, normal, low.
The high prorities get twice as much bandwidth as the normal, which get twice
The high priorities get twice as much bandwidth as the normal, which get twice
as much as the low priorities.
A driver should be able to request a priority, especially the real-time
ones such as pxa_camera with (big) throughputs.
+1
View File
@@ -129,6 +129,7 @@
data-width = <4>;
clocks = <&ahb_clk>;
clock-names = "hclk";
multi-block = <1 1 1 1 1 1>;
};
i2c0: i2c@FF120000 {
+2
View File
@@ -118,6 +118,7 @@
block_size = <0xfff>;
dma-masters = <2>;
data-width = <8 8>;
multi-block = <1 1 1 1 1 1 1 1>;
};
dma@eb000000 {
@@ -134,6 +135,7 @@
chan_priority = <1>;
block_size = <0xfff>;
data-width = <8 8>;
multi-block = <1 1 1 1 1 1 1 1>;
};
fsmc: flash@b0000000 {
+32
View File
@@ -117,6 +117,25 @@ static struct pl08x_channel_data s3c64xx_dma0_info[] = {
}
};
static const struct dma_slave_map s3c64xx_dma0_slave_map[] = {
{ "s3c6400-uart.0", "tx", &s3c64xx_dma0_info[0] },
{ "s3c6400-uart.0", "rx", &s3c64xx_dma0_info[1] },
{ "s3c6400-uart.1", "tx", &s3c64xx_dma0_info[2] },
{ "s3c6400-uart.1", "rx", &s3c64xx_dma0_info[3] },
{ "s3c6400-uart.2", "tx", &s3c64xx_dma0_info[4] },
{ "s3c6400-uart.2", "rx", &s3c64xx_dma0_info[5] },
{ "s3c6400-uart.3", "tx", &s3c64xx_dma0_info[6] },
{ "s3c6400-uart.3", "rx", &s3c64xx_dma0_info[7] },
{ "samsung-pcm.0", "tx", &s3c64xx_dma0_info[8] },
{ "samsung-pcm.0", "rx", &s3c64xx_dma0_info[9] },
{ "samsung-i2s.0", "tx", &s3c64xx_dma0_info[10] },
{ "samsung-i2s.0", "rx", &s3c64xx_dma0_info[11] },
{ "s3c6410-spi.0", "tx", &s3c64xx_dma0_info[12] },
{ "s3c6410-spi.0", "rx", &s3c64xx_dma0_info[13] },
{ "samsung-i2s.2", "tx", &s3c64xx_dma0_info[14] },
{ "samsung-i2s.2", "rx", &s3c64xx_dma0_info[15] },
};
struct pl08x_platform_data s3c64xx_dma0_plat_data = {
.memcpy_channel = {
.bus_id = "memcpy",
@@ -134,6 +153,8 @@ struct pl08x_platform_data s3c64xx_dma0_plat_data = {
.put_xfer_signal = pl08x_put_xfer_signal,
.slave_channels = s3c64xx_dma0_info,
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
.slave_map = s3c64xx_dma0_slave_map,
.slave_map_len = ARRAY_SIZE(s3c64xx_dma0_slave_map),
};
static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
@@ -207,6 +228,15 @@ static struct pl08x_channel_data s3c64xx_dma1_info[] = {
},
};
static const struct dma_slave_map s3c64xx_dma1_slave_map[] = {
{ "samsung-pcm.1", "tx", &s3c64xx_dma1_info[0] },
{ "samsung-pcm.1", "rx", &s3c64xx_dma1_info[1] },
{ "samsung-i2s.1", "tx", &s3c64xx_dma1_info[2] },
{ "samsung-i2s.1", "rx", &s3c64xx_dma1_info[3] },
{ "s3c6410-spi.1", "tx", &s3c64xx_dma1_info[4] },
{ "s3c6410-spi.1", "rx", &s3c64xx_dma1_info[5] },
};
struct pl08x_platform_data s3c64xx_dma1_plat_data = {
.memcpy_channel = {
.bus_id = "memcpy",
@@ -224,6 +254,8 @@ struct pl08x_platform_data s3c64xx_dma1_plat_data = {
.put_xfer_signal = pl08x_put_xfer_signal,
.slave_channels = s3c64xx_dma1_info,
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
.slave_map = s3c64xx_dma1_slave_map,
.slave_map_len = ARRAY_SIZE(s3c64xx_dma1_slave_map),
};
static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
-24
View File
@@ -1124,15 +1124,6 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
pd.dma_tx = (void *)DMACH_SPI0_TX;
pd.dma_rx = (void *)DMACH_SPI0_RX;
#if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
pd.filter = pl08x_filter_id;
#elif defined(CONFIG_S3C24XX_DMAC)
pd.filter = s3c24xx_dma_filter;
#endif
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0);
}
@@ -1169,14 +1160,6 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
pd.dma_tx = (void *)DMACH_SPI1_TX;
pd.dma_rx = (void *)DMACH_SPI1_RX;
#if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
pd.filter = pl08x_filter_id;
#endif
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
}
@@ -1213,13 +1196,6 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
pd.dma_tx = (void *)DMACH_SPI2_TX;
pd.dma_rx = (void *)DMACH_SPI2_RX;
#if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
pd.filter = pl08x_filter_id;
#endif
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
}
+1 -1
View File
@@ -494,7 +494,7 @@ config TEGRA20_APB_DMA
or vice versa. It does not support memory to memory data transfer.
config TEGRA210_ADMA
bool "NVIDIA Tegra210 ADMA support"
tristate "NVIDIA Tegra210 ADMA support"
depends on (ARCH_TEGRA_210_SOC || COMPILE_TEST) && PM_CLK
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
+11
View File
@@ -1793,6 +1793,13 @@ bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
}
EXPORT_SYMBOL_GPL(pl08x_filter_id);
static bool pl08x_filter_fn(struct dma_chan *chan, void *chan_id)
{
struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
return plchan->cd == chan_id;
}
/*
* Just check that the device is there and active
* TODO: turn this bit on/off depending on the number of physical channels
@@ -2307,6 +2314,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
ret = -EINVAL;
goto out_no_platdata;
}
} else {
pl08x->slave.filter.map = pl08x->pd->slave_map;
pl08x->slave.filter.mapcnt = pl08x->pd->slave_map_len;
pl08x->slave.filter.fn = pl08x_filter_fn;
}
/* By default, AHB1 only. If dualmaster, from platform */
+1 -2
View File
@@ -111,9 +111,8 @@ static struct at_desc *atc_alloc_descriptor(struct dma_chan *chan,
struct at_dma *atdma = to_at_dma(chan->device);
dma_addr_t phys;
desc = dma_pool_alloc(atdma->dma_desc_pool, gfp_flags, &phys);
desc = dma_pool_zalloc(atdma->dma_desc_pool, gfp_flags, &phys);
if (desc) {
memset(desc, 0, sizeof(struct at_desc));
INIT_LIST_HEAD(&desc->tx_list);
dma_async_tx_descriptor_init(&desc->txd, chan);
/* txd.flags will be overwritten in prep functions */
+1 -4
View File
@@ -221,7 +221,6 @@ struct at_xdmac {
int irq;
struct clk *clk;
u32 save_gim;
u32 save_gs;
struct dma_pool *at_xdmac_desc_pool;
struct at_xdmac_chan chan[0];
};
@@ -444,9 +443,8 @@ static struct at_xdmac_desc *at_xdmac_alloc_desc(struct dma_chan *chan,
struct at_xdmac *atxdmac = to_at_xdmac(chan->device);
dma_addr_t phys;
desc = dma_pool_alloc(atxdmac->at_xdmac_desc_pool, gfp_flags, &phys);
desc = dma_pool_zalloc(atxdmac->at_xdmac_desc_pool, gfp_flags, &phys);
if (desc) {
memset(desc, 0, sizeof(*desc));
INIT_LIST_HEAD(&desc->descs_list);
dma_async_tx_descriptor_init(&desc->tx_dma_desc, chan);
desc->tx_dma_desc.tx_submit = at_xdmac_tx_submit;
@@ -1896,7 +1894,6 @@ static int atmel_xdmac_resume(struct device *dev)
}
at_xdmac_write(atxdmac, AT_XDMAC_GIE, atxdmac->save_gim);
at_xdmac_write(atxdmac, AT_XDMAC_GE, atxdmac->save_gs);
list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) {
atchan = to_at_xdmac_chan(chan);
at_xdmac_chan_write(atchan, AT_XDMAC_CC, atchan->save_cc);
+50 -24
View File
@@ -164,7 +164,9 @@ struct dmatest_thread {
struct task_struct *task;
struct dma_chan *chan;
u8 **srcs;
u8 **usrcs;
u8 **dsts;
u8 **udsts;
enum dma_transaction_type type;
bool done;
};
@@ -431,6 +433,7 @@ static int dmatest_func(void *data)
ktime_t comparetime = ktime_set(0, 0);
s64 runtime = 0;
unsigned long long total_len = 0;
u8 align = 0;
set_freezable();
@@ -441,20 +444,24 @@ static int dmatest_func(void *data)
params = &info->params;
chan = thread->chan;
dev = chan->device;
if (thread->type == DMA_MEMCPY)
if (thread->type == DMA_MEMCPY) {
align = dev->copy_align;
src_cnt = dst_cnt = 1;
else if (thread->type == DMA_SG)
} else if (thread->type == DMA_SG) {
align = dev->copy_align;
src_cnt = dst_cnt = sg_buffers;
else if (thread->type == DMA_XOR) {
} else if (thread->type == DMA_XOR) {
/* force odd to ensure dst = src */
src_cnt = min_odd(params->xor_sources | 1, dev->max_xor);
dst_cnt = 1;
align = dev->xor_align;
} else if (thread->type == DMA_PQ) {
/* force odd to ensure dst = src */
src_cnt = min_odd(params->pq_sources | 1, dma_maxpq(dev, 0));
dst_cnt = 2;
align = dev->pq_align;
pq_coefs = kmalloc(params->pq_sources+1, GFP_KERNEL);
pq_coefs = kmalloc(params->pq_sources + 1, GFP_KERNEL);
if (!pq_coefs)
goto err_thread_type;
@@ -463,23 +470,47 @@ static int dmatest_func(void *data)
} else
goto err_thread_type;
thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL);
thread->srcs = kcalloc(src_cnt + 1, sizeof(u8 *), GFP_KERNEL);
if (!thread->srcs)
goto err_srcs;
thread->usrcs = kcalloc(src_cnt + 1, sizeof(u8 *), GFP_KERNEL);
if (!thread->usrcs)
goto err_usrcs;
for (i = 0; i < src_cnt; i++) {
thread->srcs[i] = kmalloc(params->buf_size, GFP_KERNEL);
if (!thread->srcs[i])
thread->usrcs[i] = kmalloc(params->buf_size + align,
GFP_KERNEL);
if (!thread->usrcs[i])
goto err_srcbuf;
/* align srcs to alignment restriction */
if (align)
thread->srcs[i] = PTR_ALIGN(thread->usrcs[i], align);
else
thread->srcs[i] = thread->usrcs[i];
}
thread->srcs[i] = NULL;
thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL);
thread->dsts = kcalloc(dst_cnt + 1, sizeof(u8 *), GFP_KERNEL);
if (!thread->dsts)
goto err_dsts;
thread->udsts = kcalloc(dst_cnt + 1, sizeof(u8 *), GFP_KERNEL);
if (!thread->udsts)
goto err_udsts;
for (i = 0; i < dst_cnt; i++) {
thread->dsts[i] = kmalloc(params->buf_size, GFP_KERNEL);
if (!thread->dsts[i])
thread->udsts[i] = kmalloc(params->buf_size + align,
GFP_KERNEL);
if (!thread->udsts[i])
goto err_dstbuf;
/* align dsts to alignment restriction */
if (align)
thread->dsts[i] = PTR_ALIGN(thread->udsts[i], align);
else
thread->dsts[i] = thread->udsts[i];
}
thread->dsts[i] = NULL;
@@ -498,20 +529,11 @@ static int dmatest_func(void *data)
dma_addr_t srcs[src_cnt];
dma_addr_t *dsts;
unsigned int src_off, dst_off, len;
u8 align = 0;
struct scatterlist tx_sg[src_cnt];
struct scatterlist rx_sg[src_cnt];
total_tests++;
/* honor alignment restrictions */
if (thread->type == DMA_MEMCPY || thread->type == DMA_SG)
align = dev->copy_align;
else if (thread->type == DMA_XOR)
align = dev->xor_align;
else if (thread->type == DMA_PQ)
align = dev->pq_align;
if (1 << align > params->buf_size) {
pr_err("%u-byte buffer too small for %d-byte alignment\n",
params->buf_size, 1 << align);
@@ -549,7 +571,7 @@ static int dmatest_func(void *data)
filltime = ktime_add(filltime, diff);
}
um = dmaengine_get_unmap_data(dev->dev, src_cnt+dst_cnt,
um = dmaengine_get_unmap_data(dev->dev, src_cnt + dst_cnt,
GFP_KERNEL);
if (!um) {
failed_tests++;
@@ -729,13 +751,17 @@ static int dmatest_func(void *data)
ret = 0;
err_dstbuf:
for (i = 0; thread->dsts[i]; i++)
kfree(thread->dsts[i]);
for (i = 0; thread->udsts[i]; i++)
kfree(thread->udsts[i]);
kfree(thread->udsts);
err_udsts:
kfree(thread->dsts);
err_dsts:
err_srcbuf:
for (i = 0; thread->srcs[i]; i++)
kfree(thread->srcs[i]);
for (i = 0; thread->usrcs[i]; i++)
kfree(thread->usrcs[i]);
kfree(thread->usrcs);
err_usrcs:
kfree(thread->srcs);
err_srcs:
kfree(pq_coefs);
+1 -1
View File
@@ -1569,7 +1569,7 @@ int dw_dma_probe(struct dw_dma_chip *chip)
(dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0;
} else {
dwc->block_size = pdata->block_size;
dwc->nollp = pdata->is_nollp;
dwc->nollp = !pdata->multi_block[i];
}
}
+17 -1
View File
@@ -102,7 +102,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct dw_dma_platform_data *pdata;
u32 tmp, arr[DW_DMA_MAX_NR_MASTERS];
u32 tmp, arr[DW_DMA_MAX_NR_MASTERS], mb[DW_DMA_MAX_NR_CHANNELS];
u32 nr_masters;
u32 nr_channels;
@@ -118,6 +118,8 @@ dw_dma_parse_dt(struct platform_device *pdev)
if (of_property_read_u32(np, "dma-channels", &nr_channels))
return NULL;
if (nr_channels > DW_DMA_MAX_NR_CHANNELS)
return NULL;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -129,6 +131,12 @@ dw_dma_parse_dt(struct platform_device *pdev)
if (of_property_read_bool(np, "is_private"))
pdata->is_private = true;
/*
* All known devices, which use DT for configuration, support
* memory-to-memory transfers. So enable it by default.
*/
pdata->is_memcpy = true;
if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
pdata->chan_allocation_order = (unsigned char)tmp;
@@ -146,6 +154,14 @@ dw_dma_parse_dt(struct platform_device *pdev)
pdata->data_width[tmp] = BIT(arr[tmp] & 0x07);
}
if (!of_property_read_u32_array(np, "multi-block", mb, nr_channels)) {
for (tmp = 0; tmp < nr_channels; tmp++)
pdata->multi_block[tmp] = mb[tmp];
} else {
for (tmp = 0; tmp < nr_channels; tmp++)
pdata->multi_block[tmp] = 1;
}
return pdata;
}
#else
+2 -1
View File
@@ -12,7 +12,8 @@
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
#define DW_DMA_MAX_NR_CHANNELS 8
#include "internal.h"
#define DW_DMA_MAX_NR_REQUESTS 16
/* flow controller */
Loaded 20 of 53 files, more files were not shown because too many files have changed in this diff. Show more