mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-08-18 02:22:47 -07:00
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:
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:
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
data-width = <4>;
|
||||
clocks = <&ahb_clk>;
|
||||
clock-names = "hclk";
|
||||
multi-block = <1 1 1 1 1 1>;
|
||||
};
|
||||
|
||||
i2c0: i2c@FF120000 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in new issue
Block a user