Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma

Pull slave-dma updates from Vinod Koul:
 - new driver for BCM2835 used in R-pi
 - new driver for MOXA ART
 - dma_get_any_slave_channel API for DT based systems
 - minor fixes and updates spread acrooss driver

[ The fsl-ssi dual fifo mode support addition clashed badly with the
  other changes to fsl-ssi that came in through the sound merge.  I did
  a very rough cut at fixing up the conflict, but Nicolin Chen (author
  of both sides) will need to verify and check things ]

* 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma: (36 commits)
  dmaengine: mmp_pdma: fix mismerge
  dma: pl08x: Export pl08x_filter_id
  acpi-dma: align documentation with kernel-doc format
  dma: fix vchan_cookie_complete() debug print
  DMA: dmatest: extend the "device" module parameter to 32 characters
  drivers/dma: fix error return code
  dma: omap: Set debug level to debugging messages
  dmaengine: fix kernel-doc style typos for few comments
  dma: tegra: add support for Tegra148/124
  dma: dw: use %pad instead of casting dma_addr_t
  dma: dw: join split up messages
  dma: dw: fix style of multiline comment
  dmaengine: k3dma: fix sparse warnings
  dma: pl330: Use dma_get_slave_channel() in the of xlate callback
  dma: pl330: Differentiate between submitted and issued descriptors
  dmaengine: sirf: Add device_slave_caps interface
  DMA: Freescale: change BWC from 256 bytes to 1024 bytes
  dmaengine: Add MOXA ART DMA engine driver
  dmaengine: Add DMA_PRIVATE to BCM2835 driver
  dma: imx-sdma: Assign a default script number for ROM firmware cases
  ...
This commit is contained in:
Linus Torvalds
2014-01-29 20:27:23 -08:00
30 changed files with 1882 additions and 199 deletions
@@ -0,0 +1,57 @@
* BCM2835 DMA controller
The BCM2835 DMA controller has 16 channels in total.
Only the lower 13 channels have an associated IRQ.
Some arbitrary channels are used by the firmware
(1,3,6,7 in the current firmware version).
The channels 0,2 and 3 have special functionality
and should not be used by the driver.
Required properties:
- compatible: Should be "brcm,bcm2835-dma".
- reg: Should contain DMA registers location and length.
- interrupts: Should contain the DMA interrupts associated
to the DMA channels in ascending order.
- #dma-cells: Must be <1>, the cell in the dmas property of the
client device represents the DREQ number.
- brcm,dma-channel-mask: Bit mask representing the channels
not used by the firmware in ascending order,
i.e. first channel corresponds to LSB.
Example:
dma: dma@7e007000 {
compatible = "brcm,bcm2835-dma";
reg = <0x7e007000 0xf00>;
interrupts = <1 16>,
<1 17>,
<1 18>,
<1 19>,
<1 20>,
<1 21>,
<1 22>,
<1 23>,
<1 24>,
<1 25>,
<1 26>,
<1 27>,
<1 28>;
#dma-cells = <1>;
brcm,dma-channel-mask = <0x7f35>;
};
DMA clients connected to the BCM2835 DMA controller must use the format
described in the dma.txt file, using a two-cell specifier for each channel.
Example:
bcm2835_i2s: i2s@7e203000 {
compatible = "brcm,bcm2835-i2s";
reg = < 0x7e203000 0x20>,
< 0x7e101098 0x02>;
dmas = <&dma 2>,
<&dma 3>;
dma-names = "tx", "rx";
};
@@ -42,6 +42,7 @@ The full ID of peripheral types can be found below.
19 IPU Memory
20 ASRC
21 ESAI
22 SSI Dual FIFO (needs firmware ver >= 2)
The third cell specifies the transfer priority as below.
@@ -0,0 +1,45 @@
MOXA ART DMA Controller
See dma.txt first
Required properties:
- compatible : Must be "moxa,moxart-dma"
- reg : Should contain registers location and length
- interrupts : Should contain an interrupt-specifier for the sole
interrupt generated by the device
- #dma-cells : Should be 1, a single cell holding a line request number
Example:
dma: dma@90500000 {
compatible = "moxa,moxart-dma";
reg = <0x90500080 0x40>;
interrupts = <24 0>;
#dma-cells = <1>;
};
Clients:
DMA clients connected to the MOXA ART DMA controller must use the format
described in the dma.txt file, using a two-cell specifier for each channel:
a phandle plus one integer cells.
The two cells in order are:
1. A phandle pointing to the DMA controller.
2. Peripheral identifier for the hardware handshaking interface.
Example:
Use specific request line passing from dma
For example, MMC request line is 5
sdhci: sdhci@98e00000 {
compatible = "moxa,moxart-sdhci";
reg = <0x98e00000 0x5C>;
interrupts = <5 0>;
clocks = <&clk_apb>;
dmas = <&dma 5>,
<&dma 5>;
dma-names = "tx", "rx";
};
+14
View File
@@ -306,6 +306,12 @@ config DMA_OMAP
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
config DMA_BCM2835
tristate "BCM2835 DMA engine support"
depends on (ARCH_BCM2835 || MACH_BCM2708)
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
config TI_CPPI41
tristate "AM33xx CPPI41 DMA support"
depends on ARCH_OMAP
@@ -336,6 +342,14 @@ config K3_DMA
Support the DMA engine for Hisilicon K3 platform
devices.
config MOXART_DMA
tristate "MOXART DMA support"
depends on ARCH_MOXART
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
help
Enable support for the MOXA ART SoC DMA controller.
config DMA_ENGINE
bool
+2
View File
@@ -38,7 +38,9 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
obj-$(CONFIG_DMA_OMAP) += omap-dma.o
obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
obj-$(CONFIG_TI_CPPI41) += cppi41.o
obj-$(CONFIG_K3_DMA) += k3dma.o
obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
+24 -12
View File
@@ -30,11 +30,12 @@ static DEFINE_MUTEX(acpi_dma_lock);
* @adev: ACPI device to match with
* @adma: struct acpi_dma of the given DMA controller
*
* Returns 1 on success, 0 when no information is available, or appropriate
* errno value on error.
*
* In order to match a device from DSDT table to the corresponding CSRT device
* we use MMIO address and IRQ.
*
* Return:
* 1 on success, 0 when no information is available, or appropriate errno value
* on error.
*/
static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp,
struct acpi_device *adev, struct acpi_dma *adma)
@@ -101,7 +102,6 @@ static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp,
*
* We are using this table to get the request line range of the specific DMA
* controller to be used later.
*
*/
static void acpi_dma_parse_csrt(struct acpi_device *adev, struct acpi_dma *adma)
{
@@ -141,10 +141,11 @@ static void acpi_dma_parse_csrt(struct acpi_device *adev, struct acpi_dma *adma)
* @data pointer to controller specific data to be used by
* translation function
*
* Returns 0 on success or appropriate errno value on error.
*
* Allocated memory should be freed with appropriate acpi_dma_controller_free()
* call.
*
* Return:
* 0 on success or appropriate errno value on error.
*/
int acpi_dma_controller_register(struct device *dev,
struct dma_chan *(*acpi_dma_xlate)
@@ -188,6 +189,9 @@ EXPORT_SYMBOL_GPL(acpi_dma_controller_register);
* @dev: struct device of DMA controller
*
* Memory allocated by acpi_dma_controller_register() is freed here.
*
* Return:
* 0 on success or appropriate errno value on error.
*/
int acpi_dma_controller_free(struct device *dev)
{
@@ -225,6 +229,9 @@ static void devm_acpi_dma_release(struct device *dev, void *res)
* Managed acpi_dma_controller_register(). DMA controller registered by this
* function are automatically freed on driver detach. See
* acpi_dma_controller_register() for more information.
*
* Return:
* 0 on success or appropriate errno value on error.
*/
int devm_acpi_dma_controller_register(struct device *dev,
struct dma_chan *(*acpi_dma_xlate)
@@ -267,8 +274,6 @@ EXPORT_SYMBOL_GPL(devm_acpi_dma_controller_free);
* @adma: struct acpi_dma of DMA controller
* @dma_spec: dma specifier to update
*
* Returns 0, if no information is avaiable, -1 on mismatch, and 1 otherwise.
*
* Accordingly to ACPI 5.0 Specification Table 6-170 "Fixed DMA Resource
* Descriptor":
* DMA Request Line bits is a platform-relative number uniquely
@@ -276,6 +281,9 @@ EXPORT_SYMBOL_GPL(devm_acpi_dma_controller_free);
* mapping is done in a controller-specific OS driver.
* That's why we can safely adjust slave_id when the appropriate controller is
* found.
*
* Return:
* 0, if no information is avaiable, -1 on mismatch, and 1 otherwise.
*/
static int acpi_dma_update_dma_spec(struct acpi_dma *adma,
struct acpi_dma_spec *dma_spec)
@@ -334,7 +342,8 @@ static int acpi_dma_parse_fixed_dma(struct acpi_resource *res, void *data)
* @dev: struct device to get DMA request from
* @index: index of FixedDMA descriptor for @dev
*
* Returns pointer to appropriate dma channel on success or NULL on error.
* Return:
* Pointer to appropriate dma channel on success or NULL on error.
*/
struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev,
size_t index)
@@ -403,7 +412,8 @@ EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_index);
* translate the names "tx" and "rx" here based on the most common case where
* the first FixedDMA descriptor is TX and second is RX.
*
* Returns pointer to appropriate dma channel on success or NULL on error.
* Return:
* Pointer to appropriate dma channel on success or NULL on error.
*/
struct dma_chan *acpi_dma_request_slave_chan_by_name(struct device *dev,
const char *name)
@@ -427,8 +437,10 @@ EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_name);
* @adma: pointer to ACPI DMA controller data
*
* A simple translation function for ACPI based devices. Passes &struct
* dma_spec to the DMA controller driver provided filter function. Returns
* pointer to the channel if found or %NULL otherwise.
* dma_spec to the DMA controller driver provided filter function.
*
* Return:
* Pointer to the channel if found or %NULL otherwise.
*/
struct dma_chan *acpi_dma_simple_xlate(struct acpi_dma_spec *dma_spec,
struct acpi_dma *adma)
+3 -1
View File
@@ -83,6 +83,7 @@
#include <linux/dmaengine.h>
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
@@ -1771,6 +1772,7 @@ bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
return false;
}
EXPORT_SYMBOL_GPL(pl08x_filter_id);
/*
* Just check that the device is there and active
@@ -2167,7 +2169,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
/* Register slave channels */
ret = pl08x_dma_init_virtual_channels(pl08x, &pl08x->slave,
pl08x->pd->num_slave_channels, true);
if (ret <= 0) {
if (ret < 0) {
dev_warn(&pl08x->adev->dev,
"%s failed to enumerate slave channels - %d\n",
__func__, ret);
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -972,8 +972,10 @@ static int cppi41_dma_probe(struct platform_device *pdev)
goto err_chans;
irq = irq_of_parse_and_map(dev->of_node, 0);
if (!irq)
if (!irq) {
ret = -EINVAL;
goto err_irq;
}
cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER);
+2 -2
View File
@@ -31,7 +31,7 @@ module_param_string(channel, test_channel, sizeof(test_channel),
S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)");
static char test_device[20];
static char test_device[32];
module_param_string(device, test_device, sizeof(test_device),
S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)");
@@ -89,7 +89,7 @@ MODULE_PARM_DESC(verbose, "Enable \"success\" result messages (default: off)");
struct dmatest_params {
unsigned int buf_size;
char channel[20];
char device[20];
char device[32];
unsigned int threads_per_chan;
unsigned int max_channels;
unsigned int iterations;
+18 -17
View File
@@ -218,8 +218,10 @@ static inline void dwc_do_single_block(struct dw_dma_chan *dwc,
struct dw_dma *dw = to_dw_dma(dwc->chan.device);
u32 ctllo;
/* Software emulation of LLP mode relies on interrupts to continue
* multi block transfer. */
/*
* Software emulation of LLP mode relies on interrupts to continue
* multi block transfer.
*/
ctllo = desc->lli.ctllo | DWC_CTLL_INT_EN;
channel_writel(dwc, SAR, desc->lli.sar);
@@ -253,8 +255,7 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
&dwc->flags);
if (was_soft_llp) {
dev_err(chan2dev(&dwc->chan),
"BUG: Attempted to start new LLP transfer "
"inside ongoing one\n");
"BUG: Attempted to start new LLP transfer inside ongoing one\n");
return;
}
@@ -420,8 +421,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
return;
}
dev_vdbg(chan2dev(&dwc->chan), "%s: llp=0x%llx\n", __func__,
(unsigned long long)llp);
dev_vdbg(chan2dev(&dwc->chan), "%s: llp=%pad\n", __func__, &llp);
list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
/* Initial residue value */
@@ -567,9 +567,9 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
unlikely(status_xfer & dwc->mask)) {
int i;
dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
"interrupt, stopping DMA transfer\n",
status_xfer ? "xfer" : "error");
dev_err(chan2dev(&dwc->chan),
"cyclic DMA unexpected %s interrupt, stopping DMA transfer\n",
status_xfer ? "xfer" : "error");
spin_lock_irqsave(&dwc->lock, flags);
@@ -711,9 +711,8 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
u32 ctllo;
dev_vdbg(chan2dev(chan),
"%s: d0x%llx s0x%llx l0x%zx f0x%lx\n", __func__,
(unsigned long long)dest, (unsigned long long)src,
len, flags);
"%s: d%pad s%pad l0x%zx f0x%lx\n", __func__,
&dest, &src, len, flags);
if (unlikely(!len)) {
dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__);
@@ -1401,9 +1400,9 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
/* Let's make a cyclic list */
last->lli.llp = cdesc->desc[0]->txd.phys;
dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu "
"period %zu periods %d\n", (unsigned long long)buf_addr,
buf_len, period_len, periods);
dev_dbg(chan2dev(&dwc->chan),
"cyclic prepared buf %pad len %zu period %zu periods %d\n",
&buf_addr, buf_len, period_len, periods);
cdesc->periods = periods;
dwc->cdesc = cdesc;
@@ -1603,9 +1602,11 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
dev_dbg(chip->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
dwc_params);
/* Decode maximum block size for given channel. The
/*
* Decode maximum block size for given channel. The
* stored 4 bit value represents blocks from 0x00 for 3
* up to 0x0a for 4095. */
* up to 0x0a for 4095.
*/
dwc->block_size =
(4 << ((max_blk_size >> 4 * i) & 0xf)) - 1;
dwc->nollp =
+3 -3
View File
@@ -699,8 +699,8 @@ static int edma_alloc_chan_resources(struct dma_chan *chan)
echan->alloced = true;
echan->slot[0] = echan->ch_num;
dev_info(dev, "allocated channel for %u:%u\n",
EDMA_CTLR(echan->ch_num), EDMA_CHAN_SLOT(echan->ch_num));
dev_dbg(dev, "allocated channel for %u:%u\n",
EDMA_CTLR(echan->ch_num), EDMA_CHAN_SLOT(echan->ch_num));
return 0;
@@ -736,7 +736,7 @@ static void edma_free_chan_resources(struct dma_chan *chan)
echan->alloced = false;
}
dev_info(dev, "freeing channel for %u\n", echan->ch_num);
dev_dbg(dev, "freeing channel for %u\n", echan->ch_num);
}
/* Send pending descriptor to hardware */
+1 -1
View File
@@ -41,7 +41,7 @@
* channel is allowed to transfer before the DMA engine pauses
* the current channel and switches to the next channel
*/
#define FSL_DMA_MR_BWC 0x08000000
#define FSL_DMA_MR_BWC 0x0A000000
/* Special MR definition for MPC8349 */
#define FSL_DMA_MR_EOTIE 0x00000080
+22 -1
View File
@@ -323,6 +323,7 @@ struct sdma_engine {
struct clk *clk_ipg;
struct clk *clk_ahb;
spinlock_t channel_0_lock;
u32 script_number;
struct sdma_script_start_addrs *script_addrs;
const struct sdma_driver_data *drvdata;
};
@@ -724,6 +725,10 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
per_2_emi = sdma->script_addrs->app_2_mcu_addr;
emi_2_per = sdma->script_addrs->mcu_2_app_addr;
break;
case IMX_DMATYPE_SSI_DUAL:
per_2_emi = sdma->script_addrs->ssish_2_mcu_addr;
emi_2_per = sdma->script_addrs->mcu_2_ssish_addr;
break;
case IMX_DMATYPE_SSI_SP:
case IMX_DMATYPE_MMC:
case IMX_DMATYPE_SDHC:
@@ -1238,6 +1243,7 @@ static void sdma_issue_pending(struct dma_chan *chan)
}
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 34
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2 38
static void sdma_add_scripts(struct sdma_engine *sdma,
const struct sdma_script_start_addrs *addr)
@@ -1246,7 +1252,11 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
s32 *saddr_arr = (u32 *)sdma->script_addrs;
int i;
for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
/* use the default firmware in ROM if missing external firmware */
if (!sdma->script_number)
sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
for (i = 0; i < sdma->script_number; i++)
if (addr_arr[i] > 0)
saddr_arr[i] = addr_arr[i];
}
@@ -1272,6 +1282,17 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
goto err_firmware;
if (header->ram_code_start + header->ram_code_size > fw->size)
goto err_firmware;
switch (header->version_major) {
case 1:
sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
break;
case 2:
sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
break;
default:
dev_err(sdma->dev, "unknown firmware version\n");
goto err_firmware;
}
addr = (void *)header + header->script_addrs_start;
ram_code = (void *)header + header->ram_code_start;
+2 -2
View File
@@ -477,7 +477,7 @@ static struct dma_async_tx_descriptor *k3_dma_prep_slave_sg(
dma_addr_t addr, src = 0, dst = 0;
int num = sglen, i;
if (sgl == 0)
if (sgl == NULL)
return NULL;
for_each_sg(sgl, sg, sglen, i) {
@@ -817,7 +817,7 @@ static int k3_dma_resume(struct device *dev)
return 0;
}
SIMPLE_DEV_PM_OPS(k3_dma_pmops, k3_dma_suspend, k3_dma_resume);
static SIMPLE_DEV_PM_OPS(k3_dma_pmops, k3_dma_suspend, k3_dma_resume);
static struct platform_driver k3_pdma_driver = {
.driver = {
+98 -93
View File
@@ -5,6 +5,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -32,38 +33,37 @@
#define DTADR 0x0208
#define DCMD 0x020c
#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */
#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */
#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */
#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */
#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */
#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */
#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */
#define DCSR_RUN BIT(31) /* Run Bit (read / write) */
#define DCSR_NODESC BIT(30) /* No-Descriptor Fetch (read / write) */
#define DCSR_STOPIRQEN BIT(29) /* Stop Interrupt Enable (read / write) */
#define DCSR_REQPEND BIT(8) /* Request Pending (read-only) */
#define DCSR_STOPSTATE BIT(3) /* Stop State (read-only) */
#define DCSR_ENDINTR BIT(2) /* End Interrupt (read / write) */
#define DCSR_STARTINTR BIT(1) /* Start Interrupt (read / write) */
#define DCSR_BUSERR BIT(0) /* Bus Error Interrupt (read / write) */
#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */
#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */
#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */
#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */
#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */
#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */
#define DCSR_EORINTR (1 << 9) /* The end of Receive */
#define DCSR_EORIRQEN BIT(28) /* End of Receive Interrupt Enable (R/W) */
#define DCSR_EORJMPEN BIT(27) /* Jump to next descriptor on EOR */
#define DCSR_EORSTOPEN BIT(26) /* STOP on an EOR */
#define DCSR_SETCMPST BIT(25) /* Set Descriptor Compare Status */
#define DCSR_CLRCMPST BIT(24) /* Clear Descriptor Compare Status */
#define DCSR_CMPST BIT(10) /* The Descriptor Compare Status */
#define DCSR_EORINTR BIT(9) /* The end of Receive */
#define DRCMR(n) ((((n) < 64) ? 0x0100 : 0x1100) + \
(((n) & 0x3f) << 2))
#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */
#define DRCMR(n) ((((n) < 64) ? 0x0100 : 0x1100) + (((n) & 0x3f) << 2))
#define DRCMR_MAPVLD BIT(7) /* Map Valid (read / write) */
#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */
#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */
#define DDADR_STOP (1 << 0) /* Stop (read / write) */
#define DDADR_STOP BIT(0) /* Stop (read / write) */
#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */
#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */
#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */
#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */
#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */
#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */
#define DCMD_INCSRCADDR BIT(31) /* Source Address Increment Setting. */
#define DCMD_INCTRGADDR BIT(30) /* Target Address Increment Setting. */
#define DCMD_FLOWSRC BIT(29) /* Flow Control by the source. */
#define DCMD_FLOWTRG BIT(28) /* Flow Control by the target. */
#define DCMD_STARTIRQEN BIT(22) /* Start Interrupt Enable */
#define DCMD_ENDIRQEN BIT(21) /* End Interrupt Enable */
#define DCMD_ENDIAN BIT(18) /* Device Endian-ness. */
#define DCMD_BURST8 (1 << 16) /* 8 byte burst */
#define DCMD_BURST16 (2 << 16) /* 16 byte burst */
#define DCMD_BURST32 (3 << 16) /* 32 byte burst */
@@ -132,10 +132,14 @@ struct mmp_pdma_device {
spinlock_t phy_lock; /* protect alloc/free phy channels */
};
#define tx_to_mmp_pdma_desc(tx) container_of(tx, struct mmp_pdma_desc_sw, async_tx)
#define to_mmp_pdma_desc(lh) container_of(lh, struct mmp_pdma_desc_sw, node)
#define to_mmp_pdma_chan(dchan) container_of(dchan, struct mmp_pdma_chan, chan)
#define to_mmp_pdma_dev(dmadev) container_of(dmadev, struct mmp_pdma_device, device)
#define tx_to_mmp_pdma_desc(tx) \
container_of(tx, struct mmp_pdma_desc_sw, async_tx)
#define to_mmp_pdma_desc(lh) \
container_of(lh, struct mmp_pdma_desc_sw, node)
#define to_mmp_pdma_chan(dchan) \
container_of(dchan, struct mmp_pdma_chan, chan)
#define to_mmp_pdma_dev(dmadev) \
container_of(dmadev, struct mmp_pdma_device, device)
static void set_desc(struct mmp_pdma_phy *phy, dma_addr_t addr)
{
@@ -162,19 +166,18 @@ static void enable_chan(struct mmp_pdma_phy *phy)
writel(dalgn, phy->base + DALGN);
reg = (phy->idx << 2) + DCSR;
writel(readl(phy->base + reg) | DCSR_RUN,
phy->base + reg);
writel(readl(phy->base + reg) | DCSR_RUN, phy->base + reg);
}
static void disable_chan(struct mmp_pdma_phy *phy)
{
u32 reg;
if (phy) {
reg = (phy->idx << 2) + DCSR;
writel(readl(phy->base + reg) & ~DCSR_RUN,
phy->base + reg);
}
if (!phy)
return;
reg = (phy->idx << 2) + DCSR;
writel(readl(phy->base + reg) & ~DCSR_RUN, phy->base + reg);
}
static int clear_chan_irq(struct mmp_pdma_phy *phy)
@@ -183,26 +186,27 @@ static int clear_chan_irq(struct mmp_pdma_phy *phy)
u32 dint = readl(phy->base + DINT);
u32 reg = (phy->idx << 2) + DCSR;
if (dint & BIT(phy->idx)) {
/* clear irq */
dcsr = readl(phy->base + reg);
writel(dcsr, phy->base + reg);
if ((dcsr & DCSR_BUSERR) && (phy->vchan))
dev_warn(phy->vchan->dev, "DCSR_BUSERR\n");
return 0;
}
return -EAGAIN;
if (!(dint & BIT(phy->idx)))
return -EAGAIN;
/* clear irq */
dcsr = readl(phy->base + reg);
writel(dcsr, phy->base + reg);
if ((dcsr & DCSR_BUSERR) && (phy->vchan))
dev_warn(phy->vchan->dev, "DCSR_BUSERR\n");
return 0;
}
static irqreturn_t mmp_pdma_chan_handler(int irq, void *dev_id)
{
struct mmp_pdma_phy *phy = dev_id;
if (clear_chan_irq(phy) == 0) {
tasklet_schedule(&phy->vchan->tasklet);
return IRQ_HANDLED;
} else
if (clear_chan_irq(phy) != 0)
return IRQ_NONE;
tasklet_schedule(&phy->vchan->tasklet);
return IRQ_HANDLED;
}
static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
@@ -224,8 +228,8 @@ static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
if (irq_num)
return IRQ_HANDLED;
else
return IRQ_NONE;
return IRQ_NONE;
}
/* lookup free phy channel as descending priority */
@@ -245,9 +249,9 @@ static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)
*/
spin_lock_irqsave(&pdev->phy_lock, flags);
for (prio = 0; prio <= (((pdev->dma_channels - 1) & 0xf) >> 2); prio++) {
for (prio = 0; prio <= ((pdev->dma_channels - 1) & 0xf) >> 2; prio++) {
for (i = 0; i < pdev->dma_channels; i++) {
if (prio != ((i & 0xf) >> 2))
if (prio != (i & 0xf) >> 2)
continue;
phy = &pdev->phy[i];
if (!phy->vchan) {
@@ -389,14 +393,16 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
if (chan->desc_pool)
return 1;
chan->desc_pool =
dma_pool_create(dev_name(&dchan->dev->device), chan->dev,
sizeof(struct mmp_pdma_desc_sw),
__alignof__(struct mmp_pdma_desc_sw), 0);
chan->desc_pool = dma_pool_create(dev_name(&dchan->dev->device),
chan->dev,
sizeof(struct mmp_pdma_desc_sw),
__alignof__(struct mmp_pdma_desc_sw),
0);
if (!chan->desc_pool) {
dev_err(chan->dev, "unable to allocate descriptor pool\n");
return -ENOMEM;
}
mmp_pdma_free_phy(chan);
chan->idle = true;
chan->dev_addr = 0;
@@ -404,7 +410,7 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
}
static void mmp_pdma_free_desc_list(struct mmp_pdma_chan *chan,
struct list_head *list)
struct list_head *list)
{
struct mmp_pdma_desc_sw *desc, *_desc;
@@ -434,8 +440,8 @@ static void mmp_pdma_free_chan_resources(struct dma_chan *dchan)
static struct dma_async_tx_descriptor *
mmp_pdma_prep_memcpy(struct dma_chan *dchan,
dma_addr_t dma_dst, dma_addr_t dma_src,
size_t len, unsigned long flags)
dma_addr_t dma_dst, dma_addr_t dma_src,
size_t len, unsigned long flags)
{
struct mmp_pdma_chan *chan;
struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new;
@@ -515,8 +521,8 @@ fail:
static struct dma_async_tx_descriptor *
mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
unsigned int sg_len, enum dma_transfer_direction dir,
unsigned long flags, void *context)
unsigned int sg_len, enum dma_transfer_direction dir,
unsigned long flags, void *context)
{
struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new = NULL;
@@ -591,10 +597,11 @@ fail:
return NULL;
}
static struct dma_async_tx_descriptor *mmp_pdma_prep_dma_cyclic(
struct dma_chan *dchan, dma_addr_t buf_addr, size_t len,
size_t period_len, enum dma_transfer_direction direction,
unsigned long flags, void *context)
static struct dma_async_tx_descriptor *
mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan,
dma_addr_t buf_addr, size_t len, size_t period_len,
enum dma_transfer_direction direction,
unsigned long flags, void *context)
{
struct mmp_pdma_chan *chan;
struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new;
@@ -636,8 +643,8 @@ static struct dma_async_tx_descriptor *mmp_pdma_prep_dma_cyclic(
goto fail;
}
new->desc.dcmd = chan->dcmd | DCMD_ENDIRQEN |
(DCMD_LENGTH & period_len);
new->desc.dcmd = (chan->dcmd | DCMD_ENDIRQEN |
(DCMD_LENGTH & period_len));
new->desc.dsadr = dma_src;
new->desc.dtadr = dma_dst;
@@ -677,12 +684,11 @@ fail:
}
static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
unsigned long arg)
unsigned long arg)
{
struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
struct dma_slave_config *cfg = (void *)arg;
unsigned long flags;
int ret = 0;
u32 maxburst = 0, addr = 0;
enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
@@ -739,11 +745,12 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
return -ENOSYS;
}
return ret;
return 0;
}
static enum dma_status mmp_pdma_tx_status(struct dma_chan *dchan,
dma_cookie_t cookie, struct dma_tx_state *txstate)
dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
return dma_cookie_status(dchan, cookie, txstate);
}
@@ -845,15 +852,14 @@ static int mmp_pdma_remove(struct platform_device *op)
return 0;
}
static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
int idx, int irq)
static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev, int idx, int irq)
{
struct mmp_pdma_phy *phy = &pdev->phy[idx];
struct mmp_pdma_chan *chan;
int ret;
chan = devm_kzalloc(pdev->dev,
sizeof(struct mmp_pdma_chan), GFP_KERNEL);
chan = devm_kzalloc(pdev->dev, sizeof(struct mmp_pdma_chan),
GFP_KERNEL);
if (chan == NULL)
return -ENOMEM;
@@ -861,8 +867,8 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
phy->base = pdev->base;
if (irq) {
ret = devm_request_irq(pdev->dev, irq,
mmp_pdma_chan_handler, 0, "pdma", phy);
ret = devm_request_irq(pdev->dev, irq, mmp_pdma_chan_handler, 0,
"pdma", phy);
if (ret) {
dev_err(pdev->dev, "channel request irq fail!\n");
return ret;
@@ -877,8 +883,7 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
INIT_LIST_HEAD(&chan->chain_running);
/* register virt channel to dma engine */
list_add_tail(&chan->chan.device_node,
&pdev->device.channels);
list_add_tail(&chan->chan.device_node, &pdev->device.channels);
return 0;
}
@@ -894,14 +899,12 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec,
{
struct mmp_pdma_device *d = ofdma->of_dma_data;
struct dma_chan *chan;
struct mmp_pdma_chan *c;
chan = dma_get_any_slave_channel(&d->device);
if (!chan)
return NULL;
c = to_mmp_pdma_chan(chan);
c->drcmr = dma_spec->args[0];
to_mmp_pdma_chan(chan)->drcmr = dma_spec->args[0];
return chan;
}
@@ -918,6 +921,7 @@ static int mmp_pdma_probe(struct platform_device *op)
pdev = devm_kzalloc(&op->dev, sizeof(*pdev), GFP_KERNEL);
if (!pdev)
return -ENOMEM;
pdev->dev = &op->dev;
spin_lock_init(&pdev->phy_lock);
@@ -929,8 +933,8 @@ static int mmp_pdma_probe(struct platform_device *op)
of_id = of_match_device(mmp_pdma_dt_ids, pdev->dev);
if (of_id)
of_property_read_u32(pdev->dev->of_node,
"#dma-channels", &dma_channels);
of_property_read_u32(pdev->dev->of_node, "#dma-channels",
&dma_channels);
else if (pdata && pdata->dma_channels)
dma_channels = pdata->dma_channels;
else
@@ -942,8 +946,9 @@ static int mmp_pdma_probe(struct platform_device *op)
irq_num++;
}
pdev->phy = devm_kzalloc(pdev->dev,
dma_channels * sizeof(struct mmp_pdma_chan), GFP_KERNEL);
pdev->phy = devm_kcalloc(pdev->dev,
dma_channels, sizeof(struct mmp_pdma_chan),
GFP_KERNEL);
if (pdev->phy == NULL)
return -ENOMEM;
@@ -952,8 +957,8 @@ static int mmp_pdma_probe(struct platform_device *op)
if (irq_num != dma_channels) {
/* all chan share one irq, demux inside */
irq = platform_get_irq(op, 0);
ret = devm_request_irq(pdev->dev, irq,
mmp_pdma_int_handler, 0, "pdma", pdev);
ret = devm_request_irq(pdev->dev, irq, mmp_pdma_int_handler, 0,
"pdma", pdev);
if (ret)
return ret;
}
@@ -1029,7 +1034,7 @@ bool mmp_pdma_filter_fn(struct dma_chan *chan, void *param)
if (chan->device->dev->driver != &mmp_pdma_driver.driver)
return false;
c->drcmr = *(unsigned int *) param;
c->drcmr = *(unsigned int *)param;
return true;
}
@@ -1037,6 +1042,6 @@ EXPORT_SYMBOL_GPL(mmp_pdma_filter_fn);
module_platform_driver(mmp_pdma_driver);
MODULE_DESCRIPTION("MARVELL MMP Periphera DMA Driver");
MODULE_DESCRIPTION("MARVELL MMP Peripheral DMA Driver");
MODULE_AUTHOR("Marvell International Ltd.");
MODULE_LICENSE("GPL v2");
+21 -7
View File
@@ -121,11 +121,13 @@ struct mmp_tdma_chan {
int idx;
enum mmp_tdma_type type;
int irq;
unsigned long reg_base;
void __iomem *reg_base;
size_t buf_len;
size_t period_len;
size_t pos;
struct gen_pool *pool;
};
#define TDMA_CHANNEL_NUM 2
@@ -182,7 +184,7 @@ static void mmp_tdma_pause_chan(struct mmp_tdma_chan *tdmac)
static int mmp_tdma_config_chan(struct mmp_tdma_chan *tdmac)
{
unsigned int tdcr;
unsigned int tdcr = 0;
mmp_tdma_disable_chan(tdmac);
@@ -324,7 +326,7 @@ static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac)
struct gen_pool *gpool;
int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc);
gpool = sram_get_gpool("asram");
gpool = tdmac->pool;
if (tdmac->desc_arr)
gen_pool_free(gpool, (unsigned long)tdmac->desc_arr,
size);
@@ -374,7 +376,7 @@ struct mmp_tdma_desc *mmp_tdma_alloc_descriptor(struct mmp_tdma_chan *tdmac)
struct gen_pool *gpool;
int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc);
gpool = sram_get_gpool("asram");
gpool = tdmac->pool;
if (!gpool)
return NULL;
@@ -505,7 +507,8 @@ static int mmp_tdma_remove(struct platform_device *pdev)
}
static int mmp_tdma_chan_init(struct mmp_tdma_device *tdev,
int idx, int irq, int type)
int idx, int irq,
int type, struct gen_pool *pool)
{
struct mmp_tdma_chan *tdmac;
@@ -526,7 +529,8 @@ static int mmp_tdma_chan_init(struct mmp_tdma_device *tdev,
tdmac->chan.device = &tdev->device;
tdmac->idx = idx;
tdmac->type = type;
tdmac->reg_base = (unsigned long)tdev->base + idx * 4;
tdmac->reg_base = tdev->base + idx * 4;
tdmac->pool = pool;
tdmac->status = DMA_COMPLETE;
tdev->tdmac[tdmac->idx] = tdmac;
tasklet_init(&tdmac->tasklet, dma_do_tasklet, (unsigned long)tdmac);
@@ -553,6 +557,7 @@ static int mmp_tdma_probe(struct platform_device *pdev)
int i, ret;
int irq = 0, irq_num = 0;
int chan_num = TDMA_CHANNEL_NUM;
struct gen_pool *pool;
of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev);
if (of_id)
@@ -579,6 +584,15 @@ static int mmp_tdma_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&tdev->device.channels);
if (pdev->dev.of_node)
pool = of_get_named_gen_pool(pdev->dev.of_node, "asram", 0);
else
pool = sram_get_gpool("asram");
if (!pool) {
dev_err(&pdev->dev, "asram pool not available\n");
return -ENOMEM;
}
if (irq_num != chan_num) {
irq = platform_get_irq(pdev, 0);
ret = devm_request_irq(&pdev->dev, irq,
@@ -590,7 +604,7 @@ static int mmp_tdma_probe(struct platform_device *pdev)
/* initialize channel parameters */
for (i = 0; i < chan_num; i++) {
irq = (irq_num != chan_num) ? 0 : platform_get_irq(pdev, i);
ret = mmp_tdma_chan_init(tdev, i, irq, type);
ret = mmp_tdma_chan_init(tdev, i, irq, type, pool);
if (ret)
return ret;
}
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -190,7 +190,7 @@ static int omap_dma_alloc_chan_resources(struct dma_chan *chan)
{
struct omap_chan *c = to_omap_dma_chan(chan);
dev_info(c->vc.chan.device->dev, "allocating channel for %u\n", c->dma_sig);
dev_dbg(c->vc.chan.device->dev, "allocating channel for %u\n", c->dma_sig);
return omap_request_dma(c->dma_sig, "DMA engine",
omap_dma_callback, c, &c->dma_ch);
@@ -203,7 +203,7 @@ static void omap_dma_free_chan_resources(struct dma_chan *chan)
vchan_free_chan_resources(&c->vc);
omap_free_dma(c->dma_ch);
dev_info(c->vc.chan.device->dev, "freeing channel for %u\n", c->dma_sig);
dev_dbg(c->vc.chan.device->dev, "freeing channel for %u\n", c->dma_sig);
}
static size_t omap_dma_sg_size(struct omap_sg *sg)
+34 -31
View File
@@ -543,7 +543,9 @@ struct dma_pl330_chan {
/* DMA-Engine Channel */
struct dma_chan chan;
/* List of to be xfered descriptors */
/* List of submitted descriptors */
struct list_head submitted_list;
/* List of issued descriptors */
struct list_head work_list;
/* List of completed descriptors */
struct list_head completed_list;
@@ -578,12 +580,16 @@ struct dma_pl330_dmac {
/* DMA-Engine Device */
struct dma_device ddma;
/* Holds info about sg limitations */
struct device_dma_parameters dma_parms;
/* Pool of descriptors available for the DMAC's channels */
struct list_head desc_pool;
/* To protect desc_pool manipulation */
spinlock_t pool_lock;
/* Peripheral channels connected to this DMAC */
unsigned int num_peripherals;
struct dma_pl330_chan *peripherals; /* keep at end */
};
@@ -606,11 +612,6 @@ struct dma_pl330_desc {
struct dma_pl330_chan *pchan;
};
struct dma_pl330_filter_args {
struct dma_pl330_dmac *pdmac;
unsigned int chan_id;
};
static inline void _callback(struct pl330_req *r, enum pl330_op_err err)
{
if (r && r->xfer_cb)
@@ -2298,16 +2299,6 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
tasklet_schedule(&pch->task);
}
static bool pl330_dt_filter(struct dma_chan *chan, void *param)
{
struct dma_pl330_filter_args *fargs = param;
if (chan->device != &fargs->pdmac->ddma)
return false;
return (chan->chan_id == fargs->chan_id);
}
bool pl330_filter(struct dma_chan *chan, void *param)
{
u8 *peri_id;
@@ -2325,23 +2316,16 @@ static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec,
{
int count = dma_spec->args_count;
struct dma_pl330_dmac *pdmac = ofdma->of_dma_data;
struct dma_pl330_filter_args fargs;
dma_cap_mask_t cap;
if (!pdmac)
return NULL;
unsigned int chan_id;
if (count != 1)
return NULL;
fargs.pdmac = pdmac;
fargs.chan_id = dma_spec->args[0];
chan_id = dma_spec->args[0];
if (chan_id >= pdmac->num_peripherals)
return NULL;
dma_cap_zero(cap);
dma_cap_set(DMA_SLAVE, cap);
dma_cap_set(DMA_CYCLIC, cap);
return dma_request_channel(cap, pl330_dt_filter, &fargs);
return dma_get_slave_channel(&pdmac->peripherals[chan_id].chan);
}
static int pl330_alloc_chan_resources(struct dma_chan *chan)
@@ -2385,6 +2369,11 @@ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned
pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
/* Mark all desc done */
list_for_each_entry(desc, &pch->submitted_list, node) {
desc->status = FREE;
dma_cookie_complete(&desc->txd);
}
list_for_each_entry(desc, &pch->work_list , node) {
desc->status = FREE;
dma_cookie_complete(&desc->txd);
@@ -2395,6 +2384,7 @@ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned
dma_cookie_complete(&desc->txd);
}
list_splice_tail_init(&pch->submitted_list, &pdmac->desc_pool);
list_splice_tail_init(&pch->work_list, &pdmac->desc_pool);
list_splice_tail_init(&pch->completed_list, &pdmac->desc_pool);
spin_unlock_irqrestore(&pch->lock, flags);
@@ -2453,7 +2443,14 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
static void pl330_issue_pending(struct dma_chan *chan)
{
pl330_tasklet((unsigned long) to_pchan(chan));
struct dma_pl330_chan *pch = to_pchan(chan);
unsigned long flags;
spin_lock_irqsave(&pch->lock, flags);
list_splice_tail_init(&pch->submitted_list, &pch->work_list);
spin_unlock_irqrestore(&pch->lock, flags);
pl330_tasklet((unsigned long)pch);
}
/*
@@ -2480,11 +2477,11 @@ static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx)
dma_cookie_assign(&desc->txd);
list_move_tail(&desc->node, &pch->work_list);
list_move_tail(&desc->node, &pch->submitted_list);
}
cookie = dma_cookie_assign(&last->txd);
list_add_tail(&last->node, &pch->work_list);
list_add_tail(&last->node, &pch->submitted_list);
spin_unlock_irqrestore(&pch->lock, flags);
return cookie;
@@ -2960,6 +2957,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
else
num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan);
pdmac->num_peripherals = num_chan;
pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
if (!pdmac->peripherals) {
ret = -ENOMEM;
@@ -2974,6 +2973,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
else
pch->chan.private = adev->dev.of_node;
INIT_LIST_HEAD(&pch->submitted_list);
INIT_LIST_HEAD(&pch->work_list);
INIT_LIST_HEAD(&pch->completed_list);
spin_lock_init(&pch->lock);
@@ -3021,6 +3021,9 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
"unable to register DMA to the generic DT DMA helpers\n");
}
}
adev->dev.dma_parms = &pdmac->dma_parms;
/*
* This is the limit for transfers with a buswidth of 1, larger
* buswidths will have larger limits.

Some files were not shown because too many files have changed in this diff Show More