From 664a57ecb026dc47f9d8b002e6dcb557e877e4d1 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:31:53 +0100 Subject: dmaengine: ste_dma40: Assign memcpy channels in the driver The channels reserved for memcpy are the same for all currently supported platforms. With this in mind, we can ease the platform data passing requirement by moving these assignments out from platform code and place them directly into the driver. Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 1734feec47b1..12de79e84b15 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -55,6 +55,9 @@ #define MAX(a, b) (((a) < (b)) ? (b) : (a)) +/* Reserved event lines for memcpy only. */ +static int dma40_memcpy_channels[] = { 56, 57, 58, 59, 60 }; + /** * enum 40_command - The different commands and/or statuses. * @@ -2014,8 +2017,7 @@ static int d40_config_memcpy(struct d40_chan *d40c) if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) { d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_log; d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY; - d40c->dma_cfg.dst_dev_type = d40c->base->plat_data-> - memcpy[d40c->chan.chan_id]; + d40c->dma_cfg.dst_dev_type = dma40_memcpy_channels[d40c->chan.chan_id]; } else if (dma_has_cap(DMA_MEMCPY, cap) && dma_has_cap(DMA_SLAVE, cap)) { @@ -2927,7 +2929,7 @@ static int __init d40_dmaengine_init(struct d40_base *base, } d40_chan_init(base, &base->dma_memcpy, base->log_chans, - base->num_log_chans, base->plat_data->memcpy_len); + base->num_log_chans, ARRAY_SIZE(dma40_memcpy_channels)); dma_cap_zero(base->dma_memcpy.cap_mask); dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); @@ -3215,7 +3217,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) num_log_chans++; base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + - (num_phy_chans + num_log_chans + plat_data->memcpy_len) * + (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) * sizeof(struct d40_chan), GFP_KERNEL); if (base == NULL) { @@ -3276,7 +3278,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) if (!base->lookup_phy_chans) goto failure; - if (num_log_chans + plat_data->memcpy_len) { + if (num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) { /* * The max number of logical channels are event lines for all * src devices and dst devices -- cgit v1.2.3 From a2acaa2163566ad2e04b10fdf81de650e9b9261b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 3 May 2013 21:46:09 +0200 Subject: dmaengine: ste_dma40: Fix up static memcpy event lines The commit "dmaengine: ste_dma40: Assign memcpy channels in the driver" had two problems: - It assigned magic numbers to the memcpy event lines instead of giving them symbolic names. - It seems to have missed one of the memcpy event lines, number 51. This patch fixes it up. Acked-by: Lee Jones Acked-by: Vinod Koul Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 12de79e84b15..cd7b4808d08c 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -56,7 +56,21 @@ #define MAX(a, b) (((a) < (b)) ? (b) : (a)) /* Reserved event lines for memcpy only. */ -static int dma40_memcpy_channels[] = { 56, 57, 58, 59, 60 }; +#define DB8500_DMA_MEMCPY_EV_0 51 +#define DB8500_DMA_MEMCPY_EV_1 56 +#define DB8500_DMA_MEMCPY_EV_2 57 +#define DB8500_DMA_MEMCPY_EV_3 58 +#define DB8500_DMA_MEMCPY_EV_4 59 +#define DB8500_DMA_MEMCPY_EV_5 60 + +static int dma40_memcpy_channels[] = { + DB8500_DMA_MEMCPY_EV_0, + DB8500_DMA_MEMCPY_EV_1, + DB8500_DMA_MEMCPY_EV_2, + DB8500_DMA_MEMCPY_EV_3, + DB8500_DMA_MEMCPY_EV_4, + DB8500_DMA_MEMCPY_EV_5, +}; /** * enum 40_command - The different commands and/or statuses. -- cgit v1.2.3 From 29027a1e1121a1c9c5e726cf09dc2e9789a282f3 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:31:54 +0100 Subject: dmaengine: ste_dma40: Move default memcpy configs into the driver There are only two default memcpy configurations used for the DMA40 driver; one for physical memcpy and one for logical memcpy. Instead of invariably passing the same configurations though platform data, we're moving them into the driver instead. Acked-by: Vinod Koul Acked-by: Arnd Bergmann Acked-by: Linus Walleij Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/devices-db8500.c | 28 ------------------------- drivers/dma/ste_dma40.c | 32 +++++++++++++++++++++++++++-- include/linux/platform_data/dma-ste-dma40.h | 4 ---- 3 files changed, 30 insertions(+), 34 deletions(-) (limited to 'drivers/dma') diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 159855fae55b..a30977b374ba 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -42,32 +42,6 @@ static struct resource dma40_resources[] = { } }; -/* Default configuration for physcial memcpy */ -struct stedma40_chan_cfg dma40_memcpy_conf_phy = { - .mode = STEDMA40_MODE_PHYSICAL, - .dir = STEDMA40_MEM_TO_MEM, - - .src_info.data_width = STEDMA40_BYTE_WIDTH, - .src_info.psize = STEDMA40_PSIZE_PHY_1, - .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, - - .dst_info.data_width = STEDMA40_BYTE_WIDTH, - .dst_info.psize = STEDMA40_PSIZE_PHY_1, - .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, -}; -/* Default configuration for logical memcpy */ -struct stedma40_chan_cfg dma40_memcpy_conf_log = { - .dir = STEDMA40_MEM_TO_MEM, - - .src_info.data_width = STEDMA40_BYTE_WIDTH, - .src_info.psize = STEDMA40_PSIZE_LOG_1, - .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, - - .dst_info.data_width = STEDMA40_BYTE_WIDTH, - .dst_info.psize = STEDMA40_PSIZE_LOG_1, - .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, -}; - /* * Mapping between destination event lines and physical device address. * The event line is tied to a device and therefore the address is constant. @@ -150,8 +124,6 @@ static struct stedma40_platform_data dma40_plat_data = { .dev_len = DB8500_DMA_NR_DEV, .dev_rx = dma40_rx_map, .dev_tx = dma40_tx_map, - .memcpy_conf_phy = &dma40_memcpy_conf_phy, - .memcpy_conf_log = &dma40_memcpy_conf_log, .disabled_channels = {-1}, }; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index cd7b4808d08c..c47139ae8fa8 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -72,6 +72,34 @@ static int dma40_memcpy_channels[] = { DB8500_DMA_MEMCPY_EV_5, }; +/* Default configuration for physcial memcpy */ +struct stedma40_chan_cfg dma40_memcpy_conf_phy = { + .mode = STEDMA40_MODE_PHYSICAL, + .dir = STEDMA40_MEM_TO_MEM, + + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .src_info.psize = STEDMA40_PSIZE_PHY_1, + .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, + + .dst_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.psize = STEDMA40_PSIZE_PHY_1, + .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, +}; + +/* Default configuration for logical memcpy */ +struct stedma40_chan_cfg dma40_memcpy_conf_log = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_MEM_TO_MEM, + + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .src_info.psize = STEDMA40_PSIZE_LOG_1, + .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, + + .dst_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.psize = STEDMA40_PSIZE_LOG_1, + .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, +}; + /** * enum 40_command - The different commands and/or statuses. * @@ -2029,13 +2057,13 @@ static int d40_config_memcpy(struct d40_chan *d40c) dma_cap_mask_t cap = d40c->chan.device->cap_mask; if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) { - d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_log; + d40c->dma_cfg = dma40_memcpy_conf_log; d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY; d40c->dma_cfg.dst_dev_type = dma40_memcpy_channels[d40c->chan.chan_id]; } else if (dma_has_cap(DMA_MEMCPY, cap) && dma_has_cap(DMA_SLAVE, cap)) { - d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_phy; + d40c->dma_cfg = dma40_memcpy_conf_phy; } else { chan_err(d40c, "No memcpy\n"); return -EINVAL; diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index a8087843a99b..869c571c8c08 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h @@ -141,8 +141,6 @@ struct stedma40_chan_cfg { * @dev_len: length of dev_tx and dev_rx * @dev_tx: mapping between destination event line and io address * @dev_rx: mapping between source event line and io address - * @memcpy_conf_phy: default configuration of physical channel memcpy - * @memcpy_conf_log: default configuration of logical channel memcpy * @disabled_channels: A vector, ending with -1, that marks physical channels * that are for different reasons not available for the driver. * @soft_lli_chans: A vector, that marks physical channels will use LLI by SW @@ -160,8 +158,6 @@ struct stedma40_platform_data { u32 dev_len; const dma_addr_t *dev_tx; const dma_addr_t *dev_rx; - struct stedma40_chan_cfg *memcpy_conf_phy; - struct stedma40_chan_cfg *memcpy_conf_log; int disabled_channels[STEDMA40_MAX_PHYS]; int *soft_lli_chans; int num_of_soft_lli_chans; -- cgit v1.2.3 From 4f8fc46c797015dddc1d4c76e1b485b57373683b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:31:55 +0100 Subject: dmaengine: ste_dma40: Rectify incorrect configuration validation checking If we compare an event's group (dev_type / 16) with STEDMA40_DEV_DST_MEMORY (-1), the only way we'd obtain a positive result is if we passed -16 as a device type, which is unfeasible. Instead, it would be much more sane to compare STEDMA40_DEV_DST_MEMORY against the raw dev_type in order to expect the expected result. Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index c47139ae8fa8..d481cb8521d9 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -1785,19 +1785,19 @@ static int d40_validate_conf(struct d40_chan *d40c, } if (conf->dir == STEDMA40_MEM_TO_PERIPH && - dst_event_group == STEDMA40_DEV_DST_MEMORY) { + conf->dst_dev_type == STEDMA40_DEV_DST_MEMORY) { chan_err(d40c, "Invalid dst\n"); res = -EINVAL; } if (conf->dir == STEDMA40_PERIPH_TO_MEM && - src_event_group == STEDMA40_DEV_SRC_MEMORY) { + conf->src_dev_type == STEDMA40_DEV_SRC_MEMORY) { chan_err(d40c, "Invalid src\n"); res = -EINVAL; } - if (src_event_group == STEDMA40_DEV_SRC_MEMORY && - dst_event_group == STEDMA40_DEV_DST_MEMORY && is_log) { + if (conf->src_dev_type == STEDMA40_DEV_SRC_MEMORY && + conf->dst_dev_type == STEDMA40_DEV_DST_MEMORY && is_log) { chan_err(d40c, "No event line\n"); res = -EINVAL; } -- cgit v1.2.3 From 26955c07dcf3c36b6427e52fec0f725300ca079e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:31:56 +0100 Subject: dmaengine: ste_dma40: Amalgamate DMA source and destination channel numbers Devices which utilise DMA use the same device numbers for transmitting and receiving. In this patch we encode the source and destination information into one single attribute. We can subsequently exploit the direction attribute to see which of the transfer directions are being described. This also lessens the burden on platform data. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/board-mop500-audio.c | 18 +-- arch/arm/mach-ux500/board-mop500-sdi.c | 24 ++-- arch/arm/mach-ux500/board-mop500.c | 33 ++--- arch/arm/mach-ux500/cpu-db8500.c | 32 ++--- arch/arm/mach-ux500/devices-db8500.c | 120 ++++++++--------- arch/arm/mach-ux500/ste-dma40-db8500.h | 193 ++++++++++------------------ arch/arm/mach-ux500/usb.c | 10 +- drivers/dma/ste_dma40.c | 93 +++++--------- drivers/dma/ste_dma40_ll.c | 4 +- include/linux/platform_data/dma-ste-dma40.h | 6 +- 10 files changed, 207 insertions(+), 326 deletions(-) (limited to 'drivers/dma') diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c index aba9e5692958..5a968fa8b90c 100644 --- a/arch/arm/mach-ux500/board-mop500-audio.c +++ b/arch/arm/mach-ux500/board-mop500-audio.c @@ -23,8 +23,7 @@ static struct stedma40_chan_cfg msp0_dma_rx = { .high_priority = true, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0, .src_info.psize = STEDMA40_PSIZE_LOG_4, .dst_info.psize = STEDMA40_PSIZE_LOG_4, @@ -36,8 +35,7 @@ static struct stedma40_chan_cfg msp0_dma_tx = { .high_priority = true, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_DST_MEMORY, - .dst_dev_type = DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX, + .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0, .src_info.psize = STEDMA40_PSIZE_LOG_4, .dst_info.psize = STEDMA40_PSIZE_LOG_4, @@ -55,8 +53,7 @@ static struct stedma40_chan_cfg msp1_dma_rx = { .high_priority = true, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV30_MSP3_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV30_MSP3, .src_info.psize = STEDMA40_PSIZE_LOG_4, .dst_info.psize = STEDMA40_PSIZE_LOG_4, @@ -68,8 +65,7 @@ static struct stedma40_chan_cfg msp1_dma_tx = { .high_priority = true, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_DST_MEMORY, - .dst_dev_type = DB8500_DMA_DEV30_MSP1_TX, + .dev_type = DB8500_DMA_DEV30_MSP1, .src_info.psize = STEDMA40_PSIZE_LOG_4, .dst_info.psize = STEDMA40_PSIZE_LOG_4, @@ -87,8 +83,7 @@ static struct stedma40_chan_cfg msp2_dma_rx = { .high_priority = true, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV14_MSP2_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV14_MSP2, /* MSP2 DMA doesn't work with PSIZE == 4 on DB8500v2 */ .src_info.psize = STEDMA40_PSIZE_LOG_1, @@ -101,8 +96,7 @@ static struct stedma40_chan_cfg msp2_dma_tx = { .high_priority = true, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_DST_MEMORY, - .dst_dev_type = DB8500_DMA_DEV14_MSP2_TX, + .dev_type = DB8500_DMA_DEV14_MSP2, .src_info.psize = STEDMA40_PSIZE_LOG_4, .dst_info.psize = STEDMA40_PSIZE_LOG_4, diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 0ef38775a0c1..4e30b6dc9ac5 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -35,8 +35,7 @@ struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV29_SD_MM0_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV29_SD_MM0, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, }; @@ -44,8 +43,7 @@ struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = { static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV29_SD_MM0_TX, + .dev_type = DB8500_DMA_DEV29_SD_MM0, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, }; @@ -88,8 +86,7 @@ void mop500_sdi_tc35892_init(struct device *parent) static struct stedma40_chan_cfg sdi1_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV32_SD_MM1_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV32_SD_MM1, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, }; @@ -97,8 +94,7 @@ static struct stedma40_chan_cfg sdi1_dma_cfg_rx = { static struct stedma40_chan_cfg sdi1_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV32_SD_MM1_TX, + .dev_type = DB8500_DMA_DEV32_SD_MM1, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, }; @@ -125,8 +121,7 @@ struct mmci_platform_data mop500_sdi1_data = { struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV28_SD_MM2_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV28_SD_MM2, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, }; @@ -134,8 +129,7 @@ struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = { static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX, + .dev_type = DB8500_DMA_DEV28_SD_MM2, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, }; @@ -163,8 +157,7 @@ struct mmci_platform_data mop500_sdi2_data = { struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV42_SD_MM4_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV42_SD_MM4, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, }; @@ -172,8 +165,7 @@ struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = { static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV42_SD_MM4_TX, + .dev_type = DB8500_DMA_DEV42_SD_MM4, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, }; diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 3cd555ac6d0a..871e61517fb2 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -425,8 +425,7 @@ void mop500_snowball_ethernet_clock_enable(void) static struct cryp_platform_data u8500_cryp1_platform_data = { .mem_to_engine = { .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV48_CAC1_TX, + .dev_type = DB8500_DMA_DEV48_CAC1, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, .mode = STEDMA40_MODE_LOGICAL, @@ -435,8 +434,7 @@ static struct cryp_platform_data u8500_cryp1_platform_data = { }, .engine_to_mem = { .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV48_CAC1_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV48_CAC1, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, .mode = STEDMA40_MODE_LOGICAL, @@ -447,8 +445,7 @@ static struct cryp_platform_data u8500_cryp1_platform_data = { static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = { .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV50_HAC1_TX, + .dev_type = DB8500_DMA_DEV50_HAC1_TX, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH, .mode = STEDMA40_MODE_LOGICAL, @@ -471,8 +468,7 @@ static struct platform_device *mop500_platform_devs[] __initdata = { static struct stedma40_chan_cfg ssp0_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV8_SSP0_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV8_SSP0, .src_info.data_width = STEDMA40_BYTE_WIDTH, .dst_info.data_width = STEDMA40_BYTE_WIDTH, }; @@ -480,8 +476,7 @@ static struct stedma40_chan_cfg ssp0_dma_cfg_rx = { static struct stedma40_chan_cfg ssp0_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV8_SSP0_TX, + .dev_type = DB8500_DMA_DEV8_SSP0, .src_info.data_width = STEDMA40_BYTE_WIDTH, .dst_info.data_width = STEDMA40_BYTE_WIDTH, }; @@ -512,8 +507,7 @@ static void __init mop500_spi_init(struct device *parent) static struct stedma40_chan_cfg uart0_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV13_UART0_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV13_UART0, .src_info.data_width = STEDMA40_BYTE_WIDTH, .dst_info.data_width = STEDMA40_BYTE_WIDTH, }; @@ -521,8 +515,7 @@ static struct stedma40_chan_cfg uart0_dma_cfg_rx = { static struct stedma40_chan_cfg uart0_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV13_UART0_TX, + .dev_type = DB8500_DMA_DEV13_UART0, .src_info.data_width = STEDMA40_BYTE_WIDTH, .dst_info.data_width = STEDMA40_BYTE_WIDTH, }; @@ -530,8 +523,7 @@ static struct stedma40_chan_cfg uart0_dma_cfg_tx = { static struct stedma40_chan_cfg uart1_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV12_UART1_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV12_UART1, .src_info.data_width = STEDMA40_BYTE_WIDTH, .dst_info.data_width = STEDMA40_BYTE_WIDTH, }; @@ -539,8 +531,7 @@ static struct stedma40_chan_cfg uart1_dma_cfg_rx = { static struct stedma40_chan_cfg uart1_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV12_UART1_TX, + .dev_type = DB8500_DMA_DEV12_UART1, .src_info.data_width = STEDMA40_BYTE_WIDTH, .dst_info.data_width = STEDMA40_BYTE_WIDTH, }; @@ -548,8 +539,7 @@ static struct stedma40_chan_cfg uart1_dma_cfg_tx = { static struct stedma40_chan_cfg uart2_dma_cfg_rx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_PERIPH_TO_MEM, - .src_dev_type = DB8500_DMA_DEV11_UART2_RX, - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .dev_type = DB8500_DMA_DEV11_UART2, .src_info.data_width = STEDMA40_BYTE_WIDTH, .dst_info.data_width = STEDMA40_BYTE_WIDTH, }; @@ -557,8 +547,7 @@ static struct stedma40_chan_cfg uart2_dma_cfg_rx = { static struct stedma40_chan_cfg uart2_dma_cfg_tx = { .mode = STEDMA40_MODE_LOGICAL, .dir = STEDMA40_MEM_TO_PERIPH, - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, - .dst_dev_type = DB8500_DMA_DEV11_UART2_TX, + .dev_type = DB8500_DMA_DEV11_UART2, .src_info.data_width = STEDMA40_BYTE_WIDTH, .dst_info.data_width = STEDMA40_BYTE_WIDTH, }; diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index e90b5ab23b6d..67d68e05f3a7 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -163,25 +163,25 @@ static void __init db8500_add_gpios(struct device *parent) } static int usb_db8500_rx_dma_cfg[] = { - DB8500_DMA_DEV38_USB_OTG_IEP_1_9, - DB8500_DMA_DEV37_USB_OTG_IEP_2_10, - DB8500_DMA_DEV36_USB_OTG_IEP_3_11, - DB8500_DMA_DEV19_USB_OTG_IEP_4_12, - DB8500_DMA_DEV18_USB_OTG_IEP_5_13, - DB8500_DMA_DEV17_USB_OTG_IEP_6_14, - DB8500_DMA_DEV16_USB_OTG_IEP_7_15, - DB8500_DMA_DEV39_USB_OTG_IEP_8 + DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9, + DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10, + DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11, + DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12, + DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13, + DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14, + DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15, + DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8 }; static int usb_db8500_tx_dma_cfg[] = { - DB8500_DMA_DEV38_USB_OTG_OEP_1_9, - DB8500_DMA_DEV37_USB_OTG_OEP_2_10, - DB8500_DMA_DEV36_USB_OTG_OEP_3_11, - DB8500_DMA_DEV19_USB_OTG_OEP_4_12, - DB8500_DMA_DEV18_USB_OTG_OEP_5_13, - DB8500_DMA_DEV17_USB_OTG_OEP_6_14, - DB8500_DMA_DEV16_USB_OTG_OEP_7_15, - DB8500_DMA_DEV39_USB_OTG_OEP_8 + DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9, + DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10, + DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11, + DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12, + DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13, + DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14, + DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15, + DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8 }; static const char *db8500_read_soc_id(void) diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index a30977b374ba..7989c564e47a 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -50,74 +50,74 @@ static struct resource dma40_resources[] = { */ static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV] = { /* MUSB - these will be runtime-reconfigured */ - [DB8500_DMA_DEV39_USB_OTG_OEP_8] = -1, - [DB8500_DMA_DEV16_USB_OTG_OEP_7_15] = -1, - [DB8500_DMA_DEV17_USB_OTG_OEP_6_14] = -1, - [DB8500_DMA_DEV18_USB_OTG_OEP_5_13] = -1, - [DB8500_DMA_DEV19_USB_OTG_OEP_4_12] = -1, - [DB8500_DMA_DEV36_USB_OTG_OEP_3_11] = -1, - [DB8500_DMA_DEV37_USB_OTG_OEP_2_10] = -1, - [DB8500_DMA_DEV38_USB_OTG_OEP_1_9] = -1, + [DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8] = -1, + [DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15] = -1, + [DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14] = -1, + [DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13] = -1, + [DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12] = -1, + [DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11] = -1, + [DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10] = -1, + [DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9] = -1, /* PrimeCells - run-time configured */ - [DB8500_DMA_DEV0_SPI0_TX] = -1, - [DB8500_DMA_DEV1_SD_MMC0_TX] = -1, - [DB8500_DMA_DEV2_SD_MMC1_TX] = -1, - [DB8500_DMA_DEV3_SD_MMC2_TX] = -1, - [DB8500_DMA_DEV8_SSP0_TX] = -1, - [DB8500_DMA_DEV9_SSP1_TX] = -1, - [DB8500_DMA_DEV11_UART2_TX] = -1, - [DB8500_DMA_DEV12_UART1_TX] = -1, - [DB8500_DMA_DEV13_UART0_TX] = -1, - [DB8500_DMA_DEV28_SD_MM2_TX] = -1, - [DB8500_DMA_DEV29_SD_MM0_TX] = -1, - [DB8500_DMA_DEV32_SD_MM1_TX] = -1, - [DB8500_DMA_DEV33_SPI2_TX] = -1, - [DB8500_DMA_DEV35_SPI1_TX] = -1, - [DB8500_DMA_DEV40_SPI3_TX] = -1, - [DB8500_DMA_DEV41_SD_MM3_TX] = -1, - [DB8500_DMA_DEV42_SD_MM4_TX] = -1, - [DB8500_DMA_DEV43_SD_MM5_TX] = -1, - [DB8500_DMA_DEV14_MSP2_TX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET, - [DB8500_DMA_DEV30_MSP1_TX] = U8500_MSP1_BASE + MSP_TX_RX_REG_OFFSET, - [DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET, - [DB8500_DMA_DEV48_CAC1_TX] = U8500_CRYP1_BASE + CRYP1_TX_REG_OFFSET, + [DB8500_DMA_DEV0_SPI0] = -1, + [DB8500_DMA_DEV1_SD_MMC0] = -1, + [DB8500_DMA_DEV2_SD_MMC1] = -1, + [DB8500_DMA_DEV3_SD_MMC2] = -1, + [DB8500_DMA_DEV8_SSP0] = -1, + [DB8500_DMA_DEV9_SSP1] = -1, + [DB8500_DMA_DEV11_UART2] = -1, + [DB8500_DMA_DEV12_UART1] = -1, + [DB8500_DMA_DEV13_UART0] = -1, + [DB8500_DMA_DEV28_SD_MM2] = -1, + [DB8500_DMA_DEV29_SD_MM0] = -1, + [DB8500_DMA_DEV32_SD_MM1] = -1, + [DB8500_DMA_DEV33_SPI2] = -1, + [DB8500_DMA_DEV35_SPI1] = -1, + [DB8500_DMA_DEV40_SPI3] = -1, + [DB8500_DMA_DEV41_SD_MM3] = -1, + [DB8500_DMA_DEV42_SD_MM4] = -1, + [DB8500_DMA_DEV43_SD_MM5] = -1, + [DB8500_DMA_DEV14_MSP2] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV30_MSP1] = U8500_MSP1_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV31_MSP0_SLIM0_CH0] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV48_CAC1] = U8500_CRYP1_BASE + CRYP1_TX_REG_OFFSET, [DB8500_DMA_DEV50_HAC1_TX] = U8500_HASH1_BASE + HASH1_TX_REG_OFFSET, }; /* Mapping between source event lines and physical device address */ static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = { /* MUSB - these will be runtime-reconfigured */ - [DB8500_DMA_DEV39_USB_OTG_IEP_8] = -1, - [DB8500_DMA_DEV16_USB_OTG_IEP_7_15] = -1, - [DB8500_DMA_DEV17_USB_OTG_IEP_6_14] = -1, - [DB8500_DMA_DEV18_USB_OTG_IEP_5_13] = -1, - [DB8500_DMA_DEV19_USB_OTG_IEP_4_12] = -1, - [DB8500_DMA_DEV36_USB_OTG_IEP_3_11] = -1, - [DB8500_DMA_DEV37_USB_OTG_IEP_2_10] = -1, - [DB8500_DMA_DEV38_USB_OTG_IEP_1_9] = -1, + [DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8] = -1, + [DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15] = -1, + [DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14] = -1, + [DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13] = -1, + [DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12] = -1, + [DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11] = -1, + [DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10] = -1, + [DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9] = -1, /* PrimeCells */ - [DB8500_DMA_DEV0_SPI0_RX] = -1, - [DB8500_DMA_DEV1_SD_MMC0_RX] = -1, - [DB8500_DMA_DEV2_SD_MMC1_RX] = -1, - [DB8500_DMA_DEV3_SD_MMC2_RX] = -1, - [DB8500_DMA_DEV8_SSP0_RX] = -1, - [DB8500_DMA_DEV9_SSP1_RX] = -1, - [DB8500_DMA_DEV11_UART2_RX] = -1, - [DB8500_DMA_DEV12_UART1_RX] = -1, - [DB8500_DMA_DEV13_UART0_RX] = -1, - [DB8500_DMA_DEV28_SD_MM2_RX] = -1, - [DB8500_DMA_DEV29_SD_MM0_RX] = -1, - [DB8500_DMA_DEV32_SD_MM1_RX] = -1, - [DB8500_DMA_DEV33_SPI2_RX] = -1, - [DB8500_DMA_DEV35_SPI1_RX] = -1, - [DB8500_DMA_DEV40_SPI3_RX] = -1, - [DB8500_DMA_DEV41_SD_MM3_RX] = -1, - [DB8500_DMA_DEV42_SD_MM4_RX] = -1, - [DB8500_DMA_DEV43_SD_MM5_RX] = -1, - [DB8500_DMA_DEV14_MSP2_RX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET, - [DB8500_DMA_DEV30_MSP3_RX] = U8500_MSP3_BASE + MSP_TX_RX_REG_OFFSET, - [DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET, - [DB8500_DMA_DEV48_CAC1_RX] = U8500_CRYP1_BASE + CRYP1_RX_REG_OFFSET, + [DB8500_DMA_DEV0_SPI0] = -1, + [DB8500_DMA_DEV1_SD_MMC0] = -1, + [DB8500_DMA_DEV2_SD_MMC1] = -1, + [DB8500_DMA_DEV3_SD_MMC2] = -1, + [DB8500_DMA_DEV8_SSP0] = -1, + [DB8500_DMA_DEV9_SSP1] = -1, + [DB8500_DMA_DEV11_UART2] = -1, + [DB8500_DMA_DEV12_UART1] = -1, + [DB8500_DMA_DEV13_UART0] = -1, + [DB8500_DMA_DEV28_SD_MM2] = -1, + [DB8500_DMA_DEV29_SD_MM0] = -1, + [DB8500_DMA_DEV32_SD_MM1] = -1, + [DB8500_DMA_DEV33_SPI2] = -1, + [DB8500_DMA_DEV35_SPI1] = -1, + [DB8500_DMA_DEV40_SPI3] = -1, + [DB8500_DMA_DEV41_SD_MM3] = -1, + [DB8500_DMA_DEV42_SD_MM4] = -1, + [DB8500_DMA_DEV43_SD_MM5] = -1, + [DB8500_DMA_DEV14_MSP2] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV30_MSP3] = U8500_MSP3_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV31_MSP0_SLIM0_CH0] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV48_CAC1] = U8500_CRYP1_BASE + CRYP1_RX_REG_OFFSET, }; static struct stedma40_platform_data dma40_plat_data = { diff --git a/arch/arm/mach-ux500/ste-dma40-db8500.h b/arch/arm/mach-ux500/ste-dma40-db8500.h index a616419bea76..0296ae5b0fd9 100644 --- a/arch/arm/mach-ux500/ste-dma40-db8500.h +++ b/arch/arm/mach-ux500/ste-dma40-db8500.h @@ -12,133 +12,74 @@ #define DB8500_DMA_NR_DEV 64 -enum dma_src_dev_type { - DB8500_DMA_DEV0_SPI0_RX = 0, - DB8500_DMA_DEV1_SD_MMC0_RX = 1, - DB8500_DMA_DEV2_SD_MMC1_RX = 2, - DB8500_DMA_DEV3_SD_MMC2_RX = 3, - DB8500_DMA_DEV4_I2C1_RX = 4, - DB8500_DMA_DEV5_I2C3_RX = 5, - DB8500_DMA_DEV6_I2C2_RX = 6, - DB8500_DMA_DEV7_I2C4_RX = 7, /* Only on V1 and later */ - DB8500_DMA_DEV8_SSP0_RX = 8, - DB8500_DMA_DEV9_SSP1_RX = 9, - DB8500_DMA_DEV10_MCDE_RX = 10, - DB8500_DMA_DEV11_UART2_RX = 11, - DB8500_DMA_DEV12_UART1_RX = 12, - DB8500_DMA_DEV13_UART0_RX = 13, - DB8500_DMA_DEV14_MSP2_RX = 14, - DB8500_DMA_DEV15_I2C0_RX = 15, - DB8500_DMA_DEV16_USB_OTG_IEP_7_15 = 16, - DB8500_DMA_DEV17_USB_OTG_IEP_6_14 = 17, - DB8500_DMA_DEV18_USB_OTG_IEP_5_13 = 18, - DB8500_DMA_DEV19_USB_OTG_IEP_4_12 = 19, - DB8500_DMA_DEV20_SLIM0_CH0_RX_HSI_RX_CH0 = 20, - DB8500_DMA_DEV21_SLIM0_CH1_RX_HSI_RX_CH1 = 21, - DB8500_DMA_DEV22_SLIM0_CH2_RX_HSI_RX_CH2 = 22, - DB8500_DMA_DEV23_SLIM0_CH3_RX_HSI_RX_CH3 = 23, - DB8500_DMA_DEV24_SRC_SXA0_RX_TX = 24, - DB8500_DMA_DEV25_SRC_SXA1_RX_TX = 25, - DB8500_DMA_DEV26_SRC_SXA2_RX_TX = 26, - DB8500_DMA_DEV27_SRC_SXA3_RX_TX = 27, - DB8500_DMA_DEV28_SD_MM2_RX = 28, - DB8500_DMA_DEV29_SD_MM0_RX = 29, - DB8500_DMA_DEV30_MSP1_RX = 30, +/* + * Unless otherwise specified, all channels numbers are used for + * TX & RX, and can be used for either source or destination + * channels. + */ +enum dma_dev_type { + DB8500_DMA_DEV0_SPI0 = 0, + DB8500_DMA_DEV1_SD_MMC0 = 1, + DB8500_DMA_DEV2_SD_MMC1 = 2, + DB8500_DMA_DEV3_SD_MMC2 = 3, + DB8500_DMA_DEV4_I2C1 = 4, + DB8500_DMA_DEV5_I2C3 = 5, + DB8500_DMA_DEV6_I2C2 = 6, + DB8500_DMA_DEV7_I2C4 = 7, /* Only on V1 and later */ + DB8500_DMA_DEV8_SSP0 = 8, + DB8500_DMA_DEV9_SSP1 = 9, + DB8500_DMA_DEV10_MCDE_RX = 10, /* RX only */ + DB8500_DMA_DEV11_UART2 = 11, + DB8500_DMA_DEV12_UART1 = 12, + DB8500_DMA_DEV13_UART0 = 13, + DB8500_DMA_DEV14_MSP2 = 14, + DB8500_DMA_DEV15_I2C0 = 15, + DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15 = 16, + DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14 = 17, + DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13 = 18, + DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12 = 19, + DB8500_DMA_DEV20_SLIM0_CH0_HSI_CH0 = 20, + DB8500_DMA_DEV21_SLIM0_CH1_HSI_CH1 = 21, + DB8500_DMA_DEV22_SLIM0_CH2_HSI_CH2 = 22, + DB8500_DMA_DEV23_SLIM0_CH3_HSI_CH3 = 23, + DB8500_DMA_DEV24_SXA0 = 24, + DB8500_DMA_DEV25_SXA1 = 25, + DB8500_DMA_DEV26_SXA2 = 26, + DB8500_DMA_DEV27_SXA3 = 27, + DB8500_DMA_DEV28_SD_MM2 = 28, + DB8500_DMA_DEV29_SD_MM0 = 29, + DB8500_DMA_DEV30_MSP1 = 30, /* On DB8500v2, MSP3 RX replaces MSP1 RX */ - DB8500_DMA_DEV30_MSP3_RX = 30, - DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX = 31, - DB8500_DMA_DEV32_SD_MM1_RX = 32, - DB8500_DMA_DEV33_SPI2_RX = 33, - DB8500_DMA_DEV34_I2C3_RX2 = 34, - DB8500_DMA_DEV35_SPI1_RX = 35, - DB8500_DMA_DEV36_USB_OTG_IEP_3_11 = 36, - DB8500_DMA_DEV37_USB_OTG_IEP_2_10 = 37, - DB8500_DMA_DEV38_USB_OTG_IEP_1_9 = 38, - DB8500_DMA_DEV39_USB_OTG_IEP_8 = 39, - DB8500_DMA_DEV40_SPI3_RX = 40, - DB8500_DMA_DEV41_SD_MM3_RX = 41, - DB8500_DMA_DEV42_SD_MM4_RX = 42, - DB8500_DMA_DEV43_SD_MM5_RX = 43, - DB8500_DMA_DEV44_SRC_SXA4_RX_TX = 44, - DB8500_DMA_DEV45_SRC_SXA5_RX_TX = 45, - DB8500_DMA_DEV46_SLIM0_CH8_RX_SRC_SXA6_RX_TX = 46, - DB8500_DMA_DEV47_SLIM0_CH9_RX_SRC_SXA7_RX_TX = 47, - DB8500_DMA_DEV48_CAC1_RX = 48, - /* 49, 50 and 51 are not used */ - DB8500_DMA_DEV52_SLIM0_CH4_RX_HSI_RX_CH4 = 52, - DB8500_DMA_DEV53_SLIM0_CH5_RX_HSI_RX_CH5 = 53, - DB8500_DMA_DEV54_SLIM0_CH6_RX_HSI_RX_CH6 = 54, - DB8500_DMA_DEV55_SLIM0_CH7_RX_HSI_RX_CH7 = 55, - /* 56, 57, 58, 59 and 60 are not used */ - DB8500_DMA_DEV61_CAC0_RX = 61, - /* 62 and 63 are not used */ -}; - -enum dma_dest_dev_type { - DB8500_DMA_DEV0_SPI0_TX = 0, - DB8500_DMA_DEV1_SD_MMC0_TX = 1, - DB8500_DMA_DEV2_SD_MMC1_TX = 2, - DB8500_DMA_DEV3_SD_MMC2_TX = 3, - DB8500_DMA_DEV4_I2C1_TX = 4, - DB8500_DMA_DEV5_I2C3_TX = 5, - DB8500_DMA_DEV6_I2C2_TX = 6, - DB8500_DMA_DEV7_I2C4_TX = 7, /* Only on V1 and later */ - DB8500_DMA_DEV8_SSP0_TX = 8, - DB8500_DMA_DEV9_SSP1_TX = 9, - /* 10 is not used*/ - DB8500_DMA_DEV11_UART2_TX = 11, - DB8500_DMA_DEV12_UART1_TX = 12, - DB8500_DMA_DEV13_UART0_TX = 13, - DB8500_DMA_DEV14_MSP2_TX = 14, - DB8500_DMA_DEV15_I2C0_TX = 15, - DB8500_DMA_DEV16_USB_OTG_OEP_7_15 = 16, - DB8500_DMA_DEV17_USB_OTG_OEP_6_14 = 17, - DB8500_DMA_DEV18_USB_OTG_OEP_5_13 = 18, - DB8500_DMA_DEV19_USB_OTG_OEP_4_12 = 19, - DB8500_DMA_DEV20_SLIM0_CH0_TX_HSI_TX_CH0 = 20, - DB8500_DMA_DEV21_SLIM0_CH1_TX_HSI_TX_CH1 = 21, - DB8500_DMA_DEV22_SLIM0_CH2_TX_HSI_TX_CH2 = 22, - DB8500_DMA_DEV23_SLIM0_CH3_TX_HSI_TX_CH3 = 23, - DB8500_DMA_DEV24_DST_SXA0_RX_TX = 24, - DB8500_DMA_DEV25_DST_SXA1_RX_TX = 25, - DB8500_DMA_DEV26_DST_SXA2_RX_TX = 26, - DB8500_DMA_DEV27_DST_SXA3_RX_TX = 27, - DB8500_DMA_DEV28_SD_MM2_TX = 28, - DB8500_DMA_DEV29_SD_MM0_TX = 29, - DB8500_DMA_DEV30_MSP1_TX = 30, - DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX = 31, - DB8500_DMA_DEV32_SD_MM1_TX = 32, - DB8500_DMA_DEV33_SPI2_TX = 33, - DB8500_DMA_DEV34_I2C3_TX2 = 34, - DB8500_DMA_DEV35_SPI1_TX = 35, - DB8500_DMA_DEV36_USB_OTG_OEP_3_11 = 36, - DB8500_DMA_DEV37_USB_OTG_OEP_2_10 = 37, - DB8500_DMA_DEV38_USB_OTG_OEP_1_9 = 38, - DB8500_DMA_DEV39_USB_OTG_OEP_8 = 39, - DB8500_DMA_DEV40_SPI3_TX = 40, - DB8500_DMA_DEV41_SD_MM3_TX = 41, - DB8500_DMA_DEV42_SD_MM4_TX = 42, - DB8500_DMA_DEV43_SD_MM5_TX = 43, - DB8500_DMA_DEV44_DST_SXA4_RX_TX = 44, - DB8500_DMA_DEV45_DST_SXA5_RX_TX = 45, - DB8500_DMA_DEV46_SLIM0_CH8_TX_DST_SXA6_RX_TX = 46, - DB8500_DMA_DEV47_SLIM0_CH9_TX_DST_SXA7_RX_TX = 47, - DB8500_DMA_DEV48_CAC1_TX = 48, - DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49, - DB8500_DMA_DEV50_HAC1_TX = 50, - DB8500_DMA_MEMCPY_TX_0 = 51, - DB8500_DMA_DEV52_SLIM1_CH4_TX_HSI_TX_CH4 = 52, - DB8500_DMA_DEV53_SLIM1_CH5_TX_HSI_TX_CH5 = 53, - DB8500_DMA_DEV54_SLIM1_CH6_TX_HSI_TX_CH6 = 54, - DB8500_DMA_DEV55_SLIM1_CH7_TX_HSI_TX_CH7 = 55, - DB8500_DMA_MEMCPY_TX_1 = 56, - DB8500_DMA_MEMCPY_TX_2 = 57, - DB8500_DMA_MEMCPY_TX_3 = 58, - DB8500_DMA_MEMCPY_TX_4 = 59, - DB8500_DMA_MEMCPY_TX_5 = 60, - DB8500_DMA_DEV61_CAC0_TX = 61, - DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62, - DB8500_DMA_DEV63_HAC0_TX = 63, + DB8500_DMA_DEV30_MSP3 = 30, + DB8500_DMA_DEV31_MSP0_SLIM0_CH0 = 31, + DB8500_DMA_DEV32_SD_MM1 = 32, + DB8500_DMA_DEV33_SPI2 = 33, + DB8500_DMA_DEV34_I2C3_RX2_TX2 = 34, + DB8500_DMA_DEV35_SPI1 = 35, + DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11 = 36, + DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10 = 37, + DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9 = 38, + DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8 = 39, + DB8500_DMA_DEV40_SPI3 = 40, + DB8500_DMA_DEV41_SD_MM3 = 41, + DB8500_DMA_DEV42_SD_MM4 = 42, + DB8500_DMA_DEV43_SD_MM5 = 43, + DB8500_DMA_DEV44_SXA4 = 44, + DB8500_DMA_DEV45_SXA5 = 45, + DB8500_DMA_DEV46_SLIM0_CH8_SRC_SXA6 = 46, + DB8500_DMA_DEV47_SLIM0_CH9_SRC_SXA7 = 47, + DB8500_DMA_DEV48_CAC1 = 48, + DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49, /* TX only */ + DB8500_DMA_DEV50_HAC1_TX = 50, /* TX only */ + DB8500_DMA_MEMCPY_TX_0 = 51, /* TX only */ + DB8500_DMA_DEV52_SLIM0_CH4_HSI_CH4 = 52, + DB8500_DMA_DEV53_SLIM0_CH5_HSI_CH5 = 53, + DB8500_DMA_DEV54_SLIM0_CH6_HSI_CH6 = 54, + DB8500_DMA_DEV55_SLIM0_CH7_HSI_CH7 = 55, + /* 56 -> 60 are channels reserved for memcpy only */ + DB8500_DMA_DEV61_CAC0 = 61, + DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62, /* TX only */ + DB8500_DMA_DEV63_HAC0_TX = 63, /* TX only */ }; #endif diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index 2dfc72f7cd8a..45af3031dfef 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -15,7 +15,6 @@ #define MUSB_DMA40_RX_CH { \ .mode = STEDMA40_MODE_LOGICAL, \ .dir = STEDMA40_PERIPH_TO_MEM, \ - .dst_dev_type = STEDMA40_DEV_DST_MEMORY, \ .src_info.data_width = STEDMA40_WORD_WIDTH, \ .dst_info.data_width = STEDMA40_WORD_WIDTH, \ .src_info.psize = STEDMA40_PSIZE_LOG_16, \ @@ -25,7 +24,6 @@ #define MUSB_DMA40_TX_CH { \ .mode = STEDMA40_MODE_LOGICAL, \ .dir = STEDMA40_MEM_TO_PERIPH, \ - .src_dev_type = STEDMA40_DEV_SRC_MEMORY, \ .src_info.data_width = STEDMA40_WORD_WIDTH, \ .dst_info.data_width = STEDMA40_WORD_WIDTH, \ .src_info.psize = STEDMA40_PSIZE_LOG_16, \ @@ -125,20 +123,20 @@ struct platform_device ux500_musb_device = { .resource = usb_resources, }; -static inline void ux500_usb_dma_update_rx_ch_config(int *src_dev_type) +static inline void ux500_usb_dma_update_rx_ch_config(int *dev_type) { u32 idx; for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_CHANNELS; idx++) - musb_dma_rx_ch[idx].src_dev_type = src_dev_type[idx]; + musb_dma_rx_ch[idx].dev_type = dev_type[idx]; } -static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type) +static inline void ux500_usb_dma_update_tx_ch_config(int *dev_type) { u32 idx; for (idx = 0; idx < UX500_MUSB_DMA_NUM_TX_CHANNELS; idx++) - musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx]; + musb_dma_tx_ch[idx].dev_type = dev_type[idx]; } void ux500_add_usb(struct device *parent, resource_size_t base, int irq, diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index d481cb8521d9..63495f6a36f9 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -1302,21 +1302,17 @@ static void __d40_config_set_event(struct d40_chan *d40c, static void d40_config_set_event(struct d40_chan *d40c, enum d40_events event_type) { + u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type); + /* Enable event line connected to device (or memcpy) */ if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || - (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) { - u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); - + (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) __d40_config_set_event(d40c, event_type, event, D40_CHAN_REG_SSLNK); - } - - if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) { - u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); + if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) __d40_config_set_event(d40c, event_type, event, D40_CHAN_REG_SDLNK); - } } static u32 d40_chan_has_events(struct d40_chan *d40c) @@ -1758,8 +1754,6 @@ static int d40_validate_conf(struct d40_chan *d40c, struct stedma40_chan_cfg *conf) { int res = 0; - u32 dst_event_group = D40_TYPE_TO_GROUP(conf->dst_dev_type); - u32 src_event_group = D40_TYPE_TO_GROUP(conf->src_dev_type); bool is_log = conf->mode == STEDMA40_MODE_LOGICAL; if (!conf->dir) { @@ -1767,44 +1761,26 @@ static int d40_validate_conf(struct d40_chan *d40c, res = -EINVAL; } - if (conf->dst_dev_type != STEDMA40_DEV_DST_MEMORY && - d40c->base->plat_data->dev_tx[conf->dst_dev_type] == 0 && - d40c->runtime_addr == 0) { - - chan_err(d40c, "Invalid TX channel address (%d)\n", - conf->dst_dev_type); - res = -EINVAL; - } - - if (conf->src_dev_type != STEDMA40_DEV_SRC_MEMORY && - d40c->base->plat_data->dev_rx[conf->src_dev_type] == 0 && - d40c->runtime_addr == 0) { - chan_err(d40c, "Invalid RX channel address (%d)\n", - conf->src_dev_type); + if ((is_log && conf->dev_type > d40c->base->num_log_chans) || + (!is_log && conf->dev_type > d40c->base->num_phy_chans) || + (conf->dev_type < 0)) { + chan_err(d40c, "Invalid device type (%d)\n", conf->dev_type); res = -EINVAL; } if (conf->dir == STEDMA40_MEM_TO_PERIPH && - conf->dst_dev_type == STEDMA40_DEV_DST_MEMORY) { - chan_err(d40c, "Invalid dst\n"); + d40c->base->plat_data->dev_tx[conf->dev_type] == 0 && + d40c->runtime_addr == 0) { + chan_err(d40c, "Invalid TX channel address (%d)\n", + conf->dev_type); res = -EINVAL; } if (conf->dir == STEDMA40_PERIPH_TO_MEM && - conf->src_dev_type == STEDMA40_DEV_SRC_MEMORY) { - chan_err(d40c, "Invalid src\n"); - res = -EINVAL; - } - - if (conf->src_dev_type == STEDMA40_DEV_SRC_MEMORY && - conf->dst_dev_type == STEDMA40_DEV_DST_MEMORY && is_log) { - chan_err(d40c, "No event line\n"); - res = -EINVAL; - } - - if (conf->dir == STEDMA40_PERIPH_TO_PERIPH && - (src_event_group != dst_event_group)) { - chan_err(d40c, "Invalid event group\n"); + d40c->base->plat_data->dev_rx[conf->dev_type] == 0 && + d40c->runtime_addr == 0) { + chan_err(d40c, "Invalid RX channel address (%d)\n", + conf->dev_type); res = -EINVAL; } @@ -1925,7 +1901,7 @@ out: static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user) { - int dev_type; + int dev_type = d40c->dma_cfg.dev_type; int event_group; int event_line; struct d40_phy_res *phys; @@ -1940,13 +1916,11 @@ static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user) num_phy_chans = d40c->base->num_phy_chans; if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { - dev_type = d40c->dma_cfg.src_dev_type; log_num = 2 * dev_type; is_src = true; } else if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { /* dst event lines are used for logical memcpy */ - dev_type = d40c->dma_cfg.dst_dev_type; log_num = 2 * dev_type + 1; is_src = false; } else @@ -2058,8 +2032,7 @@ static int d40_config_memcpy(struct d40_chan *d40c) if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) { d40c->dma_cfg = dma40_memcpy_conf_log; - d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY; - d40c->dma_cfg.dst_dev_type = dma40_memcpy_channels[d40c->chan.chan_id]; + d40c->dma_cfg.dev_type = dma40_memcpy_channels[d40c->chan.chan_id]; } else if (dma_has_cap(DMA_MEMCPY, cap) && dma_has_cap(DMA_SLAVE, cap)) { @@ -2076,7 +2049,7 @@ static int d40_free_dma(struct d40_chan *d40c) { int res = 0; - u32 event; + u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type); struct d40_phy_res *phy = d40c->phy_chan; bool is_src; @@ -2095,13 +2068,11 @@ static int d40_free_dma(struct d40_chan *d40c) } if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || - d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { - event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); + d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) is_src = false; - } else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { - event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); + else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) is_src = true; - } else { + else { chan_err(d40c, "Unknown direction\n"); return -EINVAL; } @@ -2142,7 +2113,7 @@ static bool d40_is_paused(struct d40_chan *d40c) unsigned long flags; void __iomem *active_reg; u32 status; - u32 event; + u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type); spin_lock_irqsave(&d40c->lock, flags); @@ -2163,10 +2134,8 @@ static bool d40_is_paused(struct d40_chan *d40c) if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { - event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); status = readl(chanbase + D40_CHAN_REG_SDLNK); } else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { - event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); status = readl(chanbase + D40_CHAN_REG_SSLNK); } else { chan_err(d40c, "Unknown direction\n"); @@ -2308,9 +2277,9 @@ d40_get_dev_addr(struct d40_chan *chan, enum dma_transfer_direction direction) return chan->runtime_addr; if (direction == DMA_DEV_TO_MEM) - addr = plat->dev_rx[cfg->src_dev_type]; + addr = plat->dev_rx[cfg->dev_type]; else if (direction == DMA_MEM_TO_DEV) - addr = plat->dev_tx[cfg->dst_dev_type]; + addr = plat->dev_tx[cfg->dev_type]; return addr; } @@ -2441,11 +2410,11 @@ static void d40_set_prio_realtime(struct d40_chan *d40c) if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) - __d40_set_prio_rt(d40c, d40c->dma_cfg.src_dev_type, true); + __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, true); if ((d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH) || (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) - __d40_set_prio_rt(d40c, d40c->dma_cfg.dst_dev_type, false); + __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, false); } /* DMA ENGINE functions */ @@ -2489,10 +2458,10 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) d40c->lcpa = d40c->base->lcpa_base + - d40c->dma_cfg.src_dev_type * D40_LCPA_CHAN_SIZE; + d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE; else d40c->lcpa = d40c->base->lcpa_base + - d40c->dma_cfg.dst_dev_type * + d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA; } @@ -2755,7 +2724,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, if (config->direction == DMA_DEV_TO_MEM) { dma_addr_t dev_addr_rx = - d40c->base->plat_data->dev_rx[cfg->src_dev_type]; + d40c->base->plat_data->dev_rx[cfg->dev_type]; config_addr = config->src_addr; if (dev_addr_rx) @@ -2778,7 +2747,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, } else if (config->direction == DMA_MEM_TO_DEV) { dma_addr_t dev_addr_tx = - d40c->base->plat_data->dev_tx[cfg->dst_dev_type]; + d40c->base->plat_data->dev_tx[cfg->dev_type]; config_addr = config->dst_addr; if (dev_addr_tx) diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 7180e0d41722..5eb6c10beae1 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -63,7 +63,7 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { /* Set master port to 1 */ src |= 1 << D40_SREG_CFG_MST_POS; - src |= D40_TYPE_TO_EVENT(cfg->src_dev_type); + src |= D40_TYPE_TO_EVENT(cfg->dev_type); if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) src |= 1 << D40_SREG_CFG_PHY_TM_POS; @@ -74,7 +74,7 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { /* Set master port to 1 */ dst |= 1 << D40_SREG_CFG_MST_POS; - dst |= D40_TYPE_TO_EVENT(cfg->dst_dev_type); + dst |= D40_TYPE_TO_EVENT(cfg->dev_type); if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) dst |= 1 << D40_SREG_CFG_PHY_TM_POS; diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index 869c571c8c08..9e42a67d0cd5 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h @@ -109,8 +109,7 @@ struct stedma40_half_channel_info { * version 3+, i.e DB8500v2+ * @mode: channel mode: physical, logical, or operation * @mode_opt: options for the chosen channel mode - * @src_dev_type: Src device type - * @dst_dev_type: Dst device type + * @dev_type: src/dst device type (driver uses dir to figure out which) * @src_info: Parameters for dst half channel * @dst_info: Parameters for dst half channel * @use_fixed_channel: if true, use physical channel specified by phy_channel @@ -126,8 +125,7 @@ struct stedma40_chan_cfg { bool realtime; enum stedma40_mode mode; enum stedma40_mode_opt mode_opt; - int src_dev_type; - int dst_dev_type; + int dev_type; struct stedma40_half_channel_info src_info; struct stedma40_half_channel_info dst_info; -- cgit v1.2.3 From 84b3da1498943840005d7d5652caf4fe6fd333e6 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:31:58 +0100 Subject: dmaengine: ste_dma40: Remove home-brew MAX() macro The current implementation of the DMA40's local MAX() macro evaluates its arguments more times than is necessary and it not type checked. This patch strips replaces it with a new, more efficient constant. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Reported-by: Harvey Harrison Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 63495f6a36f9..367ef15a3cd8 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -53,8 +53,6 @@ #define D40_ALLOC_PHY (1 << 30) #define D40_ALLOC_LOG_FREE 0 -#define MAX(a, b) (((a) < (b)) ? (b) : (a)) - /* Reserved event lines for memcpy only. */ #define DB8500_DMA_MEMCPY_EV_0 51 #define DB8500_DMA_MEMCPY_EV_1 56 @@ -216,6 +214,9 @@ static u32 d40_backup_regs_chan[] = { D40_CHAN_REG_SDLNK, }; +#define BACKUP_REGS_SZ_MAX ((BACKUP_REGS_SZ_V4A > BACKUP_REGS_SZ_V4B) ? \ + BACKUP_REGS_SZ_V4A : BACKUP_REGS_SZ_V4B) + /** * struct d40_interrupt_lookup - lookup table for interrupt handler * @@ -579,7 +580,7 @@ struct d40_base { resource_size_t lcpa_size; struct kmem_cache *desc_slab; u32 reg_val_backup[BACKUP_REGS_SZ]; - u32 reg_val_backup_v4[MAX(BACKUP_REGS_SZ_V4A, BACKUP_REGS_SZ_V4B)]; + u32 reg_val_backup_v4[BACKUP_REGS_SZ_MAX]; u32 *reg_val_backup_chan; u16 gcc_pwr_off_mask; bool initialized; -- cgit v1.2.3 From db72da92103e3023e6a4fdfe65183b21bfe5d883 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:32:03 +0100 Subject: dmaengine: ste_dma40: Calculate number of logical channels from physical ones This change will cost ~25KB of memory, but it's worth the trade-off, as it removes a great deal of overhead. It means that instead of only allocating memory for the logical channels in use, it does so for all available ones, which is 32 per physical channel. However, this now means we can remove some platform data and we don't have to worry about adding vendor specific variables to Device Tree. Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/devices-db8500.c | 1 - drivers/dma/ste_dma40.c | 16 ++++++---------- include/linux/platform_data/dma-ste-dma40.h | 2 -- 3 files changed, 6 insertions(+), 13 deletions(-) (limited to 'drivers/dma') diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 7989c564e47a..130f3d9917e7 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -121,7 +121,6 @@ static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = { }; static struct stedma40_platform_data dma40_plat_data = { - .dev_len = DB8500_DMA_NR_DEV, .dev_rx = dma40_rx_map, .dev_tx = dma40_tx_map, .disabled_channels = {-1}, diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 367ef15a3cd8..f25c9ccf28e8 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -45,6 +45,9 @@ #define D40_LCLA_LINK_PER_EVENT_GRP 128 #define D40_LCLA_END D40_LCLA_LINK_PER_EVENT_GRP +/* Max number of logical channels per physical channel */ +#define D40_MAX_LOG_CHAN_PER_PHY 32 + /* Attempts before giving up to trying to get pages that are aligned */ #define MAX_LCLA_ALLOC_ATTEMPTS 256 @@ -3210,6 +3213,8 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) else num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; + num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; + dev_info(&pdev->dev, "hardware revision: %d @ 0x%x with %d physical channels\n", rev, res->start, num_phy_chans); @@ -3219,15 +3224,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) goto failure; } - /* Count the number of logical channels in use */ - for (i = 0; i < plat_data->dev_len; i++) - if (plat_data->dev_rx[i] != 0) - num_log_chans++; - - for (i = 0; i < plat_data->dev_len; i++) - if (plat_data->dev_tx[i] != 0) - num_log_chans++; - base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) * sizeof(struct d40_chan), GFP_KERNEL); @@ -3295,7 +3291,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) * The max number of logical channels are event lines for all * src devices and dst devices */ - base->lookup_log_chans = kzalloc(plat_data->dev_len * 2 * + base->lookup_log_chans = kzalloc(num_log_chans * sizeof(struct d40_chan *), GFP_KERNEL); if (!base->lookup_log_chans) diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index 9e42a67d0cd5..c54af61c9e48 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h @@ -136,7 +136,6 @@ struct stedma40_chan_cfg { /** * struct stedma40_platform_data - Configuration struct for the dma device. * - * @dev_len: length of dev_tx and dev_rx * @dev_tx: mapping between destination event line and io address * @dev_rx: mapping between source event line and io address * @disabled_channels: A vector, ending with -1, that marks physical channels @@ -153,7 +152,6 @@ struct stedma40_chan_cfg { * for 'multiple of 4' channels, like 8. */ struct stedma40_platform_data { - u32 dev_len; const dma_addr_t *dev_tx; const dma_addr_t *dev_rx; int disabled_channels[STEDMA40_MAX_PHYS]; -- cgit v1.2.3 From 8a59fed39577d7313921a59dba8cc1711ae90da5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:32:04 +0100 Subject: dmaengine: ste_dma40: Remove 'always true' checking Before allocating memory for logical channels, the current driver checks to see if there are any. Well as the dma40_memcpy_channels[] array is always populated, the check is always true. Best to remove the check. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index f25c9ccf28e8..7ccb8e2d59be 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3286,17 +3286,11 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) if (!base->lookup_phy_chans) goto failure; - if (num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) { - /* - * The max number of logical channels are event lines for all - * src devices and dst devices - */ - base->lookup_log_chans = kzalloc(num_log_chans * - sizeof(struct d40_chan *), - GFP_KERNEL); - if (!base->lookup_log_chans) - goto failure; - } + base->lookup_log_chans = kzalloc(num_log_chans * + sizeof(struct d40_chan *), + GFP_KERNEL); + if (!base->lookup_log_chans) + goto failure; base->reg_val_backup_chan = kmalloc(base->num_phy_chans * sizeof(d40_backup_regs_chan), -- cgit v1.2.3 From 8b2fe9b6b310a6e5d68de648d6f0697227581d66 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:32:08 +0100 Subject: dmaengine: ste_dma40: Move rev error-check up to revision acquisition At the moment we fetch the hardware revision, then do some stuff, then check whether the revision is correct and return in error if it's not. Well we may as well check it as soon as we know what it is, so let's move the check right up underneath where we acquire the version. Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 7ccb8e2d59be..fb79db3313d3 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3204,6 +3204,10 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) * DB8540v1 has revision 4 */ rev = AMBA_REV_BITS(pid); + if (rev < 2) { + d40_err(&pdev->dev, "hardware revision: %d is not supported", rev); + goto failure; + } plat_data = pdev->dev.platform_data; @@ -3218,12 +3222,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) dev_info(&pdev->dev, "hardware revision: %d @ 0x%x with %d physical channels\n", rev, res->start, num_phy_chans); - if (rev < 2) { - d40_err(&pdev->dev, "hardware revision: %d is not supported", - rev); - goto failure; - } - base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) * sizeof(struct d40_chan), GFP_KERNEL); -- cgit v1.2.3 From b2abb249de5ffca71ade8b79c9969e046fc03722 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:32:09 +0100 Subject: dmaengine: ste_dma40: Also report the number of logical channels Now we know the total of physical and logical channels, we may as well report them within the information log. Before: dma40 dma40.0: hardware revision: 3 @ 0x801c0000 with 8 physical channels After: and 256 logical channels Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index fb79db3313d3..665541df5798 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3219,8 +3219,9 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; - dev_info(&pdev->dev, "hardware revision: %d @ 0x%x with %d physical channels\n", - rev, res->start, num_phy_chans); + dev_info(&pdev->dev, + "hardware rev: %d @ 0x%x with %d physical and %d logical channels\n", + rev, res->start, num_phy_chans, num_log_chans); base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) * -- cgit v1.2.3 From bb75d93b903afcd0904c83850835857fd9f8ef2d Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:32:10 +0100 Subject: dmaengine: ste_dma40: Allocate plat_data on declaration It's the way that most other drivers do it. Very trivial clean-up which reduces line count and simplifies code. Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 665541df5798..925cdbe08c2e 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3138,7 +3138,7 @@ static int __init d40_phy_res_init(struct d40_base *base) static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) { - struct stedma40_platform_data *plat_data; + struct stedma40_platform_data *plat_data = pdev->dev.platform_data; struct clk *clk = NULL; void __iomem *virtbase = NULL; struct resource *res = NULL; @@ -3209,8 +3209,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) goto failure; } - plat_data = pdev->dev.platform_data; - /* The number of physical channels on this HW */ if (plat_data->num_of_phy_chans) num_phy_chans = plat_data->num_of_phy_chans; -- cgit v1.2.3 From 1814a1703ce2d6d4b88b5f62a52b137afebad990 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:32:11 +0100 Subject: dmaengine: ste_dma40: Allow driver to be probe()able when DT is enabled When booting using Device Tree, devices aren't registered in the normal way. Instead, they need to be provided with a compatible string which is held in an OF Match Table for comparison during start-up. Here we provide the compatible string and prepare the driver to not receive a platform data pointer. Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones [Fixed up whitespace error] Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 925cdbe08c2e..495e8869b9b0 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -3471,17 +3472,52 @@ failure: return ret; } +static int __init d40_of_probe(struct platform_device *pdev, + struct device_node *np) +{ + struct stedma40_platform_data *pdata; + + /* + * FIXME: Fill in this routine as more support is added. + * First platform enabled (u8500) doens't need any extra + * properties to run, so this is fairly sparce currently. + */ + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct stedma40_platform_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdev->dev.platform_data = pdata; + + return 0; +} + static int __init d40_probe(struct platform_device *pdev) { + struct stedma40_platform_data *plat_data = pdev->dev.platform_data; + struct device_node *np = pdev->dev.of_node; int err; int ret = -ENOENT; - struct d40_base *base; + struct d40_base *base = NULL; struct resource *res = NULL; int num_reserved_chans; u32 val; - base = d40_hw_detect_init(pdev); + if (!plat_data) { + if (np) { + if(d40_of_probe(pdev, np)) { + ret = -ENOMEM; + goto failure; + } + } else { + d40_err(&pdev->dev, "No pdata or Device Tree provided\n"); + goto failure; + } + } + base = d40_hw_detect_init(pdev); if (!base) goto failure; @@ -3655,11 +3691,17 @@ failure: return ret; } +static const struct of_device_id d40_match[] = { + { .compatible = "stericsson,dma40", }, + {} +}; + static struct platform_driver d40_driver = { .driver = { .owner = THIS_MODULE, .name = D40_NAME, .pm = DMA40_PM_OPS, + .of_match_table = d40_match, }, }; -- cgit v1.2.3 From fa332de5c6b3891485798adfe3252125457e5377 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 May 2013 15:32:12 +0100 Subject: dmaengine: ste_dma40: Supply full Device Tree parsing support Using the new DMA DT bindings and API, we can register the DMA40 driver as Device Tree capable. Now, when a client attempts to allocate a channel using the DMA DT bindings via its own node, we are able to parse the request and allocate a channel in the correct manner. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Cc: Rob Herring Cc: devicetree-discuss@lists.ozlabs.org Acked-by: Vinod Koul Reviewed-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- .../devicetree/bindings/dma/ste-dma40.txt | 62 ++++++++++++++++++++++ drivers/dma/ste_dma40.c | 52 ++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/ste-dma40.txt (limited to 'drivers/dma') diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt new file mode 100644 index 000000000000..2679a873522d --- /dev/null +++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt @@ -0,0 +1,62 @@ +* DMA40 DMA Controller + +Required properties: +- compatible: "stericsson,dma40" +- reg: Address range of the DMAC registers +- reg-names: Names of the above areas to use during resource look-up +- interrupt: Should contain the DMAC interrupt number +- #dma-cells: must be <3> + +Optional properties: +- dma-channels: Number of channels supported by hardware - if not present + the driver will attempt to obtain the information from H/W + +Example: + + dma: dma-controller@801C0000 { + compatible = "stericsson,db8500-dma40", "stericsson,dma40"; + reg = <0x801C0000 0x1000 0x40010000 0x800>; + reg-names = "base", "lcpa"; + interrupt-parent = <&intc>; + interrupts = <0 25 0x4>; + + #dma-cells = <2>; + dma-channels = <8>; + }; + +Clients +Required properties: +- dmas: Comma separated list of dma channel requests +- dma-names: Names of the aforementioned requested channels + +Each dmas request consists of 4 cells: + 1. A phandle pointing to the DMA controller + 2. Device Type + 3. The DMA request line number (only when 'use fixed channel' is set) + 4. A 32bit mask specifying; mode, direction and endianess [NB: This list will grow] + 0x00000001: Mode: + Logical channel when unset + Physical channel when set + 0x00000002: Direction: + Memory to Device when unset + Device to Memory when set + 0x00000004: Endianess: + Little endian when unset + Big endian when set + 0x00000008: Use fixed channel: + Use automatic channel selection when unset + Use DMA request line number when set + +Example: + + uart@80120000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x80120000 0x1000>; + interrupts = <0 11 0x4>; + + dmas = <&dma 13 0 0x2>, /* Logical - DevToMem */ + <&dma 13 0 0x0>; /* Logical - MemToDev */ + dma-names = "rx", "rx"; + + status = "disabled"; + }; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 495e8869b9b0..5e9f6d670891 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -2422,6 +2423,50 @@ static void d40_set_prio_realtime(struct d40_chan *d40c) __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, false); } +#define D40_DT_FLAGS_MODE(flags) ((flags >> 0) & 0x1) +#define D40_DT_FLAGS_DIR(flags) ((flags >> 1) & 0x1) +#define D40_DT_FLAGS_BIG_ENDIAN(flags) ((flags >> 2) & 0x1) +#define D40_DT_FLAGS_FIXED_CHAN(flags) ((flags >> 3) & 0x1) + +static struct dma_chan *d40_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) +{ + struct stedma40_chan_cfg cfg; + dma_cap_mask_t cap; + u32 flags; + + memset(&cfg, 0, sizeof(struct stedma40_chan_cfg)); + + dma_cap_zero(cap); + dma_cap_set(DMA_SLAVE, cap); + + cfg.dev_type = dma_spec->args[0]; + flags = dma_spec->args[2]; + + switch (D40_DT_FLAGS_MODE(flags)) { + case 0: cfg.mode = STEDMA40_MODE_LOGICAL; break; + case 1: cfg.mode = STEDMA40_MODE_PHYSICAL; break; + } + + switch (D40_DT_FLAGS_DIR(flags)) { + case 0: + cfg.dir = STEDMA40_MEM_TO_PERIPH; + cfg.dst_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); + break; + case 1: + cfg.dir = STEDMA40_PERIPH_TO_MEM; + cfg.src_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); + break; + } + + if (D40_DT_FLAGS_FIXED_CHAN(flags)) { + cfg.phy_channel = dma_spec->args[1]; + cfg.use_fixed_channel = true; + } + + return dma_request_channel(cap, stedma40_filter, &cfg); +} + /* DMA ENGINE functions */ static int d40_alloc_chan_resources(struct dma_chan *chan) { @@ -3638,6 +3683,13 @@ static int __init d40_probe(struct platform_device *pdev) d40_hw_init(base); + if (np) { + err = of_dma_controller_register(np, d40_xlate, NULL); + if (err && err != -ENODEV) + dev_err(&pdev->dev, + "could not register of_dma_controller\n"); + } + dev_info(base->dev, "initialized\n"); return 0; -- cgit v1.2.3 From 9778256b9810d2c758a7537a43825b7d81b5765f Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:24 +0100 Subject: dmaengine: ste_dma40: Separate Logical Global Interrupt Mask (GIM) unmasking During the initial setup of a logical channel, it is necessary to unmask the GIM in order to receive generated terminal count and error interrupts. We're separating out this required code so it will be possible to move the remaining code in d40_phy_cfg(), which is mostly runtime configuration into the runtime_config() routine. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 4 ++++ drivers/dma/ste_dma40_ll.c | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 5e9f6d670891..759293e4a1cc 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2513,6 +2513,10 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) d40c->lcpa = d40c->base->lcpa_base + d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA; + + /* Unmask the Global Interrupt Mask. */ + d40c->src_def_cfg |= BIT(D40_SREG_CFG_LOG_GIM_POS); + d40c->dst_def_cfg |= BIT(D40_SREG_CFG_LOG_GIM_POS); } dev_dbg(chan2dev(d40c), "allocated %s channel (phy %d%s)\n", diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 5eb6c10beae1..435a223c891f 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -107,11 +107,6 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, src |= 1 << D40_SREG_CFG_PRI_POS; dst |= 1 << D40_SREG_CFG_PRI_POS; } - - } else { - /* Logical channel */ - dst |= 1 << D40_SREG_CFG_LOG_GIM_POS; - src |= 1 << D40_SREG_CFG_LOG_GIM_POS; } if (cfg->src_info.big_endian) -- cgit v1.2.3 From 57e65ad77fef1b026f5bdf1cd417bb6346b24fdf Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:25 +0100 Subject: dmaengine: ste_dma40: Remove unnecessary call to d40_phy_cfg() The majority of configuration done in d40_phy_config() pertains to physical channels. Move the call over to runtime config which has different code paths for physical and logical channels already, and make it an exclusive physical channel config function as the name implies, and drop the is_log argument. Since we moved the call to runtime_config() it only gets called for device transfers, so encode the small snippet of configuration pertaining to memcpy channels into the d40_config_memcpy() function. Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones [rewrote the commit message] Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 14 ++++--- drivers/dma/ste_dma40_ll.c | 101 +++++++++++++++++++++------------------------ drivers/dma/ste_dma40_ll.h | 3 +- 3 files changed, 58 insertions(+), 60 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 759293e4a1cc..b7fe46bd6a8e 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2043,6 +2043,14 @@ static int d40_config_memcpy(struct d40_chan *d40c) } else if (dma_has_cap(DMA_MEMCPY, cap) && dma_has_cap(DMA_SLAVE, cap)) { d40c->dma_cfg = dma40_memcpy_conf_phy; + + /* Generate interrrupt at end of transfer or relink. */ + d40c->dst_def_cfg |= BIT(D40_SREG_CFG_TIM_POS); + + /* Generate interrupt on error. */ + d40c->src_def_cfg |= BIT(D40_SREG_CFG_EIM_POS); + d40c->dst_def_cfg |= BIT(D40_SREG_CFG_EIM_POS); + } else { chan_err(d40c, "No memcpy\n"); return -EINVAL; @@ -2496,9 +2504,6 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) } pm_runtime_get_sync(d40c->base->dev); - /* Fill in basic CFG register values */ - d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg, - &d40c->dst_def_cfg, chan_is_logical(d40c)); d40_set_prio_realtime(d40c); @@ -2862,8 +2867,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, if (chan_is_logical(d40c)) d40_log_cfg(cfg, &d40c->log_def.lcsp1, &d40c->log_def.lcsp3); else - d40_phy_cfg(cfg, &d40c->src_def_cfg, - &d40c->dst_def_cfg, false); + d40_phy_cfg(cfg, &d40c->src_def_cfg, &d40c->dst_def_cfg); /* These settings will take precedence later */ d40c->runtime_addr = config_addr; diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 435a223c891f..ab5a2a706f7a 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -50,63 +50,58 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg, } -/* Sets up SRC and DST CFG register for both logical and physical channels */ -void d40_phy_cfg(struct stedma40_chan_cfg *cfg, - u32 *src_cfg, u32 *dst_cfg, bool is_log) +void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) { u32 src = 0; u32 dst = 0; - if (!is_log) { - /* Physical channel */ - if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || - (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { - /* Set master port to 1 */ - src |= 1 << D40_SREG_CFG_MST_POS; - src |= D40_TYPE_TO_EVENT(cfg->dev_type); - - if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) - src |= 1 << D40_SREG_CFG_PHY_TM_POS; - else - src |= 3 << D40_SREG_CFG_PHY_TM_POS; - } - if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || - (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { - /* Set master port to 1 */ - dst |= 1 << D40_SREG_CFG_MST_POS; - dst |= D40_TYPE_TO_EVENT(cfg->dev_type); - - if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) - dst |= 1 << D40_SREG_CFG_PHY_TM_POS; - else - dst |= 3 << D40_SREG_CFG_PHY_TM_POS; - } - /* Interrupt on end of transfer for destination */ - dst |= 1 << D40_SREG_CFG_TIM_POS; - - /* Generate interrupt on error */ - src |= 1 << D40_SREG_CFG_EIM_POS; - dst |= 1 << D40_SREG_CFG_EIM_POS; - - /* PSIZE */ - if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { - src |= 1 << D40_SREG_CFG_PHY_PEN_POS; - src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; - } - if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { - dst |= 1 << D40_SREG_CFG_PHY_PEN_POS; - dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; - } - - /* Element size */ - src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; - dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; - - /* Set the priority bit to high for the physical channel */ - if (cfg->high_priority) { - src |= 1 << D40_SREG_CFG_PRI_POS; - dst |= 1 << D40_SREG_CFG_PRI_POS; - } + if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || + (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + /* Set master port to 1 */ + src |= 1 << D40_SREG_CFG_MST_POS; + src |= D40_TYPE_TO_EVENT(cfg->dev_type); + + if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) + src |= 1 << D40_SREG_CFG_PHY_TM_POS; + else + src |= 3 << D40_SREG_CFG_PHY_TM_POS; + } + if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || + (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + /* Set master port to 1 */ + dst |= 1 << D40_SREG_CFG_MST_POS; + dst |= D40_TYPE_TO_EVENT(cfg->dev_type); + + if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) + dst |= 1 << D40_SREG_CFG_PHY_TM_POS; + else + dst |= 3 << D40_SREG_CFG_PHY_TM_POS; + } + /* Interrupt on end of transfer for destination */ + dst |= 1 << D40_SREG_CFG_TIM_POS; + + /* Generate interrupt on error */ + src |= 1 << D40_SREG_CFG_EIM_POS; + dst |= 1 << D40_SREG_CFG_EIM_POS; + + /* PSIZE */ + if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { + src |= 1 << D40_SREG_CFG_PHY_PEN_POS; + src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; + } + if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { + dst |= 1 << D40_SREG_CFG_PHY_PEN_POS; + dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; + } + + /* Element size */ + src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; + dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; + + /* Set the priority bit to high for the physical channel */ + if (cfg->high_priority) { + src |= 1 << D40_SREG_CFG_PRI_POS; + dst |= 1 << D40_SREG_CFG_PRI_POS; } if (cfg->src_info.big_endian) diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h index fdde8ef77542..1b47312bc574 100644 --- a/drivers/dma/ste_dma40_ll.h +++ b/drivers/dma/ste_dma40_ll.h @@ -432,8 +432,7 @@ enum d40_lli_flags { void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, - u32 *dst_cfg, - bool is_log); + u32 *dst_cfg); void d40_log_cfg(struct stedma40_chan_cfg *cfg, u32 *lcsp1, -- cgit v1.2.3 From 9b233f9b2e927a93b3dc8b8e9c1d59f79be13dcc Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:26 +0100 Subject: dmaengine: ste_dma40: Don't configure runtime configurable setup during allocate Using the dmaengine API for slave transfers, allocating and configuring a channel are two separate actions. Here we're removing logical channel configuration from the channel allocation routine for slave transfers, as the same config is already done in the runtime config function, and put the corresponding call into d40_config_memcpy() for the memcpy code path. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones [Edited the commit message] Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index b7fe46bd6a8e..ba84df8fc9d8 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2040,6 +2040,9 @@ static int d40_config_memcpy(struct d40_chan *d40c) d40c->dma_cfg = dma40_memcpy_conf_log; d40c->dma_cfg.dev_type = dma40_memcpy_channels[d40c->chan.chan_id]; + d40_log_cfg(&d40c->dma_cfg, + &d40c->log_def.lcsp1, &d40c->log_def.lcsp3); + } else if (dma_has_cap(DMA_MEMCPY, cap) && dma_has_cap(DMA_SLAVE, cap)) { d40c->dma_cfg = dma40_memcpy_conf_phy; @@ -2508,9 +2511,6 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) d40_set_prio_realtime(d40c); if (chan_is_logical(d40c)) { - d40_log_cfg(&d40c->dma_cfg, - &d40c->log_def.lcsp1, &d40c->log_def.lcsp3); - if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) d40c->lcpa = d40c->base->lcpa_base + d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE; -- cgit v1.2.3 From ef9c89b3ec6916dd0b7db1563d51d85af3e7f031 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:30 +0100 Subject: dmaengine: ste_dma40: Only use addresses passed as configuration information Addresses are passed in from the client's driver via the invocation of dmaengine_slave_config(), so there's no need to fetch them from platform data too, hardwired or otherwise. This is a great step forward, as it elevates a large burden from platform data in the way of a look-up table. Signed-off-by: Lee Jones Acked-by: Vinod Koul Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 51 +++++++++++-------------------------------------- 1 file changed, 11 insertions(+), 40 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index ba84df8fc9d8..57a127e5c896 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -1774,22 +1774,6 @@ static int d40_validate_conf(struct d40_chan *d40c, res = -EINVAL; } - if (conf->dir == STEDMA40_MEM_TO_PERIPH && - d40c->base->plat_data->dev_tx[conf->dev_type] == 0 && - d40c->runtime_addr == 0) { - chan_err(d40c, "Invalid TX channel address (%d)\n", - conf->dev_type); - res = -EINVAL; - } - - if (conf->dir == STEDMA40_PERIPH_TO_MEM && - d40c->base->plat_data->dev_rx[conf->dev_type] == 0 && - d40c->runtime_addr == 0) { - chan_err(d40c, "Invalid RX channel address (%d)\n", - conf->dev_type); - res = -EINVAL; - } - if (conf->dir == STEDMA40_PERIPH_TO_PERIPH) { /* * DMAC HW supports it. Will be added to this driver, @@ -2327,14 +2311,10 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src, if (sg_next(&sg_src[sg_len - 1]) == sg_src) desc->cyclic = true; - if (direction != DMA_TRANS_NONE) { - dma_addr_t dev_addr = d40_get_dev_addr(chan, direction); - - if (direction == DMA_DEV_TO_MEM) - src_dev_addr = dev_addr; - else if (direction == DMA_MEM_TO_DEV) - dst_dev_addr = dev_addr; - } + if (direction == DMA_DEV_TO_MEM) + src_dev_addr = chan->runtime_addr; + else if (direction == DMA_MEM_TO_DEV) + dst_dev_addr = chan->runtime_addr; if (chan_is_logical(chan)) ret = d40_prep_sg_log(chan, desc, sg_src, sg_dst, @@ -2782,15 +2762,8 @@ static int d40_set_runtime_config(struct dma_chan *chan, dst_maxburst = config->dst_maxburst; if (config->direction == DMA_DEV_TO_MEM) { - dma_addr_t dev_addr_rx = - d40c->base->plat_data->dev_rx[cfg->dev_type]; - config_addr = config->src_addr; - if (dev_addr_rx) - dev_dbg(d40c->base->dev, - "channel has a pre-wired RX address %08x " - "overriding with %08x\n", - dev_addr_rx, config_addr); + if (cfg->dir != STEDMA40_PERIPH_TO_MEM) dev_dbg(d40c->base->dev, "channel was not configured for peripheral " @@ -2805,15 +2778,8 @@ static int d40_set_runtime_config(struct dma_chan *chan, dst_maxburst = src_maxburst; } else if (config->direction == DMA_MEM_TO_DEV) { - dma_addr_t dev_addr_tx = - d40c->base->plat_data->dev_tx[cfg->dev_type]; - config_addr = config->dst_addr; - if (dev_addr_tx) - dev_dbg(d40c->base->dev, - "channel has a pre-wired TX address %08x " - "overriding with %08x\n", - dev_addr_tx, config_addr); + if (cfg->dir != STEDMA40_MEM_TO_PERIPH) dev_dbg(d40c->base->dev, "channel was not configured for memory " @@ -2833,6 +2799,11 @@ static int d40_set_runtime_config(struct dma_chan *chan, return -EINVAL; } + if (config_addr <= 0) { + dev_err(d40c->base->dev, "no address supplied\n"); + return -EINVAL; + } + if (src_maxburst * src_addr_width != dst_maxburst * dst_addr_width) { dev_err(d40c->base->dev, "src/dst width/maxburst mismatch: %d*%d != %d*%d\n", -- cgit v1.2.3 From 01c935c4ecbf6e67d8b7b8258c5eb3be84c248aa Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:31 +0100 Subject: dmaengine: ste_dma40: Remove redundant address fetching function Addresses are now stored in local data structures and are easy to obtain, thus a specialist function used to fetch them is now surplus to requirement. Signed-off-by: Lee Jones Acked-by: Vinod Koul Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 57a127e5c896..6ed775736853 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2267,24 +2267,6 @@ err: return NULL; } -static dma_addr_t -d40_get_dev_addr(struct d40_chan *chan, enum dma_transfer_direction direction) -{ - struct stedma40_platform_data *plat = chan->base->plat_data; - struct stedma40_chan_cfg *cfg = &chan->dma_cfg; - dma_addr_t addr = 0; - - if (chan->runtime_addr) - return chan->runtime_addr; - - if (direction == DMA_DEV_TO_MEM) - addr = plat->dev_rx[cfg->dev_type]; - else if (direction == DMA_MEM_TO_DEV) - addr = plat->dev_tx[cfg->dev_type]; - - return addr; -} - static struct dma_async_tx_descriptor * d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src, struct scatterlist *sg_dst, unsigned int sg_len, -- cgit v1.2.3 From 8a3b6e143c3aa31fab4a820105e91e1cdb17ad42 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:52 +0100 Subject: dmaengine: ste_dma40: Use the BIT macro to replace ugly '(1 << x)'s The aim is to make the code that little more readable. Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 6ed775736853..08bc58ae4ceb 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -54,8 +54,8 @@ #define MAX_LCLA_ALLOC_ATTEMPTS 256 /* Bit markings for allocation map */ -#define D40_ALLOC_FREE (1 << 31) -#define D40_ALLOC_PHY (1 << 30) +#define D40_ALLOC_FREE BIT(31) +#define D40_ALLOC_PHY BIT(30) #define D40_ALLOC_LOG_FREE 0 /* Reserved event lines for memcpy only. */ @@ -1738,7 +1738,7 @@ static irqreturn_t d40_handle_interrupt(int irq, void *data) } /* ACK interrupt */ - writel(1 << idx, base->virtbase + il[row].clr); + writel(BIT(idx), base->virtbase + il[row].clr); spin_lock(&d40c->lock); @@ -1828,8 +1828,8 @@ static bool d40_alloc_mask_set(struct d40_phy_res *phy, if (phy->allocated_src == D40_ALLOC_FREE) phy->allocated_src = D40_ALLOC_LOG_FREE; - if (!(phy->allocated_src & (1 << log_event_line))) { - phy->allocated_src |= 1 << log_event_line; + if (!(phy->allocated_src & BIT(log_event_line))) { + phy->allocated_src |= BIT(log_event_line); goto found; } else goto not_found; @@ -1840,8 +1840,8 @@ static bool d40_alloc_mask_set(struct d40_phy_res *phy, if (phy->allocated_dst == D40_ALLOC_FREE) phy->allocated_dst = D40_ALLOC_LOG_FREE; - if (!(phy->allocated_dst & (1 << log_event_line))) { - phy->allocated_dst |= 1 << log_event_line; + if (!(phy->allocated_dst & BIT(log_event_line))) { + phy->allocated_dst |= BIT(log_event_line); goto found; } else goto not_found; @@ -1871,11 +1871,11 @@ static bool d40_alloc_mask_free(struct d40_phy_res *phy, bool is_src, /* Logical channel */ if (is_src) { - phy->allocated_src &= ~(1 << log_event_line); + phy->allocated_src &= ~BIT(log_event_line); if (phy->allocated_src == D40_ALLOC_LOG_FREE) phy->allocated_src = D40_ALLOC_FREE; } else { - phy->allocated_dst &= ~(1 << log_event_line); + phy->allocated_dst &= ~BIT(log_event_line); if (phy->allocated_dst == D40_ALLOC_LOG_FREE) phy->allocated_dst = D40_ALLOC_FREE; } @@ -2356,7 +2356,7 @@ static void __d40_set_prio_rt(struct d40_chan *d40c, int dev_type, bool src) u32 rtreg; u32 event = D40_TYPE_TO_EVENT(dev_type); u32 group = D40_TYPE_TO_GROUP(dev_type); - u32 bit = 1 << event; + u32 bit = BIT(event); u32 prioreg; struct d40_gen_dmac *dmac = &d40c->base->gen_dmac; -- cgit v1.2.3 From 2c2b62d5d911da10c0fc37c31458baf4047d531c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:54 +0100 Subject: dmaengine: ste_dma40: Replace ST-E's home-brew DMA direction defs with generic ones STEDMA40_*_TO_* direction definitions are identical in all but name to the pre-defined generic DMA_*_TO_* ones. Let's make things easy by not duplicating such things. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 56 +++++++++++++++++++++++----------------------- drivers/dma/ste_dma40_ll.c | 24 ++++++++++---------- 2 files changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 08bc58ae4ceb..483da1660eae 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -78,7 +78,7 @@ static int dma40_memcpy_channels[] = { /* Default configuration for physcial memcpy */ struct stedma40_chan_cfg dma40_memcpy_conf_phy = { .mode = STEDMA40_MODE_PHYSICAL, - .dir = STEDMA40_MEM_TO_MEM, + .dir = DMA_MEM_TO_MEM, .src_info.data_width = STEDMA40_BYTE_WIDTH, .src_info.psize = STEDMA40_PSIZE_PHY_1, @@ -92,7 +92,7 @@ struct stedma40_chan_cfg dma40_memcpy_conf_phy = { /* Default configuration for logical memcpy */ struct stedma40_chan_cfg dma40_memcpy_conf_log = { .mode = STEDMA40_MODE_LOGICAL, - .dir = STEDMA40_MEM_TO_MEM, + .dir = DMA_MEM_TO_MEM, .src_info.data_width = STEDMA40_BYTE_WIDTH, .src_info.psize = STEDMA40_PSIZE_LOG_1, @@ -843,7 +843,7 @@ static void d40_log_lli_to_lcxa(struct d40_chan *chan, struct d40_desc *desc) * that uses linked lists. */ if (!(chan->phy_chan->use_soft_lli && - chan->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)) + chan->dma_cfg.dir == DMA_DEV_TO_MEM)) curr_lcla = d40_lcla_alloc_one(chan, desc); first_lcla = curr_lcla; @@ -1311,12 +1311,12 @@ static void d40_config_set_event(struct d40_chan *d40c, u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type); /* Enable event line connected to device (or memcpy) */ - if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || - (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) + if ((d40c->dma_cfg.dir == DMA_DEV_TO_MEM) || + (d40c->dma_cfg.dir == DMA_DEV_TO_DEV)) __d40_config_set_event(d40c, event_type, event, D40_CHAN_REG_SSLNK); - if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) + if (d40c->dma_cfg.dir != DMA_DEV_TO_MEM) __d40_config_set_event(d40c, event_type, event, D40_CHAN_REG_SDLNK); } @@ -1774,7 +1774,7 @@ static int d40_validate_conf(struct d40_chan *d40c, res = -EINVAL; } - if (conf->dir == STEDMA40_PERIPH_TO_PERIPH) { + if (conf->dir == DMA_DEV_TO_DEV) { /* * DMAC HW supports it. Will be added to this driver, * in case any dma client requires it. @@ -1905,11 +1905,11 @@ static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user) phys = d40c->base->phy_res; num_phy_chans = d40c->base->num_phy_chans; - if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { + if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) { log_num = 2 * dev_type; is_src = true; - } else if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || - d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + } else if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV || + d40c->dma_cfg.dir == DMA_MEM_TO_MEM) { /* dst event lines are used for logical memcpy */ log_num = 2 * dev_type + 1; is_src = false; @@ -1920,7 +1920,7 @@ static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user) event_line = D40_TYPE_TO_EVENT(dev_type); if (!is_log) { - if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + if (d40c->dma_cfg.dir == DMA_MEM_TO_MEM) { /* Find physical half channel */ if (d40c->dma_cfg.use_fixed_channel) { i = d40c->dma_cfg.phy_channel; @@ -2068,10 +2068,10 @@ static int d40_free_dma(struct d40_chan *d40c) return -EINVAL; } - if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || - d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) + if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV || + d40c->dma_cfg.dir == DMA_MEM_TO_MEM) is_src = false; - else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) + else if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) is_src = true; else { chan_err(d40c, "Unknown direction\n"); @@ -2133,10 +2133,10 @@ static bool d40_is_paused(struct d40_chan *d40c) goto _exit; } - if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || - d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV || + d40c->dma_cfg.dir == DMA_MEM_TO_MEM) { status = readl(chanbase + D40_CHAN_REG_SDLNK); - } else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { + } else if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) { status = readl(chanbase + D40_CHAN_REG_SSLNK); } else { chan_err(d40c, "Unknown direction\n"); @@ -2387,12 +2387,12 @@ static void d40_set_prio_realtime(struct d40_chan *d40c) if (d40c->base->rev < 3) return; - if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || - (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) + if ((d40c->dma_cfg.dir == DMA_DEV_TO_MEM) || + (d40c->dma_cfg.dir == DMA_DEV_TO_DEV)) __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, true); - if ((d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH) || - (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) + if ((d40c->dma_cfg.dir == DMA_MEM_TO_DEV) || + (d40c->dma_cfg.dir == DMA_DEV_TO_DEV)) __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, false); } @@ -2423,11 +2423,11 @@ static struct dma_chan *d40_xlate(struct of_phandle_args *dma_spec, switch (D40_DT_FLAGS_DIR(flags)) { case 0: - cfg.dir = STEDMA40_MEM_TO_PERIPH; + cfg.dir = DMA_MEM_TO_DEV; cfg.dst_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); break; case 1: - cfg.dir = STEDMA40_PERIPH_TO_MEM; + cfg.dir = DMA_DEV_TO_MEM; cfg.src_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); break; } @@ -2473,7 +2473,7 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) d40_set_prio_realtime(d40c); if (chan_is_logical(d40c)) { - if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) + if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) d40c->lcpa = d40c->base->lcpa_base + d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE; else @@ -2746,12 +2746,12 @@ static int d40_set_runtime_config(struct dma_chan *chan, if (config->direction == DMA_DEV_TO_MEM) { config_addr = config->src_addr; - if (cfg->dir != STEDMA40_PERIPH_TO_MEM) + if (cfg->dir != DMA_DEV_TO_MEM) dev_dbg(d40c->base->dev, "channel was not configured for peripheral " "to memory transfer (%d) overriding\n", cfg->dir); - cfg->dir = STEDMA40_PERIPH_TO_MEM; + cfg->dir = DMA_DEV_TO_MEM; /* Configure the memory side */ if (dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) @@ -2762,12 +2762,12 @@ static int d40_set_runtime_config(struct dma_chan *chan, } else if (config->direction == DMA_MEM_TO_DEV) { config_addr = config->dst_addr; - if (cfg->dir != STEDMA40_MEM_TO_PERIPH) + if (cfg->dir != DMA_MEM_TO_DEV) dev_dbg(d40c->base->dev, "channel was not configured for memory " "to peripheral transfer (%d) overriding\n", cfg->dir); - cfg->dir = STEDMA40_MEM_TO_PERIPH; + cfg->dir = DMA_MEM_TO_DEV; /* Configure the memory side */ if (src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index ab5a2a706f7a..121c0cec4614 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -18,23 +18,23 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg, u32 l1 = 0; /* src */ /* src is mem? -> increase address pos */ - if (cfg->dir == STEDMA40_MEM_TO_PERIPH || - cfg->dir == STEDMA40_MEM_TO_MEM) + if (cfg->dir == DMA_MEM_TO_DEV || + cfg->dir == DMA_MEM_TO_MEM) l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS; /* dst is mem? -> increase address pos */ - if (cfg->dir == STEDMA40_PERIPH_TO_MEM || - cfg->dir == STEDMA40_MEM_TO_MEM) + if (cfg->dir == DMA_DEV_TO_MEM || + cfg->dir == DMA_MEM_TO_MEM) l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS; /* src is hw? -> master port 1 */ - if (cfg->dir == STEDMA40_PERIPH_TO_MEM || - cfg->dir == STEDMA40_PERIPH_TO_PERIPH) + if (cfg->dir == DMA_DEV_TO_MEM || + cfg->dir == DMA_DEV_TO_DEV) l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS; /* dst is hw? -> master port 1 */ - if (cfg->dir == STEDMA40_MEM_TO_PERIPH || - cfg->dir == STEDMA40_PERIPH_TO_PERIPH) + if (cfg->dir == DMA_MEM_TO_DEV || + cfg->dir == DMA_DEV_TO_DEV) l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS; l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS; @@ -55,8 +55,8 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) u32 src = 0; u32 dst = 0; - if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || - (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + if ((cfg->dir == DMA_DEV_TO_MEM) || + (cfg->dir == DMA_DEV_TO_DEV)) { /* Set master port to 1 */ src |= 1 << D40_SREG_CFG_MST_POS; src |= D40_TYPE_TO_EVENT(cfg->dev_type); @@ -66,8 +66,8 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) else src |= 3 << D40_SREG_CFG_PHY_TM_POS; } - if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || - (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + if ((cfg->dir == DMA_MEM_TO_DEV) || + (cfg->dir == DMA_DEV_TO_DEV)) { /* Set master port to 1 */ dst |= 1 << D40_SREG_CFG_MST_POS; dst |= D40_TYPE_TO_EVENT(cfg->dev_type); -- cgit v1.2.3 From 16db3411ebd4777b0b1b7207b10730b726fb751c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:56 +0100 Subject: dmaengine: ste_dma40_ll: Use the BIT macro to replace ugly '(1 << x)'s The aim is to make the code that little more readable. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40_ll.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 121c0cec4614..5ddd724dcdc5 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -20,28 +20,28 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg, /* src is mem? -> increase address pos */ if (cfg->dir == DMA_MEM_TO_DEV || cfg->dir == DMA_MEM_TO_MEM) - l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS; + l1 |= BIT(D40_MEM_LCSP1_SCFG_INCR_POS); /* dst is mem? -> increase address pos */ if (cfg->dir == DMA_DEV_TO_MEM || cfg->dir == DMA_MEM_TO_MEM) - l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS; + l3 |= BIT(D40_MEM_LCSP3_DCFG_INCR_POS); /* src is hw? -> master port 1 */ if (cfg->dir == DMA_DEV_TO_MEM || cfg->dir == DMA_DEV_TO_DEV) - l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS; + l1 |= BIT(D40_MEM_LCSP1_SCFG_MST_POS); /* dst is hw? -> master port 1 */ if (cfg->dir == DMA_MEM_TO_DEV || cfg->dir == DMA_DEV_TO_DEV) - l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS; + l3 |= BIT(D40_MEM_LCSP3_DCFG_MST_POS); - l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS; + l3 |= BIT(D40_MEM_LCSP3_DCFG_EIM_POS); l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS; - l1 |= 1 << D40_MEM_LCSP1_SCFG_EIM_POS; + l1 |= BIT(D40_MEM_LCSP1_SCFG_EIM_POS); l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS; @@ -58,39 +58,39 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) if ((cfg->dir == DMA_DEV_TO_MEM) || (cfg->dir == DMA_DEV_TO_DEV)) { /* Set master port to 1 */ - src |= 1 << D40_SREG_CFG_MST_POS; + src |= BIT(D40_SREG_CFG_MST_POS); src |= D40_TYPE_TO_EVENT(cfg->dev_type); if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) - src |= 1 << D40_SREG_CFG_PHY_TM_POS; + src |= BIT(D40_SREG_CFG_PHY_TM_POS); else src |= 3 << D40_SREG_CFG_PHY_TM_POS; } if ((cfg->dir == DMA_MEM_TO_DEV) || (cfg->dir == DMA_DEV_TO_DEV)) { /* Set master port to 1 */ - dst |= 1 << D40_SREG_CFG_MST_POS; + dst |= BIT(D40_SREG_CFG_MST_POS); dst |= D40_TYPE_TO_EVENT(cfg->dev_type); if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) - dst |= 1 << D40_SREG_CFG_PHY_TM_POS; + dst |= BIT(D40_SREG_CFG_PHY_TM_POS); else dst |= 3 << D40_SREG_CFG_PHY_TM_POS; } /* Interrupt on end of transfer for destination */ - dst |= 1 << D40_SREG_CFG_TIM_POS; + dst |= BIT(D40_SREG_CFG_TIM_POS); /* Generate interrupt on error */ - src |= 1 << D40_SREG_CFG_EIM_POS; - dst |= 1 << D40_SREG_CFG_EIM_POS; + src |= BIT(D40_SREG_CFG_EIM_POS); + dst |= BIT(D40_SREG_CFG_EIM_POS); /* PSIZE */ if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { - src |= 1 << D40_SREG_CFG_PHY_PEN_POS; + src |= BIT(D40_SREG_CFG_PHY_PEN_POS); src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; } if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { - dst |= 1 << D40_SREG_CFG_PHY_PEN_POS; + dst |= BIT(D40_SREG_CFG_PHY_PEN_POS); dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; } @@ -100,14 +100,14 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) /* Set the priority bit to high for the physical channel */ if (cfg->high_priority) { - src |= 1 << D40_SREG_CFG_PRI_POS; - dst |= 1 << D40_SREG_CFG_PRI_POS; + src |= BIT(D40_SREG_CFG_PRI_POS); + dst |= BIT(D40_SREG_CFG_PRI_POS); } if (cfg->src_info.big_endian) - src |= 1 << D40_SREG_CFG_LBE_POS; + src |= BIT(D40_SREG_CFG_LBE_POS); if (cfg->dst_info.big_endian) - dst |= 1 << D40_SREG_CFG_LBE_POS; + dst |= BIT(D40_SREG_CFG_LBE_POS); *src_cfg = src; *dst_cfg = dst; @@ -157,15 +157,15 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, /* If this scatter list entry is the last one, no next link */ if (next_lli == 0) - lli->reg_lnk = 0x1 << D40_SREG_LNK_PHY_TCP_POS; + lli->reg_lnk = BIT(D40_SREG_LNK_PHY_TCP_POS); else lli->reg_lnk = next_lli; /* Set/clear interrupt generation on this link item.*/ if (term_int) - lli->reg_cfg |= 0x1 << D40_SREG_CFG_TIM_POS; + lli->reg_cfg |= BIT(D40_SREG_CFG_TIM_POS); else - lli->reg_cfg &= ~(0x1 << D40_SREG_CFG_TIM_POS); + lli->reg_cfg &= ~BIT(D40_SREG_CFG_TIM_POS); /* Post link */ lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS; -- cgit v1.2.3 From 43f2e1a3be5d83004f09bcb53c46f273e7473a00 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 11:51:57 +0200 Subject: dmaengine: ste_dma40: Convert data_width from register bit format to value When a DMA client requests and configures a DMA channel, it requests data_width in Bytes. The DMA40 driver then swiftly converts it over to the necessary register bit value. Unfortunately, for any subsequent calculations we have to shift '1' by the bit pattern (1 << data_width) times to make any sense of it. This patch flips the semantics on its head and only converts the value to its respective register bit pattern when writing to registers. This way we can use the true data_width (in Bytes) value. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 63 ++++++++++++----------------- drivers/dma/ste_dma40_ll.c | 43 +++++++++++++------- include/linux/platform_data/dma-ste-dma40.h | 9 +---- sound/soc/ux500/ux500_pcm.c | 10 ++--- 4 files changed, 60 insertions(+), 65 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 483da1660eae..76c255fcdc2d 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -80,11 +80,11 @@ struct stedma40_chan_cfg dma40_memcpy_conf_phy = { .mode = STEDMA40_MODE_PHYSICAL, .dir = DMA_MEM_TO_MEM, - .src_info.data_width = STEDMA40_BYTE_WIDTH, + .src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .src_info.psize = STEDMA40_PSIZE_PHY_1, .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, - .dst_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .dst_info.psize = STEDMA40_PSIZE_PHY_1, .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, }; @@ -94,11 +94,11 @@ struct stedma40_chan_cfg dma40_memcpy_conf_log = { .mode = STEDMA40_MODE_LOGICAL, .dir = DMA_MEM_TO_MEM, - .src_info.data_width = STEDMA40_BYTE_WIDTH, + .src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .src_info.psize = STEDMA40_PSIZE_LOG_1, .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, - .dst_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .dst_info.psize = STEDMA40_PSIZE_LOG_1, .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, }; @@ -1005,20 +1005,21 @@ static int d40_psize_2_burst_size(bool is_log, int psize) /* * The dma only supports transmitting packages up to - * STEDMA40_MAX_SEG_SIZE << data_width. Calculate the total number of - * dma elements required to send the entire sg list + * STEDMA40_MAX_SEG_SIZE * data_width, where data_width is stored in Bytes. + * + * Calculate the total number of dma elements required to send the entire sg list. */ static int d40_size_2_dmalen(int size, u32 data_width1, u32 data_width2) { int dmalen; u32 max_w = max(data_width1, data_width2); u32 min_w = min(data_width1, data_width2); - u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w); + u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w); if (seg_max > STEDMA40_MAX_SEG_SIZE) - seg_max -= (1 << max_w); + seg_max -= max_w; - if (!IS_ALIGNED(size, 1 << max_w)) + if (!IS_ALIGNED(size, max_w)) return -EINVAL; if (size <= seg_max) @@ -1464,7 +1465,7 @@ static u32 d40_residue(struct d40_chan *d40c) >> D40_SREG_ELEM_PHY_ECNT_POS; } - return num_elt * (1 << d40c->dma_cfg.dst_info.data_width); + return num_elt * d40c->dma_cfg.dst_info.data_width; } static bool d40_tx_is_linked(struct d40_chan *d40c) @@ -1784,9 +1785,9 @@ static int d40_validate_conf(struct d40_chan *d40c, } if (d40_psize_2_burst_size(is_log, conf->src_info.psize) * - (1 << conf->src_info.data_width) != + conf->src_info.data_width != d40_psize_2_burst_size(is_log, conf->dst_info.psize) * - (1 << conf->dst_info.data_width)) { + conf->dst_info.data_width) { /* * The DMAC hardware only supports * src (burst x width) == dst (burst x width) @@ -2673,33 +2674,10 @@ static void d40_terminate_all(struct dma_chan *chan) static int dma40_config_to_halfchannel(struct d40_chan *d40c, struct stedma40_half_channel_info *info, - enum dma_slave_buswidth width, u32 maxburst) { - enum stedma40_periph_data_width addr_width; int psize; - switch (width) { - case DMA_SLAVE_BUSWIDTH_1_BYTE: - addr_width = STEDMA40_BYTE_WIDTH; - break; - case DMA_SLAVE_BUSWIDTH_2_BYTES: - addr_width = STEDMA40_HALFWORD_WIDTH; - break; - case DMA_SLAVE_BUSWIDTH_4_BYTES: - addr_width = STEDMA40_WORD_WIDTH; - break; - case DMA_SLAVE_BUSWIDTH_8_BYTES: - addr_width = STEDMA40_DOUBLEWORD_WIDTH; - break; - default: - dev_err(d40c->base->dev, - "illegal peripheral address width " - "requested (%d)\n", - width); - return -EINVAL; - } - if (chan_is_logical(d40c)) { if (maxburst >= 16) psize = STEDMA40_PSIZE_LOG_16; @@ -2720,7 +2698,6 @@ dma40_config_to_halfchannel(struct d40_chan *d40c, psize = STEDMA40_PSIZE_PHY_1; } - info->data_width = addr_width; info->psize = psize; info->flow_ctrl = STEDMA40_NO_FLOW_CTRL; @@ -2804,14 +2781,24 @@ static int d40_set_runtime_config(struct dma_chan *chan, src_maxburst = dst_maxburst * dst_addr_width / src_addr_width; } + /* Only valid widths are; 1, 2, 4 and 8. */ + if (src_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED || + src_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES || + dst_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED || + dst_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES || + ((src_addr_width > 1) && (src_addr_width & 1)) || + ((dst_addr_width > 1) && (dst_addr_width & 1))) + return -EINVAL; + + cfg->src_info.data_width = src_addr_width; + cfg->dst_info.data_width = dst_addr_width; + ret = dma40_config_to_halfchannel(d40c, &cfg->src_info, - src_addr_width, src_maxburst); if (ret) return ret; ret = dma40_config_to_halfchannel(d40c, &cfg->dst_info, - dst_addr_width, dst_maxburst); if (ret) return ret; diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 5ddd724dcdc5..a035dfeab6cb 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -10,6 +10,18 @@ #include "ste_dma40_ll.h" +u8 d40_width_to_bits(enum dma_slave_buswidth width) +{ + if (width == DMA_SLAVE_BUSWIDTH_1_BYTE) + return STEDMA40_ESIZE_8_BIT; + else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES) + return STEDMA40_ESIZE_16_BIT; + else if (width == DMA_SLAVE_BUSWIDTH_8_BYTES) + return STEDMA40_ESIZE_64_BIT; + else + return STEDMA40_ESIZE_32_BIT; +} + /* Sets up proper LCSP1 and LCSP3 register for a logical channel */ void d40_log_cfg(struct stedma40_chan_cfg *cfg, u32 *lcsp1, u32 *lcsp3) @@ -39,11 +51,13 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg, l3 |= BIT(D40_MEM_LCSP3_DCFG_EIM_POS); l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; - l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS; + l3 |= d40_width_to_bits(cfg->dst_info.data_width) + << D40_MEM_LCSP3_DCFG_ESIZE_POS; l1 |= BIT(D40_MEM_LCSP1_SCFG_EIM_POS); l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; - l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS; + l1 |= d40_width_to_bits(cfg->src_info.data_width) + << D40_MEM_LCSP1_SCFG_ESIZE_POS; *lcsp1 = l1; *lcsp3 = l3; @@ -95,8 +109,10 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) } /* Element size */ - src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; - dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; + src |= d40_width_to_bits(cfg->src_info.data_width) + << D40_SREG_CFG_ESIZE_POS; + dst |= d40_width_to_bits(cfg->dst_info.data_width) + << D40_SREG_CFG_ESIZE_POS; /* Set the priority bit to high for the physical channel */ if (cfg->high_priority) { @@ -133,23 +149,22 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, num_elems = 2 << psize; /* Must be aligned */ - if (!IS_ALIGNED(data, 0x1 << data_width)) + if (!IS_ALIGNED(data, data_width)) return -EINVAL; /* Transfer size can't be smaller than (num_elms * elem_size) */ - if (data_size < num_elems * (0x1 << data_width)) + if (data_size < num_elems * data_width) return -EINVAL; /* The number of elements. IE now many chunks */ - lli->reg_elt = (data_size >> data_width) << D40_SREG_ELEM_PHY_ECNT_POS; + lli->reg_elt = (data_size / data_width) << D40_SREG_ELEM_PHY_ECNT_POS; /* * Distance to next element sized entry. * Usually the size of the element unless you want gaps. */ if (addr_inc) - lli->reg_elt |= (0x1 << data_width) << - D40_SREG_ELEM_PHY_EIDX_POS; + lli->reg_elt |= data_width << D40_SREG_ELEM_PHY_EIDX_POS; /* Where the data is */ lli->reg_ptr = data; @@ -177,16 +192,16 @@ static int d40_seg_size(int size, int data_width1, int data_width2) { u32 max_w = max(data_width1, data_width2); u32 min_w = min(data_width1, data_width2); - u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w); + u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w); if (seg_max > STEDMA40_MAX_SEG_SIZE) - seg_max -= (1 << max_w); + seg_max -= max_w; if (size <= seg_max) return size; if (size <= 2 * seg_max) - return ALIGN(size / 2, 1 << max_w); + return ALIGN(size / 2, max_w); return seg_max; } @@ -352,10 +367,10 @@ static void d40_log_fill_lli(struct d40_log_lli *lli, lli->lcsp13 = reg_cfg; /* The number of elements to transfer */ - lli->lcsp02 = ((data_size >> data_width) << + lli->lcsp02 = ((data_size / data_width) << D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK; - BUG_ON((data_size >> data_width) > STEDMA40_MAX_SEG_SIZE); + BUG_ON((data_size / data_width) > STEDMA40_MAX_SEG_SIZE); /* 16 LSBs address of the current element */ lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK; diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index 54ddca615cb4..ceba6dc566a9 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h @@ -70,13 +70,6 @@ enum stedma40_flow_ctrl { STEDMA40_FLOW_CTRL, }; -enum stedma40_periph_data_width { - STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT, - STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT, - STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT, - STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT -}; - /** * struct stedma40_half_channel_info - dst/src channel configuration * @@ -87,7 +80,7 @@ enum stedma40_periph_data_width { */ struct stedma40_half_channel_info { bool big_endian; - enum stedma40_periph_data_width data_width; + enum dma_slave_buswidth data_width; int psize; enum stedma40_flow_ctrl flow_ctrl; }; diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index b6e5ae277299..31f9bbc74521 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -76,20 +76,20 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, dma_params = snd_soc_dai_get_dma_data(dai, substream); dma_cfg = dma_params->dma_cfg; - mem_data_width = STEDMA40_HALFWORD_WIDTH; + mem_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES; switch (dma_params->data_size) { case 32: - per_data_width = STEDMA40_WORD_WIDTH; + per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES; break; case 16: - per_data_width = STEDMA40_HALFWORD_WIDTH; + per_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES; break; case 8: - per_data_width = STEDMA40_BYTE_WIDTH; + per_data_width = DMA_SLAVE_BUSWIDTH_1_BYTE; break; default: - per_data_width = STEDMA40_WORD_WIDTH; + per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES; } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -- cgit v1.2.3 From 8cc5af1255966ed82117249a64fe8b13edabc8c5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:58 +0100 Subject: dmaengine: ste_dma40_ll: Replace meaningless register set with comment Unsure of the author's intentions, rather than just removing the nop, we're replacing it with a comment containing the possible intention of the statement OR:ing with 0. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40_ll.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index a035dfeab6cb..27b818dee7c7 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -182,8 +182,10 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, else lli->reg_cfg &= ~BIT(D40_SREG_CFG_TIM_POS); - /* Post link */ - lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS; + /* + * Post link - D40_SREG_LNK_PHY_PRE_POS = 0 + * Relink happens after transfer completion. + */ return 0; } -- cgit v1.2.3 From a7dacb68b35a193d9bdaabde1e4e98140d81a991 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:51:59 +0100 Subject: dmaengine: ste_dma40: Allow memcpy channels to be configured from DT At this moment in time the memcpy channels which can be used by the D40 are fixed, as each supported platform in Mainline uses the same ones. However, platforms do exist which don't follow this convention, so these will need to be tailored. Fortunately, these platforms will be DT only, so this change has very little impact on platform data. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- .../devicetree/bindings/dma/ste-dma40.txt | 2 ++ drivers/dma/ste_dma40.c | 40 +++++++++++++++++----- include/linux/platform_data/dma-ste-dma40.h | 2 ++ 3 files changed, 36 insertions(+), 8 deletions(-) (limited to 'drivers/dma') diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt index 2679a873522d..aa272d866f6e 100644 --- a/Documentation/devicetree/bindings/dma/ste-dma40.txt +++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt @@ -6,6 +6,7 @@ Required properties: - reg-names: Names of the above areas to use during resource look-up - interrupt: Should contain the DMAC interrupt number - #dma-cells: must be <3> +- memcpy-channels: Channels to be used for memcpy Optional properties: - dma-channels: Number of channels supported by hardware - if not present @@ -21,6 +22,7 @@ Example: interrupts = <0 25 0x4>; #dma-cells = <2>; + memcpy-channels = <56 57 58 59 60>; dma-channels = <8>; }; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 76c255fcdc2d..ae462d352110 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -58,6 +58,8 @@ #define D40_ALLOC_PHY BIT(30) #define D40_ALLOC_LOG_FREE 0 +#define D40_MEMCPY_MAX_CHANS 8 + /* Reserved event lines for memcpy only. */ #define DB8500_DMA_MEMCPY_EV_0 51 #define DB8500_DMA_MEMCPY_EV_1 56 @@ -522,6 +524,8 @@ struct d40_gen_dmac { * @phy_start: Physical memory start of the DMA registers. * @phy_size: Size of the DMA register map. * @irq: The IRQ number. + * @num_memcpy_chans: The number of channels used for memcpy (mem-to-mem + * transfers). * @num_phy_chans: The number of physical channels. Read from HW. This * is the number of available channels for this driver, not counting "Secure * mode" allocated physical channels. @@ -565,6 +569,7 @@ struct d40_base { phys_addr_t phy_start; resource_size_t phy_size; int irq; + int num_memcpy_chans; int num_phy_chans; int num_log_chans; struct device_dma_parameters dma_parms; @@ -2938,7 +2943,7 @@ static int __init d40_dmaengine_init(struct d40_base *base, } d40_chan_init(base, &base->dma_memcpy, base->log_chans, - base->num_log_chans, ARRAY_SIZE(dma40_memcpy_channels)); + base->num_log_chans, base->num_memcpy_chans); dma_cap_zero(base->dma_memcpy.cap_mask); dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); @@ -3139,6 +3144,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) struct d40_base *base = NULL; int num_log_chans = 0; int num_phy_chans; + int num_memcpy_chans; int clk_ret = -EINVAL; int i; u32 pid; @@ -3209,6 +3215,12 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) else num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; + /* The number of channels used for memcpy */ + if (plat_data->num_of_memcpy_chans) + num_memcpy_chans = plat_data->num_of_memcpy_chans; + else + num_memcpy_chans = ARRAY_SIZE(dma40_memcpy_channels); + num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; dev_info(&pdev->dev, @@ -3216,7 +3228,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) rev, res->start, num_phy_chans, num_log_chans); base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + - (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) * + (num_phy_chans + num_log_chans + num_memcpy_chans) * sizeof(struct d40_chan), GFP_KERNEL); if (base == NULL) { @@ -3226,6 +3238,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) base->rev = rev; base->clk = clk; + base->num_memcpy_chans = num_memcpy_chans; base->num_phy_chans = num_phy_chans; base->num_log_chans = num_log_chans; base->phy_start = res->start; @@ -3469,12 +3482,8 @@ static int __init d40_of_probe(struct platform_device *pdev, struct device_node *np) { struct stedma40_platform_data *pdata; - - /* - * FIXME: Fill in this routine as more support is added. - * First platform enabled (u8500) doens't need any extra - * properties to run, so this is fairly sparce currently. - */ + int num_memcpy = 0; + const const __be32 *list; pdata = devm_kzalloc(&pdev->dev, sizeof(struct stedma40_platform_data), @@ -3482,6 +3491,21 @@ static int __init d40_of_probe(struct platform_device *pdev, if (!pdata) return -ENOMEM; + list = of_get_property(np, "memcpy-channels", &num_memcpy); + num_memcpy /= sizeof(*list); + + if (num_memcpy > D40_MEMCPY_MAX_CHANS || num_memcpy <= 0) { + d40_err(&pdev->dev, + "Invalid number of memcpy channels specified (%d)\n", + num_memcpy); + return -EINVAL; + } + pdata->num_of_memcpy_chans = num_memcpy; + + of_property_read_u32_array(np, "memcpy-channels", + dma40_memcpy_channels, + num_memcpy); + pdev->dev.platform_data = pdata; return 0; diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index ceba6dc566a9..1bb9b1852256 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h @@ -132,6 +132,7 @@ struct stedma40_chan_cfg { * @num_of_soft_lli_chans: The number of channels that needs to be configured * to use SoftLLI. * @use_esram_lcla: flag for mapping the lcla into esram region + * @num_of_memcpy_chans: The number of channels reserved for memcpy. * @num_of_phy_chans: The number of physical channels implemented in HW. * 0 means reading the number of channels from DMA HW but this is only valid * for 'multiple of 4' channels, like 8. @@ -141,6 +142,7 @@ struct stedma40_platform_data { int *soft_lli_chans; int num_of_soft_lli_chans; bool use_esram_lcla; + int num_of_memcpy_chans; int num_of_phy_chans; }; -- cgit v1.2.3 From fd59f9e6abf2ebf0098c616e1742168db4360d13 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:52:01 +0100 Subject: dmaengine: ste_dma40: Fetch the number of physical channels from DT Some platforms insist on obscure physical channel availability. This information is currently passed though platform data in internal BSP kernels. Once those platforms land, they'll need to configure them appropriately, so we may as well add the infrastructure. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index ae462d352110..4e528dd30ad5 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3482,7 +3482,7 @@ static int __init d40_of_probe(struct platform_device *pdev, struct device_node *np) { struct stedma40_platform_data *pdata; - int num_memcpy = 0; + int num_phy = 0, num_memcpy = 0; const const __be32 *list; pdata = devm_kzalloc(&pdev->dev, @@ -3491,6 +3491,11 @@ static int __init d40_of_probe(struct platform_device *pdev, if (!pdata) return -ENOMEM; + /* If absent this value will be obtained from h/w. */ + of_property_read_u32(np, "dma-channels", &num_phy); + if (num_phy > 0) + pdata->num_of_phy_chans = num_phy; + list = of_get_property(np, "memcpy-channels", &num_memcpy); num_memcpy /= sizeof(*list); -- cgit v1.2.3 From 499c2bc3cc89dcbbf08aa526cd4a984b92a4d2a8 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 15 May 2013 10:52:02 +0100 Subject: dmaengine: ste_dma40: Fetch disabled channels from DT Some platforms have channels which are not available for normal use. This information is currently passed though platform data in internal BSP kernels. Once those platforms land, they'll need to configure them appropriately, so we may as well add the infrastructure. Cc: Dan Williams Cc: Per Forlin Cc: Rabin Vincent Acked-by: Vinod Koul Acked-by: Arnd Bergmann Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/dma/ste-dma40.txt | 2 ++ drivers/dma/ste_dma40.c | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/dma') diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt index aa272d866f6e..bea5b73a7390 100644 --- a/Documentation/devicetree/bindings/dma/ste-dma40.txt +++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt @@ -11,6 +11,7 @@ Required properties: Optional properties: - dma-channels: Number of channels supported by hardware - if not present the driver will attempt to obtain the information from H/W +- disabled-channels: Channels which can not be used Example: @@ -23,6 +24,7 @@ Example: #dma-cells = <2>; memcpy-channels = <56 57 58 59 60>; + disabled-channels = <12>; dma-channels = <8>; }; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 4e528dd30ad5..ffac8225ff54 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3482,7 +3482,7 @@ static int __init d40_of_probe(struct platform_device *pdev, struct device_node *np) { struct stedma40_platform_data *pdata; - int num_phy = 0, num_memcpy = 0; + int num_phy = 0, num_memcpy = 0, num_disabled = 0; const const __be32 *list; pdata = devm_kzalloc(&pdev->dev, @@ -3511,6 +3511,21 @@ static int __init d40_of_probe(struct platform_device *pdev, dma40_memcpy_channels, num_memcpy); + list = of_get_property(np, "disabled-channels", &num_disabled); + num_disabled /= sizeof(*list); + + if (num_disabled > STEDMA40_MAX_PHYS || num_disabled < 0) { + d40_err(&pdev->dev, + "Invalid number of disabled channels specified (%d)\n", + num_disabled); + return -EINVAL; + } + + of_property_read_u32_array(np, "disabled-channels", + pdata->disabled_channels, + num_disabled); + pdata->disabled_channels[num_disabled] = -1; + pdev->dev.platform_data = pdata; return 0; -- cgit v1.2.3 From 8581bbcd30afa9d2fa12ad1605c809b7ada495ea Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 31 May 2013 09:50:07 +0800 Subject: dmaengine: ste_dma40: fix error return code in d40_probe() In many of the error handling case, the return value 'ret' not set and 0 will be return from d40_probe() even if error, but we should return a negative error code instead in those error handling case. This patch fixed them, and also removed useless variable 'err'. Signed-off-by: Wei Yongjun Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index ffac8225ff54..842e2ed04659 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3535,7 +3535,6 @@ static int __init d40_probe(struct platform_device *pdev) { struct stedma40_platform_data *plat_data = pdev->dev.platform_data; struct device_node *np = pdev->dev.of_node; - int err; int ret = -ENOENT; struct d40_base *base = NULL; struct resource *res = NULL; @@ -3647,6 +3646,7 @@ static int __init d40_probe(struct platform_device *pdev) base->lcpa_regulator = regulator_get(base->dev, "lcla_esram"); if (IS_ERR(base->lcpa_regulator)) { d40_err(&pdev->dev, "Failed to get lcpa_regulator\n"); + ret = PTR_ERR(base->lcpa_regulator); base->lcpa_regulator = NULL; goto failure; } @@ -3662,13 +3662,13 @@ static int __init d40_probe(struct platform_device *pdev) } base->initialized = true; - err = d40_dmaengine_init(base, num_reserved_chans); - if (err) + ret = d40_dmaengine_init(base, num_reserved_chans); + if (ret) goto failure; base->dev->dma_parms = &base->dma_parms; - err = dma_set_max_seg_size(base->dev, STEDMA40_MAX_SEG_SIZE); - if (err) { + ret = dma_set_max_seg_size(base->dev, STEDMA40_MAX_SEG_SIZE); + if (ret) { d40_err(&pdev->dev, "Failed to set dma max seg size\n"); goto failure; } @@ -3676,8 +3676,8 @@ static int __init d40_probe(struct platform_device *pdev) d40_hw_init(base); if (np) { - err = of_dma_controller_register(np, d40_xlate, NULL); - if (err && err != -ENODEV) + ret = of_dma_controller_register(np, d40_xlate, NULL); + if (ret) dev_err(&pdev->dev, "could not register of_dma_controller\n"); } -- cgit v1.2.3 From b4a1ccdf27d140394250ddeeb274deeddc9a9b2e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 20 Jun 2013 11:17:39 +0200 Subject: dmaengine: ste_dma40: Declare memcpy config as static Fix sparse warnings: drivers/dma/ste_dma40.c:81:26: warning: symbol 'dma40_memcpy_conf_phy' was not declared. Should it be static? drivers/dma/ste_dma40.c:95:26: warning: symbol 'dma40_memcpy_conf_log' was not declared. Should it be static? Signed-off-by: Fabio Baltieri Acked-by: Vinod Koul Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 842e2ed04659..9f8ba7c5c01b 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -78,7 +78,7 @@ static int dma40_memcpy_channels[] = { }; /* Default configuration for physcial memcpy */ -struct stedma40_chan_cfg dma40_memcpy_conf_phy = { +static struct stedma40_chan_cfg dma40_memcpy_conf_phy = { .mode = STEDMA40_MODE_PHYSICAL, .dir = DMA_MEM_TO_MEM, @@ -92,7 +92,7 @@ struct stedma40_chan_cfg dma40_memcpy_conf_phy = { }; /* Default configuration for logical memcpy */ -struct stedma40_chan_cfg dma40_memcpy_conf_log = { +static struct stedma40_chan_cfg dma40_memcpy_conf_log = { .mode = STEDMA40_MODE_LOGICAL, .dir = DMA_MEM_TO_MEM, -- cgit v1.2.3