Re: [PATCH 3/8] dmaengine: split out virtual channel DMA support from sa11x0 driver
On Wednesday 18 April 2012 03:41 PM, Russell King wrote: +/** + * vchan_cookie_complete - report completion of a descriptor + * vd: virtual descriptor to update + * + * vc.lock must be held by caller + */ +static inline void vchan_cookie_complete(struct virt_dma_desc *vd) +{ + struct virt_dma_chan *vc = to_virt_chan(vd-tx.chan); + + dma_cookie_complete(vd-tx); + dev_vdbg(vc-chan.device-dev, txd %p[%x]: marked complete\n, + vd, vd-tx.cookie); + list_add_tail(vd-node,vc-desc_completed); + + tasklet_schedule(vc-task); +} For cyclic case, we will not like to call the dma_cookie_complete() but want to put the desc in callback list. So can we have one more arg on this function which byspass the call of dma_cookie_complete() -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/8] dmaengine: split out virtual channel DMA support from sa11x0 driver
On Tue, Apr 24, 2012 at 04:05:29PM +0530, Laxman Dewangan wrote: On Wednesday 18 April 2012 03:41 PM, Russell King wrote: +/** + * vchan_cookie_complete - report completion of a descriptor + * vd: virtual descriptor to update + * + * vc.lock must be held by caller + */ +static inline void vchan_cookie_complete(struct virt_dma_desc *vd) +{ + struct virt_dma_chan *vc = to_virt_chan(vd-tx.chan); + + dma_cookie_complete(vd-tx); + dev_vdbg(vc-chan.device-dev, txd %p[%x]: marked complete\n, + vd, vd-tx.cookie); + list_add_tail(vd-node,vc-desc_completed); + + tasklet_schedule(vc-task); +} For cyclic case, we will not like to call the dma_cookie_complete() but want to put the desc in callback list. So can we have one more arg on this function which byspass the call of dma_cookie_complete() See the discussion on what's supposed to happen with cyclic transfers. Cyclic transfers don't complete, so adding them to the completed list and marking them complete is the wrong thing to be doing. So arguably calling this function is also the wrong thing to be doing because you're not completing the transfer. I'll be addressing the issue of cyclic transfers when I eventually get to sorting out the OMAP ASoC driver. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/8] dmaengine: split out virtual channel DMA support from sa11x0 driver
On Tuesday 24 April 2012 04:20 PM, Russell King - ARM Linux wrote: For cyclic case, we will not like to call the dma_cookie_complete() but want to put the desc in callback list. So can we have one more arg on this function which byspass the call of dma_cookie_complete() See the discussion on what's supposed to happen with cyclic transfers. Cyclic transfers don't complete, so adding them to the completed list and marking them complete is the wrong thing to be doing. So arguably calling this function is also the wrong thing to be doing because you're not completing the transfer. OK, we will not call this function but still need to call the callback. So do you suggest to call callback directly from dma driver rather than the virt_chan? I'll be addressing the issue of cyclic transfers when I eventually get to sorting out the OMAP ASoC driver. Here I am developing the dma driver for Tegra in cyclic and normal mode and what is your suggestion here? Should I use your virt_chan now or I can go ahead with my first patch without virt_chan and once you are done with your virt_chan with all cyclic support then port the tegra_dma to use virt chan and next enhanced patch? In this way, my Tegra dma will be there in tree, all client will be move to dma engine based driver and then I will comeback to tegra_dma for using the virt_channel. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/8] dmaengine: split out virtual channel DMA support from sa11x0 driver
Split the virtual slave channel DMA support from the sa11x0 driver so this code can be shared with other slave DMA engine drivers. Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk --- drivers/dma/Kconfig |4 + drivers/dma/Makefile |1 + drivers/dma/sa11x0-dma.c | 249 ++--- drivers/dma/virt-dma.c | 99 ++ drivers/dma/virt-dma.h | 138 + 5 files changed, 320 insertions(+), 171 deletions(-) create mode 100644 drivers/dma/virt-dma.c create mode 100644 drivers/dma/virt-dma.h diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index cf9da36..5828ac4 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -255,6 +255,7 @@ config DMA_SA11X0 tristate SA-11x0 DMA support depends on ARCH_SA1100 select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS help Support the DMA engine found on Intel StrongARM SA-1100 and SA-1110 SoCs. This DMA engine can only be used with on-chip @@ -263,6 +264,9 @@ config DMA_SA11X0 config DMA_ENGINE bool +config DMA_VIRTUAL_CHANNELS + tristate + comment DMA Clients depends on DMA_ENGINE diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 86b795b..fc05f7d 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -2,6 +2,7 @@ ccflags-$(CONFIG_DMADEVICES_DEBUG) := -DDEBUG ccflags-$(CONFIG_DMADEVICES_VDEBUG) += -DVERBOSE_DEBUG obj-$(CONFIG_DMA_ENGINE) += dmaengine.o +obj-$(CONFIG_DMA_VIRTUAL_CHANNELS) += virt-dma.o obj-$(CONFIG_NET_DMA) += iovlock.o obj-$(CONFIG_INTEL_MID_DMAC) += intel_mid_dma.o obj-$(CONFIG_DMATEST) += dmatest.o diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c index ec78cce..5f1d2e6 100644 --- a/drivers/dma/sa11x0-dma.c +++ b/drivers/dma/sa11x0-dma.c @@ -21,6 +21,8 @@ #include linux/slab.h #include linux/spinlock.h +#include virt-dma.h + #define NR_PHY_CHAN6 #define DMA_ALIGN 3 #define DMA_MAX_SIZE 0x1fff @@ -72,12 +74,11 @@ struct sa11x0_dma_sg { }; struct sa11x0_dma_desc { - struct dma_async_tx_descriptor tx; + struct virt_dma_descvd; + u32 ddar; size_t size; - /* maybe protected by c-lock */ - struct list_headnode; unsignedsglen; struct sa11x0_dma_sgsg[0]; }; @@ -85,15 +86,11 @@ struct sa11x0_dma_desc { struct sa11x0_dma_phy; struct sa11x0_dma_chan { - struct dma_chan chan; - spinlock_t lock; - dma_cookie_tlc; + struct virt_dma_chanvc; - /* protected by c-lock */ + /* protected by c-vc.lock */ struct sa11x0_dma_phy *phy; enum dma_status status; - struct list_headdesc_submitted; - struct list_headdesc_issued; /* protected by d-lock */ struct list_headnode; @@ -109,7 +106,7 @@ struct sa11x0_dma_phy { struct sa11x0_dma_chan *vchan; - /* Protected by c-lock */ + /* Protected by c-vc.lock */ unsignedsg_load; struct sa11x0_dma_desc *txd_load; unsignedsg_done; @@ -127,13 +124,12 @@ struct sa11x0_dma_dev { spinlock_t lock; struct tasklet_struct task; struct list_headchan_pending; - struct list_headdesc_complete; struct sa11x0_dma_phy phy[NR_PHY_CHAN]; }; static struct sa11x0_dma_chan *to_sa11x0_dma_chan(struct dma_chan *chan) { - return container_of(chan, struct sa11x0_dma_chan, chan); + return container_of(chan, struct sa11x0_dma_chan, vc.chan); } static struct sa11x0_dma_dev *to_sa11x0_dma(struct dma_device *dmadev) @@ -141,27 +137,26 @@ static struct sa11x0_dma_dev *to_sa11x0_dma(struct dma_device *dmadev) return container_of(dmadev, struct sa11x0_dma_dev, slave); } -static struct sa11x0_dma_desc *to_sa11x0_dma_tx(struct dma_async_tx_descriptor *tx) +static struct sa11x0_dma_desc *sa11x0_dma_next_desc(struct sa11x0_dma_chan *c) { - return container_of(tx, struct sa11x0_dma_desc, tx); + struct virt_dma_desc *vd = vchan_next_desc(c-vc); + + return vd ? container_of(vd, struct sa11x0_dma_desc, vd) : NULL; } -static struct sa11x0_dma_desc *sa11x0_dma_next_desc(struct sa11x0_dma_chan *c) +static void sa11x0_dma_free_desc(struct virt_dma_desc *vd) { - if (list_empty(c-desc_issued)) - return NULL; - - return list_first_entry(c-desc_issued, struct sa11x0_dma_desc, node); + kfree(container_of(vd, struct sa11x0_dma_desc, vd)); } static void sa11x0_dma_start_desc(struct sa11x0_dma_phy *p, struct sa11x0_dma_desc *txd) { - list_del(txd-node); + list_del(txd-vd.node); p-txd_load = txd; p-sg_load = 0; dev_vdbg(p-dev-slave.dev, pchan %u: txd %p[%x]: starting: