patches against slave dma subsystem
v2 cover patches against slave dma subsystem
Recend to Vinod for review.
Since v1:
- is_slave_xfer renamed to is_slave_direction
- changelog fixed for "dma: dw_dmac: clear suspend bit during termination"
- typo fixed in the changelog of "dw_dmac: backlink to dw_dma in dw_dma_chan is superfluous"
Andy Shevchenko (10):
dmaengine: introduce is_slave_direction function
dma: at_hdmac: check direction properly for cyclic transfers
dma: dw_dmac: check direction properly in dw_dma_cyclic_prep
dma: ep93xx_dma: reuse is_slave_direction helper
dma: ipu_idmac: reuse is_slave_direction helper
dma: ste_dma40: reuse is_slave_direction helper
dw_dmac: call .probe after we have a device in place
dw_dmac: store direction in the custom channel structure
dw_dmac: make usage of dw_dma_slave optional
dw_dmac: backlink to dw_dma in dw_dma_chan is superfluous
Heikki Krogerus (1):
dma: dw_dmac: clear suspend bit during termination
drivers/dma/at_hdmac.c | 10 +++---- drivers/dma/dw_dmac.c | 62 ++++++++++++++++++++++++++++++------------- drivers/dma/dw_dmac_regs.h | 17 ++++++------ drivers/dma/ep93xx_dma.c | 3 +-- drivers/dma/ipu/ipu_idmac.c | 2 +- drivers/dma/ste_dma40.c | 2 +- include/linux/dmaengine.h | 5 ++++ 7 files changed, 64 insertions(+), 37 deletions(-)
Signature · 1 line
1.7.10.4
PATCH v2 1/11 dmaengine: introduce is_slave_direction function
This function helps to distinguish the slave type of transfer by checking the direction parameter.
--- include/linux/dmaengine.h | 5 +++++ 1 file changed, 5 insertions(+)
include/linux/dmaengine.h +5 -0
@@ -621,6 +621,11 @@ static inline int dmaengine_slave_config(struct dma_chan *chan, (unsigned long)config); } +static inline bool is_slave_direction (enum dma_transfer_direction direction) +{ +return (direction ==DMA_MEM_TO_DEV ) || (direction ==DMA_DEV_TO_MEM ); +} +static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single (struct dma_chan *chan,dma_addr_t buf,size_t len,enum dma_transfer_direction dir,unsigned long flags)
Signature · 1 line
1.7.10.4
PATCH v2 2/11 dma: at_hdmac: check direction properly for cyclic transfers
In reply to Andy Shevchenkodma_transfer_direction is a normal enum. It means we can't usually use the values as bit fields. Let's adjust this check and move it above the usage of the direction parameter, due to the nature of the following usage of it.
--- drivers/dma/at_hdmac.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/dma/at_hdmac.c +5 -5
@@ -778,7 +778,7 @@ err:*/ static int atc_dma_cyclic_check_values (unsigned int reg_width,dma_addr_t buf_addr, -size_t period_len,enum dma_transfer_direction direction) +size_t period_len) {if (period_len > (ATC_BTSIZE_MAX << reg_width)) goto err_out;
@@ -786,8 +786,6 @@ atc_dma_cyclic_check_values(unsigned int reg_width, dma_addr_t buf_addr, goto err_out;if (unlikely (buf_addr & ((1 << reg_width) -1 ))) goto err_out; -if (unlikely (!(direction & (DMA_DEV_TO_MEM |DMA_MEM_TO_DEV )))) - goto err_out;return 0 ;
@@ -886,14 +884,16 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,return NULL ; } +if (unlikely (!is_slave_direction (direction))) + goto err_out; +if (sconfig->direction ==DMA_MEM_TO_DEV ) reg_width =convert_buswidth (sconfig->dst_addr_width);else reg_width =convert_buswidth (sconfig->src_addr_width);/* Check for too big/unaligned periods and unaligned DMA buffer */ -if (atc_dma_cyclic_check_values (reg_width, buf_addr, - period_len, direction)) +if (atc_dma_cyclic_check_values (reg_width, buf_addr, period_len)) goto err_out;/* build cyclic linked list */
Signature · 1 line
1.7.10.4
PATCH v2 3/11 dma: dw_dmac: check direction properly in dw_dma_cyclic_prep
In reply to Andy Shevchenkodma_transfer_direction is a normal enum. It means we can't usually use the values as bit fields. Let's adjust this check and move it above the usage of the direction parameter, due to the nature of the following usage of it.
--- drivers/dma/dw_dmac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/dma/dw_dmac.c +3 -2
@@ -1355,6 +1355,9 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, retval =ERR_PTR (-EINVAL ); +if (unlikely (!is_slave_direction (direction))) + goto out_err; +if (direction ==DMA_MEM_TO_DEV ) reg_width =__ffs (sconfig->dst_addr_width);else
@@ -1369,8 +1372,6 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, goto out_err;if (unlikely (buf_addr & ((1 << reg_width) -1 ))) goto out_err; -if (unlikely (!(direction & (DMA_MEM_TO_DEV |DMA_DEV_TO_MEM )))) - goto out_err; retval =ERR_PTR (-ENOMEM );
Signature · 1 line
1.7.10.4
PATCH v2 4/11 dma: ep93xx_dma: reuse is_slave_direction helper
In reply to Andy ShevchenkoThe is_slave_direction helps to check if the transfer type is slave.
--- drivers/dma/ep93xx_dma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/dma/ep93xx_dma.c +1 -2
@@ -903,8 +903,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan)switch (data->port) {case EP93XX_DMA_SSP :case EP93XX_DMA_IDE : -if (data->direction !=DMA_MEM_TO_DEV && - data->direction !=DMA_DEV_TO_MEM ) +if (!is_slave_direction (data->direction))return -EINVAL ;break ;default :
Signature · 1 line
1.7.10.4
PATCH v2 5/11 dma: ipu_idmac: reuse is_slave_direction helper
In reply to Andy ShevchenkoThe is_slave_direction helps to check if the transfer type is slave.
--- drivers/dma/ipu/ipu_idmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/ipu/ipu_idmac.c +1 -1
@@ -1347,7 +1347,7 @@ static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan chan->chan_id != IDMAC_IC_7)return NULL ; -if (direction !=DMA_DEV_TO_MEM && direction !=DMA_MEM_TO_DEV ) { +if (!is_slave_direction (direction)) {dev_err (chan->device->dev,"Invalid DMA direction %d!\n" , direction);return NULL ; }
Signature · 1 line
1.7.10.4
PATCH v2 6/11 dma: ste_dma40: reuse is_slave_direction helper
In reply to Andy ShevchenkoThe is_slave_direction helps to check if the transfer type is slave.
--- drivers/dma/ste_dma40.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/ste_dma40.c +1 -1
@@ -2337,7 +2337,7 @@ static struct dma_async_tx_descriptor *d40_prep_slave_sg(struct dma_chan *chan, unsigned long dma_flags, void *context) { -if (direction !=DMA_DEV_TO_MEM && direction !=DMA_MEM_TO_DEV ) +if (!is_slave_direction (direction))return NULL ;return d40_prep_sg (chan, sgl, sgl, sg_len, direction, dma_flags);
Signature · 1 line
1.7.10.4
PATCH v2 7/11 dw_dmac: call .probe after we have a device in place
In reply to Andy ShevchenkoIf we don't yet have the platform device for the driver when it is being loaded we fail to probe the driver. So instead of calling probe() directly we call platform_driver_register(). It will call the probe() immediately if we have the device but also makes the driver to work on platforms where the platform device is created later.
--- drivers/dma/dw_dmac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/dma/dw_dmac.c +2 -1
@@ -1858,6 +1858,7 @@ MODULE_DEVICE_TABLE(of, dw_dma_id_table);#endif static struct platform_driver dw_driver = { + .probe = dw_probe, .remove = dw_remove, .shutdown = dw_shutdown, .driver = {
@@ -1869,7 +1870,7 @@ static struct platform_driver dw_driver = {static int __init dw_init (void ) { -return platform_driver_probe (&dw_driver, dw_probe); +return platform_driver_register (&dw_driver); }subsys_initcall (dw_init);
Signature · 1 line
1.7.10.4
PATCH v2 8/11 dw_dmac: store direction in the custom channel structure
In reply to Andy ShevchenkoCurrently the direction value comes from the generic slave configuration structure and explicitly as a preparation function parameter. The first one is kinda obsoleted. Thus, we have to store the value passed to the preparation function somewhere in our structures to be able to use it later. The best candidate to provide the storage is a custom channel structure. Until now we still keep and check the direction field of the slave config structure as well.
--- drivers/dma/dw_dmac.c | 12 ++++++++++-- drivers/dma/dw_dmac_regs.h | 14 ++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-)
drivers/dma/dw_dmac.c +10 -2
@@ -178,9 +178,9 @@ static void dwc_initialize(struct dw_dma_chan *dwc) cfghi = dws->cfg_hi; cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK ; }else { -if (dwc->dma_sconfig.direction ==DMA_MEM_TO_DEV ) +if (dwc->direction ==DMA_MEM_TO_DEV ) cfghi =DWC_CFGH_DST_PER (dwc->dma_sconfig.slave_id); -else if (dwc->dma_sconfig.direction ==DMA_DEV_TO_MEM ) +else if (dwc->direction ==DMA_DEV_TO_MEM ) cfghi =DWC_CFGH_SRC_PER (dwc->dma_sconfig.slave_id); }
@@ -721,6 +721,8 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,return NULL ; } + dwc->direction =DMA_MEM_TO_MEM ; + data_width = min_t(unsigned int, dwc->dw->data_width[dwc_get_sms(dws)], dwc->dw->data_width[dwc_get_dms (dws)]);
@@ -805,6 +807,8 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,if (unlikely (!dws || !sg_len))return NULL ; + dwc->direction = direction; + prev = first =NULL ;switch (direction) {
@@ -981,6 +985,7 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)return -EINVAL ;memcpy (&dwc->dma_sconfig, sconfig,sizeof (*sconfig)); + dwc->direction = sconfig->direction;convert_burst (&dwc->dma_sconfig.src_maxburst);convert_burst (&dwc->dma_sconfig.dst_maxburst);
@@ -1358,6 +1363,8 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,if (unlikely (!is_slave_direction (direction))) goto out_err; + dwc->direction = direction; +if (direction ==DMA_MEM_TO_DEV ) reg_width =__ffs (sconfig->dst_addr_width);else
@@ -1732,6 +1739,7 @@ static int dw_probe(struct platform_device *pdev)channel_clear_bit (dw,CH_EN , dwc->mask); dwc->dw = dw; + dwc->direction =DMA_TRANS_NONE ;/* hardware configuration */ if (autocfg) {
drivers/dma/dw_dmac_regs.h +8 -6
@@ -9,6 +9,7 @@* published by the Free Software Foundation. */ +#include <linux/dmaengine.h> #include <linux/dw_dmac.h> #define DW_DMA_MAX_NR_CHANNELS 8
@@ -184,12 +185,13 @@ enum dw_dmac_flags { };struct dw_dma_chan { -struct dma_chan chan; -void __iomem *ch_regs; -u8 mask; -u8 priority; -bool paused; -bool initialized; +struct dma_chan chan; +void __iomem *ch_regs; +u8 mask; +u8 priority; +enum dma_transfer_direction direction; +bool paused; +bool initialized;/* software emulation of the LLP transfers */ struct list_head *tx_list;
Signature · 1 line
1.7.10.4
PATCH v2 9/11 dw_dmac: make usage of dw_dma_slave optional
In reply to Andy ShevchenkoThe driver requires a custom slave configuration to be present to be able to make the slave transfers. Nevertheless, in some cases we need only the request line as an additional information to the generic slave configuration. The request line is provided by slave_id parameter of the dma_slave_config structure. That's why the custom slave configuration could be optional for such cases.
--- drivers/dma/dw_dmac.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/dma/dw_dmac.c +7 -6
@@ -50,11 +50,12 @@ static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)struct dw_dma_slave *__slave = (_chan->private); \struct dw_dma_chan *_dwc =to_dw_dma_chan (_chan); \struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \ +bool _is_slave =is_slave_xfer (_dwc->direction); \int _dms =dwc_get_dms (__slave); \int _sms =dwc_get_sms (__slave); \ -u8 _smsize = __slave ? _sconfig->src_maxburst : \ +u8 _smsize = _is_slave ? _sconfig->src_maxburst : \DW_DMA_MSIZE_16 ; \ -u8 _dmsize = __slave ? _sconfig->dst_maxburst : \ +u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \DW_DMA_MSIZE_16 ; \ \ (DWC_CTLL_DST_MSIZE(_dmsize) \
@@ -328,7 +329,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,list_splice_init (&desc->tx_list, &dwc->free_list);list_move (&desc->desc_node, &dwc->free_list); -if (!dwc->chan.private) { +if (!is_slave_xfer (dwc->direction)) {struct device *parent =chan2parent (&dwc->chan);if (!(txd->flags &DMA_COMPL_SKIP_DEST_UNMAP )) {if (txd->flags &DMA_COMPL_DEST_UNMAP_SINGLE )
@@ -804,7 +805,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,dev_vdbg (chan2dev (chan),"%s\n" , __func__); -if (unlikely (!dws || !sg_len)) +if (unlikely (!is_slave_xfer (direction) || !sg_len))return NULL ; dwc->direction = direction;
@@ -980,8 +981,8 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) {struct dw_dma_chan *dwc =to_dw_dma_chan (chan); -/* Check if it is chan is configured for slave transfers */ -if (!chan->private) +/* Check if chan will be configured for slave transfers */ +if (!is_slave_xfer (sconfig->direction))return -EINVAL ;memcpy (&dwc->dma_sconfig, sconfig,sizeof (*sconfig));
Signature · 1 line
1.7.10.4
Re: [PATCHv2 09/11] dw_dmac: make usage of dw_dma_slave optional
Please, don't push this one yet. I forgot to update the name of is_slave_xfer.
Quoted 69 lines · Andy Shevchenko
The driver requires a custom slave configuration to be present to be able to make the slave transfers. Nevertheless, in some cases we need only the request line as an additional information to the generic slave configuration. The request line is provided by
slave_idparameter of thedma_slave_configstructure. That's why the custom slave configuration could be optional for such cases.Signed-off-by Andy Shevchenko <[email protected]>Acked-by Viresh Kumar <[email protected]>--- drivers/dma/dw_dmac.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)drivers/dma/dw_dmac.c +7
-7@@ -50,11 +50,12 @@ static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)struct dw_dma_slave *__slave = (_chan->private); \struct dw_dma_chan *_dwc =to_dw_dma_chan (_chan); \struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \ +bool _is_slave =is_slave_xfer (_dwc->direction); \int _dms =dwc_get_dms (__slave); \int _sms =dwc_get_sms (__slave); \ -u8 _smsize = __slave ? _sconfig->src_maxburst : \ +u8 _smsize = _is_slave ? _sconfig->src_maxburst : \DW_DMA_MSIZE_16 ; \ -u8 _dmsize = __slave ? _sconfig->dst_maxburst : \ +u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \DW_DMA_MSIZE_16 ; \ \ (DWC_CTLL_DST_MSIZE(_dmsize) \@@ -328,7 +329,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,list_splice_init (&desc->tx_list, &dwc->free_list);list_move (&desc->desc_node, &dwc->free_list); -if (!dwc->chan.private) { +if (!is_slave_xfer (dwc->direction)) {struct device *parent =chan2parent (&dwc->chan);if (!(txd->flags &DMA_COMPL_SKIP_DEST_UNMAP )) {if (txd->flags &DMA_COMPL_DEST_UNMAP_SINGLE )@@ -804,7 +805,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,dev_vdbg (chan2dev (chan),"%s\n" , __func__); -if (unlikely (!dws || !sg_len)) +if (unlikely (!is_slave_xfer (direction) || !sg_len))return NULL ; dwc->direction = direction;@@ -980,8 +981,8 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) {struct dw_dma_chan *dwc =to_dw_dma_chan (chan); -/* Check if it is chan is configured for slave transfers */ -if (!chan->private) +/* Check if chan will be configured for slave transfers */ +if (!is_slave_xfer (sconfig->direction))return -EINVAL ;memcpy (&dwc->dma_sconfig, sconfig,sizeof (*sconfig)); --1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 2 lines
With Best Regards, Andy Shevchenko
[PATCHv2.1] dw_dmac: make usage of dw_dma_slave optional
The driver requires a custom slave configuration to be present to be able to make the slave transfers. Nevertheless, in some cases we need only the request line as an additional information to the generic slave configuration. The request line is provided by slave_id parameter of the dma_slave_config structure. That's why the custom slave configuration could be optional for such cases.
--- drivers/dma/dw_dmac.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/dma/dw_dmac.c +7 -6
@@ -50,11 +50,12 @@ static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)struct dw_dma_slave *__slave = (_chan->private); \struct dw_dma_chan *_dwc =to_dw_dma_chan (_chan); \struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \ +bool _is_slave =is_slave_direction (_dwc->direction); \int _dms =dwc_get_dms (__slave); \int _sms =dwc_get_sms (__slave); \ -u8 _smsize = __slave ? _sconfig->src_maxburst : \ +u8 _smsize = _is_slave ? _sconfig->src_maxburst : \DW_DMA_MSIZE_16 ; \ -u8 _dmsize = __slave ? _sconfig->dst_maxburst : \ +u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \DW_DMA_MSIZE_16 ; \ \ (DWC_CTLL_DST_MSIZE(_dmsize) \
@@ -328,7 +329,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,list_splice_init (&desc->tx_list, &dwc->free_list);list_move (&desc->desc_node, &dwc->free_list); -if (!dwc->chan.private) { +if (!is_slave_direction (dwc->direction)) {struct device *parent =chan2parent (&dwc->chan);if (!(txd->flags &DMA_COMPL_SKIP_DEST_UNMAP )) {if (txd->flags &DMA_COMPL_DEST_UNMAP_SINGLE )
@@ -804,7 +805,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,dev_vdbg (chan2dev (chan),"%s\n" , __func__); -if (unlikely (!dws || !sg_len)) +if (unlikely (!is_slave_direction (direction) || !sg_len))return NULL ; dwc->direction = direction;
@@ -980,8 +981,8 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) {struct dw_dma_chan *dwc =to_dw_dma_chan (chan); -/* Check if it is chan is configured for slave transfers */ -if (!chan->private) +/* Check if chan will be configured for slave transfers */ +if (!is_slave_direction (sconfig->direction))return -EINVAL ;memcpy (&dwc->dma_sconfig, sconfig,sizeof (*sconfig));
Signature · 1 line
1.7.10.4
PATCH v2 10/11 dw_dmac: backlink to dw_dma in dw_dma_chan is superfluous
In reply to Andy ShevchenkoThe same information could be extracted from the struct dma_chan. The patch introduces helper function dwc_get_data_width() as well.
--- drivers/dma/dw_dmac.c | 27 ++++++++++++++++++++------- drivers/dma/dw_dmac_regs.h | 3 --- 2 files changed, 20 insertions(+), 10 deletions(-)
drivers/dma/dw_dmac.c +20 -7
@@ -73,6 +73,22 @@ static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)*/ #define NR_DESCS_PER_CHANNEL 64 +#define SRC_MASTER 0 +#define DST_MASTER 1 + +static inline unsigned int dwc_get_data_width (struct dma_chan *chan,int master) +{ +struct dw_dma *dw =to_dw_dma (chan->device); +struct dw_dma_slave *dws = chan->private; + +if (master ==SRC_MASTER ) +return dw->data_width[dwc_get_sms (dws)]; +else if (master ==DST_MASTER ) +return dw->data_width[dwc_get_dms (dws)]; + +return 0 ; +} +/*----------------------------------------------------------------------*/ /*
@@ -701,7 +717,6 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, size_t len, unsigned long flags) {struct dw_dma_chan *dwc =to_dw_dma_chan (chan); -struct dw_dma_slave *dws = chan->private;struct dw_desc *desc;struct dw_desc *first;struct dw_desc *prev;
@@ -724,8 +739,8 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, dwc->direction =DMA_MEM_TO_MEM ; - data_width = min_t(unsigned int, dwc->dw->data_width[dwc_get_sms(dws)], - dwc->dw->data_width[dwc_get_dms (dws)]); + data_width = min_t(unsigned int, dwc_get_data_width(chan, SRC_MASTER), +dwc_get_data_width (chan,DST_MASTER )); src_width = dst_width = min_t(unsigned int, data_width,dwc_fast_fls (src | dest | len));
@@ -790,7 +805,6 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, unsigned long flags, void *context) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); -struct dw_dma_slave *dws = chan->private;struct dma_slave_config *sconfig = &dwc->dma_sconfig;struct dw_desc *prev;struct dw_desc *first;
@@ -824,7 +838,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ctllo |= sconfig->device_fc ?DWC_CTLL_FC (DW_DMA_FC_P_M2P ) :DWC_CTLL_FC (DW_DMA_FC_D_M2P ); - data_width = dwc->dw->data_width[dwc_get_sms (dws)]; + data_width =dwc_get_data_width (chan,SRC_MASTER );for_each_sg (sgl, sg, sg_len, i) {struct dw_desc *desc;
@@ -887,7 +901,7 @@ slave_sg_todev_fill_desc: ctllo |= sconfig->device_fc ?DWC_CTLL_FC (DW_DMA_FC_P_P2M ) :DWC_CTLL_FC (DW_DMA_FC_D_P2M ); - data_width = dwc->dw->data_width[dwc_get_dms (dws)]; + data_width =dwc_get_data_width (chan,DST_MASTER );for_each_sg (sgl, sg, sg_len, i) {struct dw_desc *desc;
@@ -1739,7 +1753,6 @@ static int dw_probe(struct platform_device *pdev)channel_clear_bit (dw,CH_EN , dwc->mask); - dwc->dw = dw; dwc->direction =DMA_TRANS_NONE ;/* hardware configuration */
drivers/dma/dw_dmac_regs.h +0 -3
@@ -214,9 +214,6 @@ struct dw_dma_chan {/* configuration passed via DMA_SLAVE_CONFIG */ struct dma_slave_config dma_sconfig; - -/* backlink to dw_dma */ -struct dw_dma *dw; }; static inline struct dw_dma_chan_regs __iomem *
Signature · 1 line
1.7.10.4
PATCH v2 11/11 dma: dw_dmac: clear suspend bit during termination
In reply to Andy ShevchenkoFrom: Heikki Krogerus <[email protected]>
The DMA transfer could not be established if previously it was paused and terminated. In that case the channel's suspend bit remains set that prevents to transfer anything until channel is resumed.
The patch adds the dwc_chan_resume() call instead of a plain flag assignment. That clears the DWC_CFGL_CH_SUSP bit as well during termination.
--- drivers/dma/dw_dmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/dw_dmac.c +1 -1
@@ -1059,7 +1059,7 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,dwc_chan_disable (dw, dwc); - dwc->paused = false; +dwc_chan_resume (dwc);/* active_list entries will end up before queued entries */ list_splice_init (&dwc->queue, &list);
Signature · 1 line
1.7.10.4
Vinod Koul
AppliedQuoted 7 lines · Andy Shevchenko
Recend to Vinod for review.
Since v1:
-is_slave_xferrenamed tois_slave_direction
- changelog fixed for "dma:dw_dmac: clear suspend bit during termination"
- typo fixed in the changelog of "dw_dmac: backlink todw_dmaindw_dma_chanis superfluous"
Applied all, Thanks
--
~Vinod
Quoted 28 lines
Andy Shevchenko (10):
dmaengine: introduceis_slave_directionfunction
dma:at_hdmac: check direction properly for cyclic transfers
dma:dw_dmac: check direction properly indw_dma_cyclic_prep
dma:ep93xx_dma: reuseis_slave_directionhelper
dma:ipu_idmac: reuseis_slave_directionhelper
dma:ste_dma40: reuseis_slave_directionhelper
dw_dmac: call .probe after we have a device in place
dw_dmac: store direction in the custom channel structure
dw_dmac: make usage ofdw_dma_slaveoptional
dw_dmac: backlink todw_dmaindw_dma_chanis superfluousHeikki Krogerus (1):
dma:dw_dmac: clear suspend bit during terminationdrivers/dma/at_hdmac.c | 10 +++---- drivers/dma/dw_dmac.c | 62 ++++++++++++++++++++++++++++++------------- drivers/dma/dw_dmac_regs.h | 17 ++++++------ drivers/dma/ep93xx_dma.c | 3 +-- drivers/dma/ipu/ipu_idmac.c | 2 +- drivers/dma/ste_dma40.c | 2 +- include/linux/dmaengine.h | 5 ++++ 7 files changed, 64 insertions(+), 37 deletions(-)Signature · 1 line
1.7.10.4