To use DMA generic APIs for Samsung DMA
Subsystems (9)
v5 cover To use DMA generic APIs for Samsung DMA
This patchset adds support DMA generic APIs for Samsung DMA.
The changes from V4 are following:
- Change DMA cyclic capability operation on '04 patch'
- Remove cyclic_task
- Initialize 'cyclic' variable on channel request.
- Change pl330 data structure on '02, 07, 08, 09, 10 patches'
- Move 'fifo_addr' and 'burst_sz' variables from 'struct dma_pl330_peri' to 'struct dma_pl330_chan'
- Change some names on '02, 05 patch'
- Change DMADEV_PL330 configuration to SAMSUNG_DMA_PL330
- Add comment for 'burst_sz' variable
- Consider 'xxx_maxburst' on '03, 06 patch'
- Modify pl330_filter() function on '06 patch'
- Merge DMA control code on SPI driver on '13 patch'
[PATCH V5 01/15] DMA: PL330: Add support runtime PM for PL330 DMAC [PATCH V5 02/15] DMA: PL330: Update PL330 DMA API driver
[PATCH V5 03/15] DMA: PL330: Support DMA_SLAVE_CONFIG command
[PATCH V5 04/15] DMA: PL330: Add DMA_CYCLIC capability
[PATCH V5 05/15] ARM: SAMSUNG: Update to use PL330-DMA driver
[PATCH V5 06/15] ARM: SAMSUNG: Add common DMA operations
[PATCH V5 07/15] ARM: EXYNOS4: Use generic DMA PL330 driver
[PATCH V5 08/15] ARM: S5PV210: Use generic DMA PL330 driver
[PATCH V5 09/15] ARM: S5PC100: Use generic DMA PL330 driver
[PATCH V5 10/15] ARM: S5P64X0: Use generic DMA PL330 driver
[PATCH V5 11/15] ARM: SAMSUNG: Remove S3C-PL330-DMA driver
[PATCH V5 12/15] spi/s3c64xx: Add support DMA engine API
[PATCH V5 13/15] spi/s3c64xx: Merge dma control code
[PATCH V5 14/15] ASoC: Samsung: Update DMA interface
[PATCH V5 15/15] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction
PATCH v5 1/15 DMA: PL330: Add support runtime PM for PL330 DMAC
--- drivers/dma/pl330.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 73 insertions(+), 2 deletions(-)
drivers/dma/pl330.c +73 -2
@@ -17,6 +17,7 @@#include <linux/interrupt.h> #include <linux/amba/bus.h> #include <linux/amba/pl330.h> +#include <linux/pm_runtime.h> #define NR_DEFAULT_DESC 16
@@ -83,6 +84,8 @@ struct dma_pl330_dmac {/* Peripheral channels connected to this DMAC */ struct dma_pl330_chan peripherals[0 ];/* keep at end */ + +struct clk *clk; };struct dma_pl330_desc {
@@ -696,6 +699,30 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) goto probe_err1; } + pdmac->clk =clk_get (&adev->dev,"dma" ); +if (IS_ERR (pdmac->clk)) { +dev_err (&adev->dev,"Cannot get operation clock.\n" ); + ret = -EINVAL ; + goto probe_err1; + } + +amba_set_drvdata (adev, pdmac); + +#ifdef CONFIG_PM_RUNTIME +/* to use the runtime PM helper functions */ +pm_runtime_enable (&adev->dev); + +/* enable the power domain */ +if (pm_runtime_get_sync (&adev->dev)) { +dev_err (&adev->dev,"failed to get runtime pm\n" ); + ret = -ENODEV ; + goto probe_err1; + } +#else +/* enable dma clk */ +clk_enable (pdmac->clk); +#endif + irq = adev->irq[0 ]; ret =request_irq (irq, pl330_irq_handler,0 ,dev_name (&adev->dev), pi);
@@ -763,8 +790,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) goto probe_err4; } -amba_set_drvdata (adev, pdmac); -dev_info (&adev->dev,"Loaded driver for PL330 DMAC-%d\n" , adev->periphid); dev_info(&adev->dev,
@@ -825,6 +850,13 @@ static int __devexit pl330_remove(struct amba_device *adev) res = &adev->res;release_mem_region (res->start,resource_size (res)); +#ifdef CONFIG_PM_RUNTIME +pm_runtime_put (&adev->dev); +pm_runtime_disable (&adev->dev); +#else +clk_disable (pdmac->clk); +#endif +kfree (pdmac);return 0 ;
@@ -838,10 +870,49 @@ static struct amba_id pl330_ids[] = { { 0, 0 }, }; +#ifdef CONFIG_PM_RUNTIME +static int pl330_runtime_suspend (struct device *dev) +{ +struct dma_pl330_dmac *pdmac =dev_get_drvdata (dev); + +if (!pdmac) { +dev_err (dev,"failed to get dmac\n" ); +return -ENODEV ; + } + +clk_disable (pdmac->clk); + +return 0 ; +} + +static int pl330_runtime_resume (struct device *dev) +{ +struct dma_pl330_dmac *pdmac =dev_get_drvdata (dev); + +if (!pdmac) { +dev_err (dev,"failed to get dmac\n" ); +return -ENODEV ; + } + +clk_enable (pdmac->clk); + +return 0 ; +} +#else +#define pl330_runtime_suspend NULL +#define pl330_runtime_resume NULL +#endif /* CONFIG_PM_RUNTIME */ + +static const struct dev_pm_ops pl330_pm_ops = { + .runtime_suspend = pl330_runtime_suspend, + .runtime_resume = pl330_runtime_resume, +}; +static struct amba_driver pl330_driver = { .drv = { .owner =THIS_MODULE , .name ="dma-pl330" , + .pm = &pl330_pm_ops, }, .id_table = pl330_ids, .probe = pl330_probe,
Signature · 1 line
1.7.1
RFC PATCH 1/1 DMA: PL330: Update PL330 DMAC to support runtime PM
This patch update runtime PM for PL330 DMAC to reduce power consumption.
---
The following patch support runtime PM for PL330 DMAC, but the clock of PL330 is always on. If the clock of PL330 is always on, additional power (10mA) is consumed.
"[PATCH 01/15] DMA: PL330: Add support runtime PM for PL330 DMAC"
http://permalink.gmane.org/gmane.linux.kernel.samsung-soc/5931
arch/arm/plat-samsung/dma-ops.c | 21 +++++++++++ drivers/dma/pl330.c | 76 +++++++++++++-------------------------- include/linux/amba/pl330.h | 54 +++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 51 deletions(-)
arch/arm/plat-samsung/dma-ops.c +21 -0
@@ -13,6 +13,7 @@#include <linux/kernel.h> #include <linux/errno.h> #include <linux/amba/pl330.h> +#include <linux/pm_runtime.h> #include <mach/dma.h>
@@ -33,12 +34,23 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch,struct dma_chan *chan;dma_cap_mask_t mask;struct dma_slave_config slave_config; +#ifdef CONFIG_PM_RUNTIME +struct dma_pl330_chan *pch; +struct dma_pl330_dmac *pdmac; +#endif dma_cap_zero (mask);dma_cap_set (info->cap, mask); chan =dma_request_channel (mask, pl330_filter, (void *)dma_ch); +#ifdef CONFIG_PM_RUNTIME + pch = container_of(chan, struct dma_pl330_chan, chan); + pdmac = pch->dmac; + +pm_runtime_get_sync (pdmac->pif.dev); +#endif +if (info->direction ==DMA_FROM_DEVICE ) {memset (&slave_config,0 ,sizeof (struct dma_slave_config )); slave_config.direction = info->direction;
@@ -59,8 +71,17 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch,static int samsung_dmadev_release (unsigned ch,struct s3c2410_dma_client *client) { +#ifdef CONFIG_PM_RUNTIME +struct dma_pl330_chan *pch = + container_of((struct dma_chan *)ch, struct dma_pl330_chan, chan); +struct dma_pl330_dmac *pdmac = pdmac = pch->dmac;; +#endif +dma_release_channel ((struct dma_chan *)ch); +#ifdef CONFIG_PM_RUNTIME +pm_runtime_put (pdmac->pif.dev); +#endif return 0 ; }
drivers/dma/pl330.c +25 -51
100 lines not on this page · raw message
include/linux/amba/pl330.h +54 -0
64 lines not on this page · raw message
RFC PATCH 1/1 DMA: PL330: Update PL330 DMAC to support runtime PM
Quoted 8 lines · Chanwoo Choi
This patch update runtime PM for PL330 DMAC to reduce power consumption.
Signed-off-by Chanwoo Choi <[email protected]>Signed-off-by Kyungmin Park <[email protected]>---
The following patch support runtime PM for PL330 DMAC, but the clock of PL330 is always on. If the clock of PL330 is always on, additional power (10mA) is consumed.
Yes, we need to do this, but please do it in drivers/dma/pl330.c so that every platform benefits.
Quoted 69 lines
include/linux/amba/pl330.h +0
-0@@ -12,6 +12,9 @@?#ifndef ? ? ? ?__AMBA_PL330_H_
?#define ? ? ? ?__AMBA_PL330_H_include/linux/amba/pl330.h +3
-0+#include <linux/dmaengine.h> +#include <linux/interrupt.h> +?#include <
asm/hardware/pl330.h>?struct
dma_pl330_peri{include/linux/amba/pl330.h +51
-0@@ -42,4 +45,55 @@ struct dma_pl330_platdata { ? ? ? ?unsigned mcbuf_sz; ?}; +struct dma_pl330_chan { + ? ? ? /* Schedule desc completion */ + ? ? ? struct tasklet_struct task; + + ? ? ? /* DMA-Engine Channel */ + ? ? ? struct dma_chan chan; + + ? ? ? /* Last completed cookie */ + ? ? ? dma_cookie_t completed; + + ? ? ? /* List of to be xfered descriptors */ + ? ? ? struct list_head work_list; + + ? ? ? /* Pointer to the DMAC that manages this channel, + ? ? ? ?* NULL if the channel is available to be acquired. + ? ? ? ?* As the parent, this DMAC also provides descriptors + ? ? ? ?* to the channel. + ? ? ? ?*/ + ? ? ? struct dma_pl330_dmac *dmac; + + ? ? ? /* To protect channel manipulation */ + ? ? ? spinlock_t lock; + + ? ? ? /* Token of a hardware channel thread of PL330 DMAC + ? ? ? ?* NULL if the channel is available to be acquired. + ? ? ? ?*/ + ? ? ? void *pl330_chid; + + ? ? ? /* taks for cyclic capability */ + ? ? ? struct tasklet_struct *cyclic_task; + + ? ? ? bool cyclic; +}; + +struct dma_pl330_dmac { + ? ? ? struct pl330_info pif; + + ? ? ? /* DMA-Engine Device */ + ? ? ? struct dma_device ddma; + + ? ? ? /* Pool of descriptors available for the DMAC's channels */ + ? ? ? struct list_head desc_pool; + ? ? ? /* To protect desc_pool manipulation */ + ? ? ? spinlock_t pool_lock; + + ? ? ? /* Peripheral channels connected to this DMAC */ + ? ? ? struct dma_pl330_chan peripherals[0]; /* keep at end */ + + ? ? ? struct clk *clk; +}; +
Quoted 1 line
?#endif /*
__AMBA_PL330_H_*/
struct dma_pl330_dmac and struct dma_pl330_chan are internal to the pl330 dmac driver. Nobody from outside should ever need them.
Thanks,
Jassi
RFC PATCH 1/1 DMA: PL330: Update PL330 DMAC to support runtime PM
In reply to Chanwoo ChoiQuoted 6 lines · Chanwoo Choi
arch/arm/plat-samsung/dma-ops.c +4
-0+#ifdef CONFIG_PM_RUNTIME +struct dma_pl330_chan *pch; +struct dma_pl330_dmac *pdmac; +#endif dma_cap_zero (mask);
arch/arm/plat-samsung/dma-ops.c static unsigned samsung_dmadev_request(enum dma_ch dma_ch, · line 52
Quoted 10 lines
arch/arm/plat-samsung/dma-ops.c +6
-0dma_cap_set (info->cap, mask); chan =dma_request_channel (mask, pl330_filter, (void *)dma_ch); +#ifdef CONFIG_PM_RUNTIME + pch = container_of(chan, struct dma_pl330_chan, chan); + pdmac = pch->dmac; + +pm_runtime_get_sync (pdmac->pif.dev); +#endif
This is not the right way to do this. The pm runtime stuff should be internal to the PL330 driver. Take a moment to think about this:
You need to wake it up just before a transfer starts. You need to put it back to sleep just after the last transfer has finished. That gives you a hint where the calls need to be.
That can only be done from within the PL330 driver.
RFC PATCH 1/1 DMA: PL330: Update PL330 DMAC to support runtime PM
Quoted 21 lines · Russell King - ARM Linux
Quoted 6 lines · Chanwoo Choi
arch/arm/plat-samsung/dma-ops.c +4
-0+#ifdef CONFIG_PM_RUNTIME +struct dma_pl330_chan *pch; +struct dma_pl330_dmac *pdmac; +#endif dma_cap_zero (mask);arch/arm/plat-samsung/dma-ops.c static unsigned samsung_dmadev_request(enum dma_ch dma_ch, · line 52
Quoted 10 lines
arch/arm/plat-samsung/dma-ops.c +6
-0dma_cap_set (info->cap, mask); chan =dma_request_channel (mask, pl330_filter, (void *)dma_ch); +#ifdef CONFIG_PM_RUNTIME + pch = container_of(chan, struct dma_pl330_chan, chan); + pdmac = pch->dmac; + +pm_runtime_get_sync (pdmac->pif.dev); +#endif This is not the right way to do this. The pm runtime stuff should be internal to the PL330 driver. Take a moment to think about this:
Quoted 6 lines
You need to wake it up just before a transfer starts. You need to put it back to sleep just after the last transfer has finished. That gives you a hint where the calls need to be.
That can only be done from within the PL330 driver.
Thanks for your comment&hint.
I will repost the patch which support runtime pm of PL330 in internal to the PL330 driver.
Regards,
Chanwoo Choi
PATCH 1/15 DMA: PL330: Add support runtime PM for PL330 DMAC
In reply to Boojin KimQuoted 4 lines · Boojin Kim
Signed-off-by Boojin Kim <[email protected]>Cc Vinod Koul <[email protected]>Cc Dan Williams <[email protected]>Signed-off-by Kukjin Kim <[email protected]>
PATCH v5 2/15 DMA: PL330: Update PL330 DMA API driver
In reply to Boojin KimThis patch updates following 3 items.
1. Removes unneccessary code.
2. Add AMBA, PL330 configuration
3. Change the meaning of 'peri_id' variable from PL330 event number to specific dma id by user.
--- drivers/dma/Kconfig | 3 ++- drivers/dma/pl330.c | 13 ++++++++----- include/linux/amba/pl330.h | 6 +----- 3 files changed, 11 insertions(+), 11 deletions(-)
drivers/dma/Kconfig +2 -1
@@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL config PL330_DMA tristate "DMA API Driver for PL330" select DMA_ENGINE - depends on PL330 + depends on ARM_AMBA + select PL330 help Select if your platform has one or more PL330 DMACs. You need to provide platform specific settings via
drivers/dma/pl330.c +8 -5
@@ -69,6 +69,10 @@ struct dma_pl330_chan {* NULL if the channel is available to be acquired. */ void *pl330_chid; + +/* For D-to-M and M-to-D channels */ +int burst_sz;/* the peripheral fifo width */ +dma_addr_t fifo_addr; };struct dma_pl330_dmac {
@@ -455,7 +459,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)async_tx_ack (&desc->txd); desc->req.rqtype = peri->rqtype; - desc->req.peri = peri->peri_id; + desc->req.peri = pch->chan.chan_id;dma_async_tx_descriptor_init (&desc->txd, &pch->chan);
@@ -577,7 +581,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,struct dma_pl330_peri *peri = chan->private;struct scatterlist *sg;unsigned long flags; -int i, burst_size; +int i;dma_addr_t addr;if (unlikely (!pch || !sgl || !sg_len))
@@ -593,8 +597,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,return NULL ; } - addr = peri->fifo_addr; - burst_size = peri->burst_sz; + addr = pch->fifo_addr; first =NULL ;
@@ -642,7 +645,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, sg_dma_address(sg), addr, sg_dma_len(sg)); } - desc->rqcfg.brst_size = burst_size; + desc->rqcfg.brst_size = pch->burst_sz; desc->rqcfg.brst_len =1 ; }
include/linux/amba/pl330.h +1 -5
@@ -19,12 +19,8 @@ struct dma_pl330_peri {* Peri_Req i/f of the DMAC that is * peripheral could be reached from. */ -u8 peri_id;/* {0, 31} */ +u8 peri_id;/* specific dma id */ enum pl330_reqtype rqtype; - -/* For M->D and D->M Channels */ -int burst_sz;/* in power of 2 */ -dma_addr_t fifo_addr; };struct dma_pl330_platdata {
Signature · 1 line
1.7.1
PATCH v5 3/15 DMA: PL330: Support DMA_SLAVE_CONFIG command
In reply to Boojin Kim--- drivers/dma/pl330.c | 56 ++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 42 insertions(+), 14 deletions(-)
drivers/dma/pl330.c +42 -14
@@ -72,6 +72,7 @@ struct dma_pl330_chan {/* For D-to-M and M-to-D channels */ int burst_sz;/* the peripheral fifo width */ +int burst_len;/* the number of burst */ dma_addr_t fifo_addr; };
@@ -260,25 +261,52 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)static int pl330_control (struct dma_chan *chan,enum dma_ctrl_cmd cmd,unsigned long arg) {struct dma_pl330_chan *pch =to_pchan (chan); -struct dma_pl330_desc *desc; +struct dma_pl330_desc *desc, *_dt;unsigned long flags; +struct dma_pl330_dmac *pdmac = pch->dmac; +struct dma_slave_config *slave_config; +LIST_HEAD (list); -/* Only supports DMA_TERMINATE_ALL */ -if (cmd !=DMA_TERMINATE_ALL ) -return -ENXIO ; - -spin_lock_irqsave (&pch->lock, flags); - -/* FLUSH the PL330 Channel thread */ -pl330_chan_ctrl (pch->pl330_chid,PL330_OP_FLUSH ); +switch (cmd) { +case DMA_TERMINATE_ALL : +spin_lock_irqsave (&pch->lock, flags); -/* Mark all desc done */ -list_for_each_entry (desc, &pch->work_list, node) - desc->status =DONE ; +/* FLUSH the PL330 Channel thread */ +pl330_chan_ctrl (pch->pl330_chid,PL330_OP_FLUSH ); -spin_unlock_irqrestore (&pch->lock, flags); +/* Mark all desc done */ +list_for_each_entry_safe (desc, _dt, &pch->work_list , node) { + desc->status =DONE ; + pch->completed = desc->txd.cookie; +list_move_tail (&desc->node, &list); + } -pl330_tasklet ((unsigned long ) pch); +list_splice_tail_init (&list, &pdmac->desc_pool); +spin_unlock_irqrestore (&pch->lock, flags); +break ; +case DMA_SLAVE_CONFIG : + slave_config = (struct dma_slave_config *)arg; + +if (slave_config->direction ==DMA_TO_DEVICE ) { +if (slave_config->dst_addr) + pch->fifo_addr = slave_config->dst_addr; +if (slave_config->dst_addr_width) + pch->burst_sz =__ffs (slave_config->dst_addr_width); +if (slave_config->dst_maxburst) + pch->burst_len = slave_config->dst_maxburst; + }else if (slave_config->direction ==DMA_FROM_DEVICE ) { +if (slave_config->src_addr) + pch->fifo_addr = slave_config->src_addr; +if (slave_config->src_addr_width) + pch->burst_sz =__ffs (slave_config->src_addr_width); +if (slave_config->src_maxburst) + pch->burst_len = slave_config->src_maxburst; + } +break ; +default : +dev_err (pch->dmac->pif.dev,"Not supported command.\n" ); +return -ENXIO ; + }return 0 ; }
Signature · 1 line
1.7.1
PATCH v5 4/15 DMA: PL330: Add DMA_CYCLIC capability
In reply to Boojin KimThis patch adds DMA_CYCLIC capability that is used for audio driver. DMA driver activated with it reuses the dma requests that were submitted through tx_submit().
--- drivers/dma/pl330.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 95 insertions(+), 2 deletions(-)
drivers/dma/pl330.c +95 -2
@@ -42,6 +42,12 @@ enum desc_status { DONE, }; +enum cyclic_mode { +NO_CYCLIC , +CYCLIC_PREP , +CYCLIC_TRIGGER , +}; +struct dma_pl330_chan {/* Schedule desc completion */ struct tasklet_struct task;
@@ -74,6 +80,9 @@ struct dma_pl330_chan {int burst_sz;/* the peripheral fifo width */ int burst_len;/* the number of burst */ dma_addr_t fifo_addr; + +/* for cyclic capability */ +enum cyclic_mode cyclic; };struct dma_pl330_dmac {
@@ -160,6 +169,31 @@ static inline void free_desc_list(struct list_head *list)spin_unlock_irqrestore (&pdmac->pool_lock, flags); } +static inline void handle_cyclic_desc_list (struct list_head *list) +{ +struct dma_pl330_desc *desc; +struct dma_pl330_chan *pch; +unsigned long flags; + +if (list_empty (list)) +return ; + +list_for_each_entry (desc, list, node) { +dma_async_tx_callback callback; + +/* Change status to reload it */ + desc->status =PREP ; + pch = desc->pchan; + callback = desc->txd.callback; +if (callback) +callback (desc->txd.callback_param); + } + +spin_lock_irqsave (&pch->lock, flags); +list_splice_tail_init (list, &pch->work_list); +spin_unlock_irqrestore (&pch->lock, flags); +} +static inline void fill_queue (struct dma_pl330_chan *pch) {struct dma_pl330_desc *desc;
@@ -213,7 +247,10 @@ static void pl330_tasklet(unsigned long data)spin_unlock_irqrestore (&pch->lock, flags); -free_desc_list (&list); +if (pch->cyclic ==CYCLIC_TRIGGER ) +handle_cyclic_desc_list (&list); +else +free_desc_list (&list); }static void dma_pl330_rqcb (void *token,enum pl330_op_err err)
@@ -244,6 +281,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)spin_lock_irqsave (&pch->lock, flags); pch->completed = chan->cookie =1 ; + pch->cyclic =NO_CYCLIC ; pch->pl330_chid =pl330_request_channel (&pdmac->pif);if (!pch->pl330_chid) {
@@ -323,6 +361,9 @@ static void pl330_free_chan_resources(struct dma_chan *chan)pl330_release_channel (pch->pl330_chid); pch->pl330_chid =NULL ; +if (pch->cyclic) +list_splice_tail_init (&pch->work_list, &pch->dmac->desc_pool); +spin_unlock_irqrestore (&pch->lock, flags); }
@@ -346,7 +387,11 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,static void pl330_issue_pending (struct dma_chan *chan) { -pl330_tasklet ((unsigned long )to_pchan (chan)); +struct dma_pl330_chan *pch =to_pchan (chan); +pl330_tasklet ((unsigned long ) pch); + +if (pch->cyclic ==CYCLIC_PREP ) + pch->cyclic =CYCLIC_TRIGGER ; }/*
@@ -554,6 +599,52 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len)return burst_len; } +static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic ( +struct dma_chan *chan,dma_addr_t dma_addr,size_t len, +size_t period_len,enum dma_data_direction direction) +{ +struct dma_pl330_desc *desc; +struct dma_pl330_chan *pch =to_pchan (chan); +dma_addr_t dst; +dma_addr_t src; + + desc =pl330_get_desc (pch); +if (!desc) { +dev_err (pch->dmac->pif.dev,"%s:%d Unable to fetch desc\n" , + __func__, __LINE__); +return NULL ; + } + +switch (direction) { +case DMA_TO_DEVICE : + desc->rqcfg.src_inc =1 ; + desc->rqcfg.dst_inc =0 ; + src = dma_addr; + dst = pch->fifo_addr; +break ; +case DMA_FROM_DEVICE : + desc->rqcfg.src_inc =0 ; + desc->rqcfg.dst_inc =1 ; + src = pch->fifo_addr; + dst = dma_addr; +break ; +default : +dev_err (pch->dmac->pif.dev,"%s:%d Invalid dma direction\n" , + __func__, __LINE__); +return NULL ; + } + + desc->rqcfg.brst_size = pch->burst_sz; + desc->rqcfg.brst_len =1 ; + +if (!pch->cyclic) + pch->cyclic =CYCLIC_PREP ; + +fill_px (&desc->px, dst, src, period_len); + +return &desc->txd; +} +static struct dma_async_tx_descriptor *pl330_prep_dma_memcpy (struct dma_chan *chan,dma_addr_t dst,dma_addr_t src,size_t len,unsigned long flags)
@@ -786,6 +877,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)case MEMTODEV :case DEVTOMEM :dma_cap_set (DMA_SLAVE , pd->cap_mask); +dma_cap_set (DMA_CYCLIC , pd->cap_mask);break ;default :dev_err (&adev->dev,"DEVTODEV Not Supported\n" );
@@ -810,6 +902,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pd->device_alloc_chan_resources = pl330_alloc_chan_resources; pd->device_free_chan_resources = pl330_free_chan_resources; pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy; + pd->device_prep_dma_cyclic = pl330_prep_dma_cyclic; pd->device_tx_status = pl330_tx_status; pd->device_prep_slave_sg = pl330_prep_slave_sg; pd->device_control = pl330_control;
Signature · 1 line
1.7.1
PATCH v5 5/15 ARM: SAMSUNG: Update to use PL330-DMA driver
In reply to Boojin KimThis patch adds to support PL330-DMA driver on DMADEVICE for S5P SoCs.
---
arch/arm/mach-exynos4/include/mach/dma.h | 4 ++--
arch/arm/mach-s5p64x0/include/mach/dma.h | 2 +-
arch/arm/mach-s5pc100/include/mach/dma.h | 2 +-
arch/arm/mach-s5pv210/include/mach/dma.h | 2 +-
arch/arm/plat-samsung/Kconfig | 8 ++++++++
.../include/plat/{s3c-dma-pl330.h => dma-pl330.h} | 8 ++++----
.../plat-samsung/include/plat/s3c-pl330-pdata.h | 2 +-
7 files changed, 18 insertions(+), 10 deletions(-)
rename arch/arm/plat-samsung/include/plat/{s3c-dma-pl330.h => dma-pl330.h} (93%)arch/arm/mach-exynos4/include/mach/dma.h +2 -2
@@ -20,7 +20,7 @@#ifndef __MACH_DMA_H#define __MACH_DMA_H -/* This platform uses the common S3C DMA API driver for PL330 */ -#include <plat/s3c-dma-pl330.h> +/* This platform uses the common DMA API driver for PL330 */ +#include <plat/dma-pl330.h> #endif /* __MACH_DMA_H */
arch/arm/mach-s5p64x0/include/mach/dma.h +1 -1
@@ -21,6 +21,6 @@#define __MACH_DMA_H/* This platform uses the common S3C DMA API driver for PL330 */ -#include <plat/s3c-dma-pl330.h> +#include <plat/dma-pl330.h> #endif /* __MACH_DMA_H */
arch/arm/mach-s5pc100/include/mach/dma.h +1 -1
@@ -21,6 +21,6 @@#define __MACH_DMA_H/* This platform uses the common S3C DMA API driver for PL330 */ -#include <plat/s3c-dma-pl330.h> +#include <plat/dma-pl330.h> #endif /* __MACH_DMA_H */
arch/arm/mach-s5pv210/include/mach/dma.h +1 -1
@@ -21,6 +21,6 @@#define __MACH_DMA_H/* This platform uses the common S3C DMA API driver for PL330 */ -#include <plat/s3c-dma-pl330.h> +#include <plat/dma-pl330.h> #endif /* __MACH_DMA_H */
arch/arm/plat-samsung/Kconfig +8 -0
@@ -300,6 +300,14 @@ config S3C_PL330_DMA help S3C DMA API Driver for PL330 DMAC. +config SAMSUNG_DMA_PL330 + bool + select DMADEVICES + select PL330_DMA + select ARM_AMBA + help + Use DMA device engine for PL330 DMAC. + comment "Power management" config SAMSUNG_PM_DEBUG
arch/arm/plat-samsung/include/plat/dma-pl330.h renamed from arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h +4 -4
@@ -8,8 +8,8 @@* (at your option) any later version. */ -#ifndef __S3C_DMA_PL330_H_ -#define __S3C_DMA_PL330_H_ +#ifndef __DMA_PL330_H_ +#define __DMA_PL330_H_ __FILE__#define S3C2410_DMAF_AUTOSTART (1 << 0)#define S3C2410_DMAF_CIRCULAR (1 << 1)
@@ -20,7 +20,7 @@* For the sake of consistency across client drivers, * We keep the channel names unchanged and only add * missing peripherals are added. -* Order is not important since S3C PL330 API driver +* Order is not important since DMA PL330 API driver * use these just as IDs. */ enum dma_ch {
@@ -95,4 +95,4 @@ static inline bool s3c_dma_has_circular(void)#include <plat/dma.h> -#endif /* __S3C_DMA_PL330_H_ */ +#endif /* __DMA_PL330_H_ */
arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h +1 -1
@@ -12,7 +12,7 @@#ifndef __S3C_PL330_PDATA_H#define __S3C_PL330_PDATA_H -#include <plat/s3c-dma-pl330.h> +#include <plat/dma-pl330.h> /* * Every PL330 DMAC has max 32 peripheral interfaces,
Signature · 1 line
1.7.1
PATCH v5 6/15 ARM: SAMSUNG: Add common DMA operations
In reply to Boojin KimThis patch adds common DMA operations which are used for Samsung DMA drivers. Currently there are two types of DMA driver for Samsung SoCs. The one is S3C-DMA for S3C SoCs and the other is PL330-DMA for S5P SoCs. This patch provides funcion pointers for common DMA operations to DMA client driver like SPI and Audio. It makes DMA client drivers support multi-platform.
In addition, this common DMA operations implement the shared actions that are needed for DMA client driver. For example shared actions are filter() function for dma_request_channel() and parameter passing for device_prep_slave_sg().
--- arch/arm/mach-s3c2410/include/mach/dma.h | 8 ++- arch/arm/mach-s3c64xx/include/mach/dma.h | 4 + arch/arm/plat-samsung/Makefile | 6 +- arch/arm/plat-samsung/dma-ops.c | 130 +++++++++++++++++++++++ arch/arm/plat-samsung/include/plat/dma-ops.h | 63 +++++++++++ arch/arm/plat-samsung/include/plat/dma-pl330.h | 4 + arch/arm/plat-samsung/include/plat/dma.h | 1 + arch/arm/plat-samsung/s3c-dma-ops.c | 133 ++++++++++++++++++++++++ 8 files changed, 346 insertions(+), 3 deletions(-) create mode 100644 arch/arm/plat-samsung/dma-ops.c create mode 100644 arch/arm/plat-samsung/include/plat/dma-ops.h create mode 100644 arch/arm/plat-samsung/s3c-dma-ops.c
arch/arm/mach-s3c2410/include/mach/dma.h +7 -1
@@ -13,7 +13,6 @@#ifndef __ASM_ARCH_DMA_H#define __ASM_ARCH_DMA_H __FILE__ -#include <plat/dma.h> #include <linux/sysdev.h> #define MAX_DMA_TRANSFER_SIZE 0x100000/* Data Unit is half word */
@@ -51,6 +50,13 @@ enum dma_ch { DMACH_MAX, /* the end entry */ }; +static inline bool samsung_dma_is_dmadev (void ) +{ +return false; +} + +#include <plat/dma.h> +#define DMACH_LOW_LEVEL (1<<28)/* use this to specifiy hardware ch no */ /* we have 4 dma channels */
arch/arm/mach-s3c64xx/include/mach/dma.h +4 -0
@@ -63,6 +63,10 @@ static __inline__ bool s3c_dma_has_circular(void)return true; } +static inline bool samsung_dma_is_dmadev (void ) +{ +return false; +}#define S3C2410_DMAF_CIRCULAR (1 << 0)#include <plat/dma.h>
arch/arm/plat-samsung/Makefile +4 -2
@@ -62,9 +62,11 @@ obj-$(CONFIG_SAMSUNG_DEV_PWM) += dev-pwm.o # DMA support -obj-$(CONFIG_S3C_DMA) += dma.o +obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o -obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o +obj-$(CONFIG_SAMSUNG_DMA_PL330) += dma-ops.o + +obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o s3c-dma-ops.o # PM support
arch/arm/plat-samsung/dma-ops.c new file +130 -0
130 lines not on this page · raw message
arch/arm/plat-samsung/include/plat/dma-ops.h new file +63 -0
63 lines not on this page · raw message
arch/arm/plat-samsung/include/plat/dma-pl330.h +4 -0
@@ -93,6 +93,10 @@ static inline bool s3c_dma_has_circular(void) return true; } +static inline bool samsung_dma_is_dmadev (void ) +{ +return true; +}#include <plat/dma.h> #endif /* __DMA_PL330_H_ */
arch/arm/plat-samsung/include/plat/dma.h +1 -0
@@ -125,3 +125,4 @@ extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn);extern int s3c2410_dma_set_buffdone_fn (unsigned int ,s3c2410_dma_cbfn_t rtn); +#include <plat/dma-ops.h>
arch/arm/plat-samsung/s3c-dma-ops.c new file +133 -0
133 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH v5 7/15 ARM: EXYNOS4: Use generic DMA PL330 driver
In reply to Boojin KimThis patch makes Samsung EXYNOS4 to use DMA PL330 driver on DMADEVICE. The EXYNOS4 uses DMA generic APIs instead of SAMSUNG specific S3C-PL330 APIs.
--- arch/arm/mach-exynos4/Kconfig | 2 +- arch/arm/mach-exynos4/clock.c | 16 ++- arch/arm/mach-exynos4/dma.c | 299 ++++++++++++++++++++++++++--------------- 3 files changed, 198 insertions(+), 119 deletions(-)
arch/arm/mach-exynos4/Kconfig +1 -1
@@ -11,7 +11,7 @@ if ARCH_EXYNOS4 config CPU_EXYNOS4210 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 help Enable EXYNOS4210 CPU support
arch/arm/mach-exynos4/clock.c +9 -7
@@ -47,6 +47,11 @@ static struct clk clk_sclk_usbphy1 = { .id = -1, }; +static struct clk dummy_apb_pclk = { + .name ="apb_pclk" , + .id =-1 , +}; +static int exynos4_clksrc_mask_top_ctrl (struct clk *clk,int enable) {return s5p_gatectrl (S5P_CLKSRC_MASK_TOP , clk, enable);
@@ -485,16 +490,11 @@ static struct clk init_clocks_off[] = { .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 10), }, { - .name = "pdma", - .id = 0, + .name = "dma", + .id = -1, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 0), }, { - .name = "pdma", - .id = 1, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 1), - }, { .name = "adc", .id = -1, .enable = exynos4_clk_ip_peril_ctrl,
@@ -1212,5 +1212,7 @@ void __init exynos4_register_clocks(void)s3c_register_clocks (init_clocks_off,ARRAY_SIZE (init_clocks_off));s3c_disable_clocks (init_clocks_off,ARRAY_SIZE (init_clocks_off)); +s3c24xx_register_clock (&dummy_apb_pclk); +s3c_pwmclk_init (); }
arch/arm/mach-exynos4/dma.c +188 -111
339 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH 7/15 ARM: EXYNOS4: Use generic DMA PL330 driver
Hi Boojin,
Quoted 12 lines · Boojin Kim
This patch makes Samsung EXYNOS4 to use DMA PL330 driver on DMADEVICE. The EXYNOS4 uses DMA generic APIs instead of SAMSUNG specific S3C-PL330 APIs.
Signed-off-by Boojin Kim <[email protected]>Signed-off-by Kukjin Kim <[email protected]>---
?arch/arm/mach-exynos4/Kconfig | ? ?2 +- ?arch/arm/mach-exynos4/clock.c | ? 16 ++- ?arch/arm/mach-exynos4/dma.c ? | ?299 ++++++++++++++++++++++++++---------------?3 files changed, 198 insertions(+), 119 deletions(-)
[...]
Quoted 2 lines
arch/arm/mach-exynos4/dma.c +0
-0
[...]
Quoted 16 lines
+struct
amba_deviceexynos4_device_pdma0= {
+ ? ? ? .dev = {
+ ? ? ? ? ? ? ? .init_name = "dma-pl330.0",
? ? ? ? ? ? ? ?.dma_mask =&dma_dmamask,
? ? ? ? ? ? ? ?.coherent_dma_mask =DMA_BIT_MASK(32), ? ? ? ? ? ? ? ?.platform_data =&exynos4_pdma0_pdata, ? ? ? ?},
+ ? ? ? .res = {
+ ? ? ? ? ? ? ? .start =EXYNOS4_PA_PDMA0,
+ ? ? ? ? ? ? ? .end =EXYNOS4_PA_PDMA0+SZ_4K,
+ ? ? ? ? ? ? ? .flags =IORESOURCE_MEM,
+ ? ? ? },
+ ? ? ? .irq = {IRQ_PDMA0,NO_IRQ},
+ ? ? ? .periphid =0x00041330,
?};
[...]
Quoted 21 lines
+struct
amba_deviceexynos4_device_pdma1= {
+ ? ? ? .dev = {
+ ? ? ? ? ? ? ? .init_name = "dma-pl330.1",
? ? ? ? ? ? ? ?.dma_mask =&dma_dmamask,
? ? ? ? ? ? ? ?.coherent_dma_mask =DMA_BIT_MASK(32), ? ? ? ? ? ? ? ?.platform_data =&exynos4_pdma1_pdata, ? ? ? ?},arch/arm/mach-exynos4/dma.c +7
-5-}; - -static struct platform_device *exynos4_dmacs[]__initdata = { - ? ? ? &exynos4_device_pdma0, - ? ? ? &exynos4_device_pdma1, + ? ? ? .res = { + ? ? ? ? ? ? ? .start = EXYNOS4_PA_PDMA1, + ? ? ? ? ? ? ? .end = EXYNOS4_PA_PDMA1 + SZ_4K, + ? ? ? ? ? ? ? .flags = IORESOURCE_MEM, + ? ? ? }, + ? ? ? .irq = {IRQ_PDMA1, NO_IRQ}, + ? ? ? .periphid = 0x00041330,?};
Quoted 4 lines
?static int
__initexynos4_dma_init(void)
?{
- ? ? ?platform_add_devices(exynos4_dmacs, ARRAY_SIZE(exynos4_dmacs));
+ ? ? ?amba_device_register(&exynos4_device_pdma0, &iomem_resource);
How would the 'exynos4_device_pdma1' instance get registered? Should there be a amba_device_register call for 'exynos4_device_pdma1' instance as well?
Thanks,
Thomas.
PATCH 7/15 ARM: EXYNOS4: Use generic DMA PL330 driver
In reply to Boojin KimHi Boojin,
Quoted 12 lines · Boojin Kim
This patch makes Samsung EXYNOS4 to use DMA PL330 driver on DMADEVICE. The EXYNOS4 uses DMA generic APIs instead of SAMSUNG specific S3C-PL330 APIs.
Signed-off-by Boojin Kim <[email protected]>Signed-off-by Kukjin Kim <[email protected]>---
?arch/arm/mach-exynos4/Kconfig | ? ?2 +- ?arch/arm/mach-exynos4/clock.c | ? 16 ++- ?arch/arm/mach-exynos4/dma.c ? | ?299 ++++++++++++++++++++++++++---------------?3 files changed, 198 insertions(+), 119 deletions(-)
[...]
Quoted 2 lines
arch/arm/mach-exynos4/dma.c +0
-0
[...]
Quoted 5 lines
+struct
dma_pl330_peripdma0_peri[28] = {
+ ? ? ? {
+ ? ? ? ? ? ? ? .peri_id = (u8)DMACH_PCM0_RX,
+ ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
+ ? ? ? }, {
The client driver specifies the direction of the transfer (DMA_TO_DEVICE or DMA_FROM_DEVICE) when requesting for a dma channel. So, is the rqtype parameter required in the platform data for the dma driver?
Thanks,
Thomas.
PATCH 7/15 ARM: EXYNOS4: Use generic DMA PL330 driver
Quoted 10 lines · Thomas Abraham
Quoted 5 lines
+struct
dma_pl330_peripdma0_peri[28] = {
+ ? ? ? {
+ ? ? ? ? ? ? ? .peri_id = (u8)DMACH_PCM0_RX,
+ ? ? ? ? ? ? ? .rqtype = DEVTOMEM,
+ ? ? ? }, {The client driver specifies the direction of the transfer (
DMA_TO_DEVICEorDMA_FROM_DEVICE) when requesting for a dma channel. So, is the rqtype parameter required in the platform data for the dma driver?
That was done initially too with PL080, which has 8 uncommitted DMA channels. Peripheral drivers still had to pass the DMA direction. So it turned out to be entirely redundant information, so it got killed off, along with other channel specific configuration which drivers should've been doing via the slave configuration callback.
Passing lots of information via platform data which should come via other routes makes dmaengine users fragile - you can't tell whether they are passing the correct and full information necessary to work with other dmaengine drivers. So, the DMA engine platform data should only contain the absolute _minimum_ of information.
PATCH v5 8/15 ARM: S5PV210: Use generic DMA PL330 driver
In reply to Boojin KimThis patch makes Samsung S5PV210 to use DMA PL330 driver on DMADEVICE. The S5PV210 uses DMA generic APIs instead of SAMSUNG specific S3C-PL330 APIs.
--- arch/arm/mach-s5pv210/Kconfig | 2 +- arch/arm/mach-s5pv210/clock.c | 16 +- arch/arm/mach-s5pv210/dma.c | 316 +++++++++++++++++++----------- arch/arm/mach-s5pv210/include/mach/dma.h | 2 +- 4 files changed, 214 insertions(+), 122 deletions(-)
arch/arm/mach-s5pv210/Kconfig +1 -1
@@ -11,7 +11,7 @@ if ARCH_S5PV210 config CPU_S5PV210 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 select S5P_EXT_INT select S5P_HRT select S5PV210_PM if PM
arch/arm/mach-s5pv210/clock.c +8 -8
@@ -221,6 +221,11 @@ static struct clk clk_pcmcdclk2 = { .id = -1, }; +static struct clk dummy_apb_pclk = { + .name ="apb_pclk" , + .id =-1 , +}; +static struct clk *clkset_vpllsrc_list[] = { [0 ] = &clk_fin_vpll, [1 ] = &clk_sclk_hdmi27m,
@@ -311,18 +316,12 @@ static struct clk_ops clk_fout_apll_ops = {static struct clk init_clocks_off[] = { { - .name ="pdma" , - .id =0 , + .name ="dma" , + .id =-1 , .parent = &clk_hclk_psys.clk, .enable = s5pv210_clk_ip0_ctrl, .ctrlbit = (1 <<3 ), }, { - .name ="pdma" , - .id =1 , - .parent = &clk_hclk_psys.clk, - .enable = s5pv210_clk_ip0_ctrl, - .ctrlbit = (1 <<4 ), - }, { .name ="rot" , .id =-1 , .parent = &clk_hclk_dsys.clk,
@@ -1239,5 +1238,6 @@ void __init s5pv210_register_clocks(void)s3c_register_clocks (init_clocks_off,ARRAY_SIZE (init_clocks_off));s3c_disable_clocks (init_clocks_off,ARRAY_SIZE (init_clocks_off)); +s3c24xx_register_clock (&dummy_apb_pclk);s3c_pwmclk_init (); }
arch/arm/mach-s5pv210/dma.c +204 -112
359 lines not on this page · raw message
arch/arm/mach-s5pv210/include/mach/dma.h +1 -1
@@ -20,7 +20,7 @@#ifndef __MACH_DMA_H#define __MACH_DMA_H -/* This platform uses the common S3C DMA API driver for PL330 */ +/* This platform uses the common DMA API driver for PL330 */ #include <plat/dma-pl330.h> #endif /* __MACH_DMA_H */
Signature · 1 line
1.7.1
PATCH v5 9/15 ARM: S5PC100: Use generic DMA PL330 driver
In reply to Boojin KimThis patch makes Samsung S5PC100 to use DMA PL330 driver on DMADEVICE. The S5PC100 uses DMA generic APIs instead of SAMSUNG specific S3C-PL330 APIs.
--- arch/arm/mach-s5pc100/Kconfig | 2 +- arch/arm/mach-s5pc100/clock.c | 23 +-- arch/arm/mach-s5pc100/dma.c | 323 +++++++++++++++++++---------- arch/arm/mach-s5pc100/include/mach/dma.h | 2 +- 4 files changed, 222 insertions(+), 128 deletions(-)
arch/arm/mach-s5pc100/Kconfig +1 -1
@@ -10,7 +10,7 @@ if ARCH_S5PC100 config CPU_S5PC100 bool select S5P_EXT_INT - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 help Enable S5PC100 CPU support
arch/arm/mach-s5pc100/clock.c +9 -14
@@ -34,6 +34,11 @@ static struct clk s5p_clk_otgphy = { .id = -1, }; +static struct clk dummy_apb_pclk = { + .name ="apb_pclk" , + .id =-1 , +}; +static struct clk *clk_src_mout_href_list[] = { [0 ] = &s5p_clk_27m, [1 ] = &clk_fin_hpll,
@@ -416,12 +421,6 @@ static struct clk init_clocks_off[] = { .enable = s5pc100_d0_0_ctrl, .ctrlbit = (1 << 4), }, { - .name = "mdma", - .id = -1, - .parent = &clk_div_d0_bus.clk, - .enable = s5pc100_d0_0_ctrl, - .ctrlbit = (1 << 3), - }, { .name = "cfcon", .id = -1, .parent = &clk_div_d0_bus.clk,
@@ -488,14 +487,8 @@ static struct clk init_clocks_off[] = { .enable = s5pc100_d1_0_ctrl, .ctrlbit = (1 << 2), }, { - .name = "pdma", - .id = 1, - .parent = &clk_div_d1_bus.clk, - .enable = s5pc100_d1_0_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "pdma", - .id = 0, + .name = "dma", + .id = -1, .parent = &clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, .ctrlbit = (1 << 0),
@@ -1394,5 +1387,7 @@ void __init s5pc100_register_clocks(void)s3c_register_clocks (init_clocks_off,ARRAY_SIZE (init_clocks_off));s3c_disable_clocks (init_clocks_off,ARRAY_SIZE (init_clocks_off)); +s3c24xx_register_clock (&dummy_apb_pclk); +s3c_pwmclk_init (); }
arch/arm/mach-s5pc100/dma.c +211 -112
365 lines not on this page · raw message
arch/arm/mach-s5pc100/include/mach/dma.h +1 -1
@@ -20,7 +20,7 @@#ifndef __MACH_DMA_H#define __MACH_DMA_H -/* This platform uses the common S3C DMA API driver for PL330 */ +/* This platform uses the common DMA API driver for PL330 */ #include <plat/dma-pl330.h> #endif /* __MACH_DMA_H */
Signature · 1 line
1.7.1
PATCH v5 10/15 ARM: S5P64X0: Use generic DMA PL330 driver
In reply to Boojin KimThis patch makes Samsung S5P64X0 to use DMA PL330 driver on DMADEVICE. The S5P64X0 uses DMA generic APIs instead of SAMSUNG specific S3C-PL330 APIs.
--- arch/arm/mach-s5p64x0/Kconfig | 4 +- arch/arm/mach-s5p64x0/clock-s5p6440.c | 9 +- arch/arm/mach-s5p64x0/clock-s5p6450.c | 9 +- arch/arm/mach-s5p64x0/dma.c | 273 ++++++++++++++++++++---------- arch/arm/mach-s5p64x0/include/mach/dma.h | 2 +- 5 files changed, 201 insertions(+), 96 deletions(-)
arch/arm/mach-s5p64x0/Kconfig +2 -2
@@ -9,14 +9,14 @@ if ARCH_S5P64X0 config CPU_S5P6440 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 select S5P_HRT help Enable S5P6440 CPU support config CPU_S5P6450 bool - select S3C_PL330_DMA + select SAMSUNG_DMA_PL330 select S5P_HRT help Enable S5P6450 CPU support
arch/arm/mach-s5p64x0/clock-s5p6440.c +8 -1
@@ -153,7 +153,7 @@ static struct clk init_clocks_off[] = { .enable = s5p64x0_hclk0_ctrl, .ctrlbit = (1 << 8), }, { - .name = "pdma", + .name = "dma", .id = -1, .parent = &clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl,
@@ -533,6 +533,11 @@ static struct clksrc_clk *sysclks[] = { &clk_pclk_low, }; +static struct clk dummy_apb_pclk = { + .name ="apb_pclk" , + .id =-1 , +}; + void __init_or_cpufreq s5p6440_setup_clocks(void) {struct clk *xtal_clk;
@@ -615,5 +620,7 @@ void __init s5p6440_register_clocks(void)s3c_register_clocks (init_clocks_off,ARRAY_SIZE (init_clocks_off));s3c_disable_clocks (init_clocks_off,ARRAY_SIZE (init_clocks_off)); +s3c24xx_register_clock (&dummy_apb_pclk); +s3c_pwmclk_init (); }
arch/arm/mach-s5p64x0/clock-s5p6450.c +8 -1
@@ -189,7 +189,7 @@ static struct clk init_clocks_off[] = { .enable = s5p64x0_hclk0_ctrl, .ctrlbit = (1 << 3), }, { - .name = "pdma", + .name = "dma", .id = -1, .parent = &clk_hclk_low.clk, .enable = s5p64x0_hclk0_ctrl,
@@ -583,6 +583,11 @@ static struct clksrc_clk *sysclks[] = { &clk_sclk_audio0, }; +static struct clk dummy_apb_pclk = { + .name ="apb_pclk" , + .id =-1 , +}; + void __init_or_cpufreq s5p6450_setup_clocks(void) {struct clk *xtal_clk;
@@ -662,5 +667,7 @@ void __init s5p6450_register_clocks(void)s3c_register_clocks (init_clocks_off,ARRAY_SIZE (init_clocks_off));s3c_disable_clocks (init_clocks_off,ARRAY_SIZE (init_clocks_off)); +s3c24xx_register_clock (&dummy_apb_pclk); +s3c_pwmclk_init (); }
arch/arm/mach-s5p64x0/dma.c +182 -91
310 lines not on this page · raw message
arch/arm/mach-s5p64x0/include/mach/dma.h +1 -1
@@ -20,7 +20,7 @@#ifndef __MACH_DMA_H#define __MACH_DMA_H -/* This platform uses the common S3C DMA API driver for PL330 */ +/* This platform uses the common common DMA API driver for PL330 */ #include <plat/dma-pl330.h> #endif /* __MACH_DMA_H */
Signature · 1 line
1.7.1
PATCH v5 11/15 ARM: SAMSUNG: Remove S3C-PL330-DMA driver
In reply to Boojin KimSince DMA generic APIs can be used for Samsung DMA now so that the s3c-pl330 which includes Samsung specific DMA APIs can be removed.
--- arch/arm/plat-samsung/Kconfig | 6 - arch/arm/plat-samsung/Makefile | 2 - arch/arm/plat-samsung/include/plat/dma-pl330.h | 10 +- .../plat-samsung/include/plat/s3c-pl330-pdata.h | 32 - arch/arm/plat-samsung/s3c-pl330.c | 1244 -------------------- 5 files changed, 6 insertions(+), 1288 deletions(-) delete mode 100644 arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h delete mode 100644 arch/arm/plat-samsung/s3c-pl330.c
arch/arm/plat-samsung/Kconfig +0 -6
@@ -294,12 +294,6 @@ config S3C_DMA help Internal configuration for S3C DMA core -config S3C_PL330_DMA - bool - select PL330 - help - S3C DMA API Driver for PL330 DMAC. - config SAMSUNG_DMA_PL330 bool select DMADEVICES
arch/arm/plat-samsung/Makefile +0 -2
@@ -66,8 +66,6 @@ obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o obj-$(CONFIG_SAMSUNG_DMA_PL330) += dma-ops.o -obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o s3c-dma-ops.o - # PM support obj-$(CONFIG_PM) += pm.o
arch/arm/plat-samsung/include/plat/dma-pl330.h +6 -4
@@ -11,9 +11,6 @@#ifndef __DMA_PL330_H_#define __DMA_PL330_H_ __FILE__ -#define S3C2410_DMAF_AUTOSTART (1 << 0) -#define S3C2410_DMAF_CIRCULAR (1 << 1) -/* * PL330 can assign any channel to communicate with * any of the peripherals attched to the DMAC.
@@ -88,6 +85,10 @@ enum dma_ch { DMACH_MAX, }; +struct s3c2410_dma_client { +char *name; +}; +static inline bool s3c_dma_has_circular (void ) {return true;
@@ -97,6 +98,7 @@ static inline bool samsung_dma_is_dmadev(void) {return true; } -#include <plat/dma.h> + +#include <plat/dma-ops.h> #endif /* __DMA_PL330_H_ */
arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h deleted +0 -32
@@ -1,32 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h -* -* Copyright (C) 2010 Samsung Electronics Co. Ltd. -* Jaswinder Singh <[email protected]> -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -*/ - -#ifndef __S3C_PL330_PDATA_H -#define __S3C_PL330_PDATA_H - -#include <plat/dma-pl330.h> - -/* -* Every PL330 DMAC has max 32 peripheral interfaces, -* of which some may be not be really used in your -* DMAC's configuration. -* Populate this array of 32 peri i/fs with relevant -* channel IDs for used peri i/f and DMACH_MAX for -* those unused. -* -* The platforms just need to provide this info -* to the S3C DMA API driver for PL330. -*/ -struct s3c_pl330_platdata { -enum dma_ch peri[32 ]; -}; - -#endif /* __S3C_PL330_PDATA_H */
arch/arm/plat-samsung/s3c-pl330.c deleted +0 -1244
1,244 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH v5 12/15 spi/s3c64xx: Add support DMA engine API
In reply to Boojin KimThis patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs.
--- drivers/spi/spi_s3c64xx.c | 141 ++++++++++++++++++++++----------------------- 1 files changed, 69 insertions(+), 72 deletions(-)
drivers/spi/spi_s3c64xx.c +69 -72
@@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data {unsigned state;unsigned cur_mode, cur_bpw;unsigned cur_speed; +unsigned rx_ch; +unsigned tx_ch; +struct samsung_dma_ops *ops; };static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
@@ -227,6 +230,38 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)writel (val, regs +S3C64XX_SPI_CH_CFG ); } +static void s3c64xx_spi_dma_rxcb (void *data) +{ +struct s3c64xx_spi_driver_data *sdd + = (struct s3c64xx_spi_driver_data *)data; +unsigned long flags; + +spin_lock_irqsave (&sdd->lock, flags); + + sdd->state &= ~RXBUSY ; +/* If the other done */ +if (!(sdd->state &TXBUSY )) +complete (&sdd->xfer_completion); + +spin_unlock_irqrestore (&sdd->lock, flags); +} + +static void s3c64xx_spi_dma_txcb (void *data) +{ +struct s3c64xx_spi_driver_data *sdd + = (struct s3c64xx_spi_driver_data *)data; +unsigned long flags; + +spin_lock_irqsave (&sdd->lock, flags); + + sdd->state &= ~TXBUSY ; +/* If the other done */ +if (!(sdd->state &RXBUSY )) +complete (&sdd->xfer_completion); + +spin_unlock_irqrestore (&sdd->lock, flags); +} +static void enable_datapath (struct s3c64xx_spi_driver_data *sdd,struct spi_device *spi,struct spi_transfer *xfer,int dma_mode)
@@ -234,6 +269,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,struct s3c64xx_spi_info *sci = sdd->cntrlr_info;void __iomem *regs = sdd->regs;u32 modecfg, chcfg; +struct samsung_dma_prep_info info; modecfg =readl (regs +S3C64XX_SPI_MODE_CFG ); modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON |S3C64XX_SPI_MODE_RXDMA_ON );
@@ -259,10 +295,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, chcfg |=S3C64XX_SPI_CH_TXCH_ON ;if (dma_mode) { modecfg |=S3C64XX_SPI_MODE_TXDMA_ON ; -s3c2410_dma_config (sdd->tx_dmach, sdd->cur_bpw /8 ); -s3c2410_dma_enqueue (sdd->tx_dmach, (void *)sdd, - xfer->tx_dma, xfer->len); -s3c2410_dma_ctrl (sdd->tx_dmach,S3C2410_DMAOP_START ); + info.cap =DMA_SLAVE ; + info.direction =DMA_TO_DEVICE ; + info.buf = xfer->tx_dma; + info.len = xfer->len; + info.fp = s3c64xx_spi_dma_txcb; + info.fp_param = sdd; + sdd->ops->prepare (sdd->tx_ch, &info); + sdd->ops->trigger (sdd->tx_ch); }else {switch (sdd->cur_bpw) {case 32 :
@@ -294,10 +334,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,writel (((xfer->len *8 / sdd->cur_bpw) &0xffff ) |S3C64XX_SPI_PACKET_CNT_EN , regs +S3C64XX_SPI_PACKET_CNT ); -s3c2410_dma_config (sdd->rx_dmach, sdd->cur_bpw /8 ); -s3c2410_dma_enqueue (sdd->rx_dmach, (void *)sdd, - xfer->rx_dma, xfer->len); -s3c2410_dma_ctrl (sdd->rx_dmach,S3C2410_DMAOP_START ); + info.cap =DMA_SLAVE ; + info.direction =DMA_FROM_DEVICE ; + info.buf = xfer->rx_dma; + info.len = xfer->len; + info.fp = s3c64xx_spi_dma_rxcb; + info.fp_param = sdd; + sdd->ops->prepare (sdd->rx_ch, &info); + sdd->ops->trigger (sdd->rx_ch); } }
@@ -483,46 +527,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) } } -static void s3c64xx_spi_dma_rxcb (struct s3c2410_dma_chan *chan,void *buf_id, -int size,enum s3c2410_dma_buffresult res) -{ -struct s3c64xx_spi_driver_data *sdd = buf_id; -unsigned long flags; - -spin_lock_irqsave (&sdd->lock, flags); - -if (res ==S3C2410_RES_OK ) - sdd->state &= ~RXBUSY ; -else -dev_err (&sdd->pdev->dev,"DmaAbrtRx-%d\n" , size); - -/* If the other done */ -if (!(sdd->state &TXBUSY )) -complete (&sdd->xfer_completion); - -spin_unlock_irqrestore (&sdd->lock, flags); -} - -static void s3c64xx_spi_dma_txcb (struct s3c2410_dma_chan *chan,void *buf_id, -int size,enum s3c2410_dma_buffresult res) -{ -struct s3c64xx_spi_driver_data *sdd = buf_id; -unsigned long flags; - -spin_lock_irqsave (&sdd->lock, flags); - -if (res ==S3C2410_RES_OK ) - sdd->state &= ~TXBUSY ; -else -dev_err (&sdd->pdev->dev,"DmaAbrtTx-%d \n" , size); - -/* If the other done */ -if (!(sdd->state &RXBUSY )) -complete (&sdd->xfer_completion); - -spin_unlock_irqrestore (&sdd->lock, flags); -} -#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
@@ -697,12 +701,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,if (use_dma) {if (xfer->tx_buf !=NULL && (sdd->state &TXBUSY )) -s3c2410_dma_ctrl (sdd->tx_dmach, -S3C2410_DMAOP_FLUSH ); + sdd->ops->stop (sdd->tx_ch);if (xfer->rx_buf !=NULL && (sdd->state &RXBUSY )) -s3c2410_dma_ctrl (sdd->rx_dmach, -S3C2410_DMAOP_FLUSH ); + sdd->ops->stop (sdd->rx_ch); } goto out;
@@ -742,24 +744,19 @@ out:static int acquire_dma (struct s3c64xx_spi_driver_data *sdd) { -if (s3c2410_dma_request (sdd->rx_dmach, - &s3c64xx_spi_dma_client,NULL ) <0 ) { -dev_err (&sdd->pdev->dev,"cannot get RxDMA\n" ); -return 0 ; - } -s3c2410_dma_set_buffdone_fn (sdd->rx_dmach, s3c64xx_spi_dma_rxcb); -s3c2410_dma_devconfig (sdd->rx_dmach,S3C2410_DMASRC_HW , - sdd->sfr_start +S3C64XX_SPI_RX_DATA ); - -if (s3c2410_dma_request (sdd->tx_dmach, - &s3c64xx_spi_dma_client,NULL ) <0 ) { -dev_err (&sdd->pdev->dev,"cannot get TxDMA\n" ); -s3c2410_dma_free (sdd->rx_dmach, &s3c64xx_spi_dma_client); -return 0 ; - } -s3c2410_dma_set_buffdone_fn (sdd->tx_dmach, s3c64xx_spi_dma_txcb); -s3c2410_dma_devconfig (sdd->tx_dmach,S3C2410_DMASRC_MEM , - sdd->sfr_start +S3C64XX_SPI_TX_DATA ); + +struct samsung_dma_info info; + sdd->ops =samsung_dma_get_ops (); + + info.cap =DMA_SLAVE ; + info.client = &s3c64xx_spi_dma_client; + info.direction =DMA_FROM_DEVICE ; + info.fifo = sdd->sfr_start +S3C64XX_SPI_RX_DATA ; + info.width = sdd->cur_bpw /8 ; + sdd->rx_ch = sdd->ops->request (sdd->rx_dmach, &info); + info.direction =DMA_TO_DEVICE ; + info.fifo = sdd->sfr_start +S3C64XX_SPI_TX_DATA ; + sdd->tx_ch = sdd->ops->request (sdd->tx_dmach, &info);return 1 ; }
@@ -800,8 +797,8 @@ static void s3c64xx_spi_work(struct work_struct *work)spin_unlock_irqrestore (&sdd->lock, flags);/* Free DMA channels */ -s3c2410_dma_free (sdd->tx_dmach, &s3c64xx_spi_dma_client); -s3c2410_dma_free (sdd->rx_dmach, &s3c64xx_spi_dma_client); + sdd->ops->release (sdd->rx_ch, &s3c64xx_spi_dma_client); + sdd->ops->release (sdd->tx_ch, &s3c64xx_spi_dma_client); } static int s3c64xx_spi_transfer(struct spi_device *spi,
Signature · 1 line
1.7.1
PATCH 12/15 spi/s3c64xx: Add support DMA engine API
Quoted 27 lines · Boojin Kim
This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs.
Signed-off-by Boojin Kim <[email protected]>Acked-by Grant Likely <[email protected]>Signed-off-by Kukjin Kim <[email protected]>---
?drivers/spi/spi_s3c64xx.c | ?141 ++++++++++++++++++++++----------------------- ?1 files changed, 69 insertions(+), 72 deletions(-)drivers/spi/spi_s3c64xx.c +3
-0@@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data { ? ? ? ?unsigned ? ? ? ? ? ? ? ? ? ? ? ?state; ? ? ? ?unsigned ? ? ? ? ? ? ? ? ? ? ? ?cur_mode, cur_bpw; ? ? ? ?unsigned ? ? ? ? ? ? ? ? ? ? ? ?cur_speed; + ? ? ? unsigned ? ? ? ? ? ? ? ? ? ? ? ?rx_ch; + ? ? ? unsigned ? ? ? ? ? ? ? ? ? ? ? ?tx_ch; + ? ? ? struct samsung_dma_ops ? ? ? ? ?*ops; ?}; ?static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
drivers/spi/spi_s3c64xx.c static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) · line 236
Quoted 7 lines
drivers/spi/spi_s3c64xx.c +4
-0@@ -227,6 +230,38 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) ? ? ? ?writel(val, regs + S3C64XX_SPI_CH_CFG); ?} +static void s3c64xx_spi_dma_rxcb (void *data) +{ + ? ? ? struct s3c64xx_spi_driver_data *sdd + ? ? ? ? ? ? ? = (struct s3c64xx_spi_driver_data *)data;
void* doesn't need typecasting (same for all such occurances) IIRC someone already pointed it out?
Quoted 180 lines
drivers/spi/spi_s3c64xx.c +37
-4+ ? ? ? unsigned long flags; + + ? ? ? spin_lock_irqsave(&sdd->lock, flags); + + ? ? ? sdd->state &= ~RXBUSY; + ? ? ? /* If the other done */ + ? ? ? if (!(sdd->state & TXBUSY)) + ? ? ? ? ? ? ? complete(&sdd->xfer_completion); + + ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); +} + +static void s3c64xx_spi_dma_txcb (void *data) +{ + ? ? ? struct s3c64xx_spi_driver_data *sdd + ? ? ? ? ? ? ? = (struct s3c64xx_spi_driver_data *)data; + ? ? ? unsigned long flags; + + ? ? ? spin_lock_irqsave(&sdd->lock, flags); + + ? ? ? sdd->state &= ~TXBUSY; + ? ? ? /* If the other done */ + ? ? ? if (!(sdd->state & RXBUSY)) + ? ? ? ? ? ? ? complete(&sdd->xfer_completion); + + ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); +} + ?static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct spi_device *spi, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct spi_transfer *xfer, int dma_mode)@@ -234,6 +269,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ?struct s3c64xx_spi_info *sci = sdd->cntrlr_info; ? ? ? ?void __iomem *regs = sdd->regs; ? ? ? ?u32 modecfg, chcfg; + ? ? ? struct samsung_dma_prep_info info; ? ? ? ?modecfg = readl(regs + S3C64XX_SPI_MODE_CFG); ? ? ? ?modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);@@ -259,10 +295,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ?chcfg |= S3C64XX_SPI_CH_TXCH_ON; ? ? ? ? ? ? ? ?if (dma_mode) { ? ? ? ? ? ? ? ? ? ? ? ?modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? xfer->tx_dma, xfer->len); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START); + ? ? ? ? ? ? ? ? ? ? ? info.cap = DMA_SLAVE; + ? ? ? ? ? ? ? ? ? ? ? info.direction = DMA_TO_DEVICE; + ? ? ? ? ? ? ? ? ? ? ? info.buf = xfer->tx_dma; + ? ? ? ? ? ? ? ? ? ? ? info.len = xfer->len; + ? ? ? ? ? ? ? ? ? ? ? info.fp = s3c64xx_spi_dma_txcb; + ? ? ? ? ? ? ? ? ? ? ? info.fp_param = sdd; + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->prepare(sdd->tx_ch, &info); + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->trigger(sdd->tx_ch); ? ? ? ? ? ? ? ?} else { ? ? ? ? ? ? ? ? ? ? ? ?switch (sdd->cur_bpw) {? ? ? ? ? ? ? ? ? ? ? ?case 32:
drivers/spi/spi_s3c64xx.c +8
-44@@ -294,10 +334,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ? ? ? ? ?writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| S3C64XX_SPI_PACKET_CNT_EN, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?regs + S3C64XX_SPI_PACKET_CNT); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? xfer->rx_dma, xfer->len); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START); + ? ? ? ? ? ? ? ? ? ? ? info.cap = DMA_SLAVE; + ? ? ? ? ? ? ? ? ? ? ? info.direction = DMA_FROM_DEVICE; + ? ? ? ? ? ? ? ? ? ? ? info.buf = xfer->rx_dma; + ? ? ? ? ? ? ? ? ? ? ? info.len = xfer->len; + ? ? ? ? ? ? ? ? ? ? ? info.fp = s3c64xx_spi_dma_rxcb; + ? ? ? ? ? ? ? ? ? ? ? info.fp_param = sdd; + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->prepare(sdd->rx_ch, &info); + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->trigger(sdd->rx_ch); ? ? ? ? ? ? ? ?} ? ? ? ?}@@ -483,46 +527,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) ? ? ? ?} ?} -static void s3c64xx_spi_dma_rxcb (struct s3c2410_dma_chan *chan,void *buf_id, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int size, enum s3c2410_dma_buffresult res) -{ - ? ? ? struct s3c64xx_spi_driver_data *sdd = buf_id; - ? ? ? unsigned long flags; - - ? ? ? spin_lock_irqsave(&sdd->lock, flags); - - ? ? ? if (res == S3C2410_RES_OK) - ? ? ? ? ? ? ? sdd->state &= ~RXBUSY; - ? ? ? else - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size); - - ? ? ? /* If the other done */ - ? ? ? if (!(sdd->state & TXBUSY)) - ? ? ? ? ? ? ? complete(&sdd->xfer_completion); - - ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); -} - -static void s3c64xx_spi_dma_txcb (struct s3c2410_dma_chan *chan,void *buf_id, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int size, enum s3c2410_dma_buffresult res) -{ - ? ? ? struct s3c64xx_spi_driver_data *sdd = buf_id; - ? ? ? unsigned long flags; - - ? ? ? spin_lock_irqsave(&sdd->lock, flags); - - ? ? ? if (res == S3C2410_RES_OK) - ? ? ? ? ? ? ? sdd->state &= ~TXBUSY; - ? ? ? else - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size); - - ? ? ? /* If the other done */ - ? ? ? if (!(sdd->state & RXBUSY)) - ? ? ? ? ? ? ? complete(&sdd->xfer_completion); - - ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); -} - ?#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) ?static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,@@ -697,12 +701,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ? ? ? ? ?if (use_dma) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (
xfer->tx_buf!= NULL
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&& (sdd->state& TXBUSY))
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->tx_dmach,
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_DMAOP_FLUSH);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sdd->ops->stop(sdd->tx_ch); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (xfer->rx_buf!= NULL
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&& (sdd->state& RXBUSY))
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->rx_dmach,
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_DMAOP_FLUSH);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sdd->ops->stop(sdd->rx_ch); ? ? ? ? ? ? ? ? ? ? ? ?}? ? ? ? ? ? ? ? ? ? ? ?goto out;
drivers/spi/spi_s3c64xx.c +13
-18@@ -742,24 +744,19 @@ out: ?static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) ?{ - ? ? ? if (s3c2410_dma_request(sdd->rx_dmach, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &s3c64xx_spi_dma_client, NULL) < 0) { - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "cannot get RxDMA\n"); - ? ? ? ? ? ? ? return 0; - ? ? ? } - ? ? ? s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb); - ? ? ? s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sdd->sfr_start + S3C64XX_SPI_RX_DATA); - - ? ? ? if (s3c2410_dma_request(sdd->tx_dmach, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &s3c64xx_spi_dma_client, NULL) < 0) { - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "cannot get TxDMA\n"); - ? ? ? ? ? ? ? s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); - ? ? ? ? ? ? ? return 0; - ? ? ? } - ? ? ? s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb); - ? ? ? s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sdd->sfr_start + S3C64XX_SPI_TX_DATA); + + ? ? ? struct samsung_dma_info info; + ? ? ? sdd->ops = samsung_dma_get_ops(); + + ? ? ? info.cap = DMA_SLAVE; + ? ? ? info.client = &s3c64xx_spi_dma_client; + ? ? ? info.direction = DMA_FROM_DEVICE; + ? ? ? info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; + ? ? ? info.width = sdd->cur_bpw / 8; + ? ? ? sdd->rx_ch = sdd->ops->request(sdd->rx_dmach, &info); + ? ? ? info.direction = DMA_TO_DEVICE; + ? ? ? info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; + ? ? ? sdd->tx_ch = sdd->ops->request(sdd->tx_dmach, &info); ? ? ? ?return 1; ?}@@ -800,8 +797,8 @@ static void s3c64xx_spi_work(struct work_struct *work) ? ? ? ?spin_unlock_irqrestore(&sdd->lock, flags);
Quoted 6 lines
? ? ? ?/* Free DMA channels */
- ? ? ?s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
- ? ? ?s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
+ ? ? ?sdd->ops->release(sdd->rx_ch, &s3c64xx_spi_dma_client);
+ ? ? ?sdd->ops->release(sdd->tx_ch, &s3c64xx_spi_dma_client); ?}
Btw, this spi driver is for S3C64xx(with pl080) and S5P(with pl330) series, both of which
have DMAENGINE drivers. May be it could be directly switched to using those, rather than
via Samsung's wrapper driver.
Or am I overlooking something ?
PATCH 12/15 spi/s3c64xx: Add support DMA engine API
Am Montag 08 August 2011, 19:47:58 schrieb Jassi Brar:
Quoted 221 lines · Boojin Kim
Quoted 28 lines
This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs.
Signed-off-by Boojin Kim <[email protected]>Acked-by Grant Likely <[email protected]>Signed-off-by Kukjin Kim <[email protected]>--- drivers/spi/spi_s3c64xx.c | 141++++++++++++++++++++++----------------------- 1 files changed, 69 insertions(+), 72 deletions(-)
drivers/spi/spi_s3c64xx.c +3
-0@@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data {unsigned state;unsigned cur_mode, cur_bpw;unsigned cur_speed; +unsigned rx_ch; +unsigned tx_ch; +struct samsung_dma_ops *ops; };static struct s3c2410_dma_client s3c64xx_spi_dma_client = {drivers/spi/spi_s3c64xx.c static void flush_fifo(struct · line 236
Quoted 7 lines
drivers/spi/spi_s3c64xx.c +4
-0@@ -227,6 +230,38 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) writel(val, regs + S3C64XX_SPI_CH_CFG); } +static void s3c64xx_spi_dma_rxcb (void *data) +{ +struct s3c64xx_spi_driver_data *sdd + = (struct s3c64xx_spi_driver_data *)data;void* doesn't need typecasting (same for all such occurances) IIRC someone already pointed it out?
Quoted 181 lines
drivers/spi/spi_s3c64xx.c +28
-0+unsigned long flags; + +spin_lock_irqsave (&sdd->lock, flags); + + sdd->state &= ~RXBUSY ; +/* If the other done */ +if (!(sdd->state &TXBUSY )) +complete (&sdd->xfer_completion); + +spin_unlock_irqrestore (&sdd->lock, flags); +} + +static void s3c64xx_spi_dma_txcb (void *data) +{ +struct s3c64xx_spi_driver_data *sdd + = (struct s3c64xx_spi_driver_data *)data; +unsigned long flags; + +spin_lock_irqsave (&sdd->lock, flags); + + sdd->state &= ~TXBUSY ; +/* If the other done */ +if (!(sdd->state &RXBUSY )) +complete (&sdd->xfer_completion); + +spin_unlock_irqrestore (&sdd->lock, flags); +} +static void enable_datapath (struct s3c64xx_spi_driver_data *sdd,struct spi_device *spi,struct spi_transfer *xfer,int dma_mode)@@ -234,6 +269,7 @@ static void enable_datapath(struct
s3c64xx_spi_driver_data*sdd, structs3c64xx_spi_info*sci =sdd->cntrlr_info; void __iomem *regs = sdd->regs; u32 modecfg, chcfg;+ struct
samsung_dma_prep_infoinfo;modecfg = readl(regs + S3C64XX_SPI_MODE_CFG); modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON); @@ -259,10 +295,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, chcfg |= S3C64XX_SPI_CH_TXCH_ON; if (dma_mode) { modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;- s3c2410_dma_config(sdd->tx_dmach,
sdd->cur_bpw/
8); - s3c2410_dma_enqueue(sdd->tx_dmach, (void
*)sdd, -xfer->tx_dma,xfer->len); - s3c2410_dma_ctrl(sdd->tx_dmach,S3C2410_DMAOP_START); + info.cap =DMA_SLAVE;drivers/spi/spi_s3c64xx.c +7
-0+ info.direction =DMA_TO_DEVICE ; + info.buf = xfer->tx_dma; + info.len = xfer->len; + info.fp = s3c64xx_spi_dma_txcb; + info.fp_param = sdd; + sdd->ops->prepare (sdd->tx_ch, &info); + sdd->ops->trigger (sdd->tx_ch); }else {switch (sdd->cur_bpw) {case 32 :@@ -294,10 +334,14 @@ static void enable_datapath(struct
s3c64xx_spi_driver_data*sdd, writel(((xfer->len * 8 /sdd->cur_bpw) &0xffff) |S3C64XX_SPI_PACKET_CNT_EN, regs +S3C64XX_SPI_PACKET_CNT); -s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);drivers/spi/spi_s3c64xx.c +0
-2- s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd, - xfer->rx_dma,
xfer->len); - s3c2410_dma_ctrl(sdd->rx_dmach,S3C2410_DMAOP_START); + info.cap =DMA_SLAVE;drivers/spi/spi_s3c64xx.c +7
-19+ info.direction =DMA_FROM_DEVICE ; + info.buf = xfer->rx_dma; + info.len = xfer->len; + info.fp = s3c64xx_spi_dma_rxcb; + info.fp_param = sdd; + sdd->ops->prepare (sdd->rx_ch, &info); + sdd->ops->trigger (sdd->rx_ch); } }@@ -483,46 +527,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) } } -static void s3c64xx_spi_dma_rxcb (struct s3c2410_dma_chan *chan,void *buf_id, - int size, enum s3c2410_dma_buffresult res) -{ -struct s3c64xx_spi_driver_data *sdd = buf_id; -unsigned long flags; - -spin_lock_irqsave (&sdd->lock, flags); - -if (res ==S3C2410_RES_OK ) - sdd->state &= ~RXBUSY ; -else -dev_err (&sdd->pdev->dev,"DmaAbrtRx-%d\n" , size); - -/* If the other done */ -if (!(sdd->state &TXBUSY )) -complete (&sdd->xfer_completion); - -spin_unlock_irqrestore (&sdd->lock, flags); -} - -static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, - int size, enum
s3c2410_dma_buffresultres) -{drivers/spi/spi_s3c64xx.c +0
-19-struct s3c64xx_spi_driver_data *sdd = buf_id; -unsigned long flags; - -spin_lock_irqsave (&sdd->lock, flags); - -if (res ==S3C2410_RES_OK ) - sdd->state &= ~TXBUSY ; -else -dev_err (&sdd->pdev->dev,"DmaAbrtTx-%d \n" , size); - -/* If the other done */ -if (!(sdd->state &RXBUSY )) -complete (&sdd->xfer_completion); - -spin_unlock_irqrestore (&sdd->lock, flags); -} -#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,@@ -697,12 +701,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd, if (use_dma) {if (xfer->tx_buf !=NULL && (sdd->state &TXBUSY )) - s3c2410_dma_ctrl(sdd->tx_dmach, -
S3C2410_DMAOP_FLUSH); +sdd->ops->stop(sdd->tx_ch); if (xfer->rx_buf!= NULL&& (sdd->state & RXBUSY))drivers/spi/spi_s3c64xx.c +0
-2- s3c2410_dma_ctrl(sdd->rx_dmach, -
S3C2410_DMAOP_FLUSH); +sdd->ops->stop(sdd->rx_ch); }goto out;drivers/spi/spi_s3c64xx.c +0
-7@@ -742,24 +744,19 @@ out:static int acquire_dma (struct s3c64xx_spi_driver_data *sdd) { -if (s3c2410_dma_request (sdd->rx_dmach, - &s3c64xx_spi_dma_client,NULL ) < 0) { - dev_err(&sdd->pdev->dev, "cannot get RxDMA\n"); -return 0 ; - } -s3c2410_dma_set_buffdone_fn (sdd->rx_dmach, s3c64xx_spi_dma_rxcb); - s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW, - sdd->sfr_start +
S3C64XX_SPI_RX_DATA); -drivers/spi/spi_s3c64xx.c +0
-2- if (s3c2410_dma_request(sdd->tx_dmach, - &s3c64xx_spi_dma_client, NULL) <0) { -
dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");drivers/spi/spi_s3c64xx.c +0
-6-s3c2410_dma_free (sdd->rx_dmach, &s3c64xx_spi_dma_client); -return 0 ; - } -s3c2410_dma_set_buffdone_fn (sdd->tx_dmach, s3c64xx_spi_dma_txcb); - s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM, - sdd->sfr_start +
S3C64XX_SPI_TX_DATA); +drivers/spi/spi_s3c64xx.c +12
-0+struct samsung_dma_info info; + sdd->ops =samsung_dma_get_ops (); + + info.cap =DMA_SLAVE ; + info.client = &s3c64xx_spi_dma_client; + info.direction =DMA_FROM_DEVICE ; + info.fifo = sdd->sfr_start +S3C64XX_SPI_RX_DATA ; + info.width = sdd->cur_bpw /8 ; + sdd->rx_ch = sdd->ops->request (sdd->rx_dmach, &info); + info.direction =DMA_TO_DEVICE ; + info.fifo = sdd->sfr_start +S3C64XX_SPI_TX_DATA ; + sdd->tx_ch = sdd->ops->request (sdd->tx_dmach, &info);return 1 ; }@@ -800,8 +797,8 @@ static void s3c64xx_spi_work(struct work_struct *work) spin_unlock_irqrestore(&sdd->lock, flags);
Quoted 13 lines
drivers/spi/spi_s3c64xx.c static void s3c64xx_spi_work(struct work_struct *work) · line 802
Quoted 6 lines
drivers/spi/spi_s3c64xx.c +2
-2/* Free DMA channels */ -s3c2410_dma_free (sdd->tx_dmach, &s3c64xx_spi_dma_client); -s3c2410_dma_free (sdd->rx_dmach, &s3c64xx_spi_dma_client); + sdd->ops->release (sdd->rx_ch, &s3c64xx_spi_dma_client); + sdd->ops->release (sdd->tx_ch, &s3c64xx_spi_dma_client); }Btw, this spi driver is for S3C64xx(with pl080) and S5P(with pl330) series, both of which
have DMAENGINE drivers. May be it could be directly switched to using those, rather than
via Samsung's wrapper driver.
Or am I overlooking something ?
yep, at least the S3C2416/2450 HSSPI which should use this driver.
Heiko
PATCH 12/15 spi/s3c64xx: Add support DMA engine API
Quoted 9 lines · Heiko St?bner
Am Montag 08 August 2011, 19:47:58 schrieb Jassi Brar:
Quoted 6 lines
Btw, this spi driver is for S3C64xx(with pl080) and S5P(with pl330) series, both of which
have DMAENGINE drivers. May be it could be directly switched to using those, rather than
via Samsung's wrapper driver.
Or am I overlooking something ?yep, at least the S3C2416/2450 HSSPI which should use this driver.
Seems you keep some patches private ;) the spi driver isn't enabled for 2416 in mainline.
PATCH 12/15 spi/s3c64xx: Add support DMA engine API
Am Montag 08 August 2011, 20:16:58 schrieben Sie:
Quoted 9 lines · Heiko St?bner
Quoted 8 lines
Am Montag 08 August 2011, 19:47:58 schrieb Jassi Brar:
Quoted 6 lines
Btw, this spi driver is for S3C64xx(with pl080) and S5P(with pl330) series, both of which
have DMAENGINE drivers. May be it could be directly switched to using those, rather than
via Samsung's wrapper driver.
Or am I overlooking something ?
Quoted 4 lines
Quoted 1 line
yep, at least the S3C2416/2450 HSSPI which should use this driver.
Seems you keep some patches private ;) the spi driver isn't enabled for 2416 in mainline.
It's not so private [1], but isn't working yet :-). I'm still new to the whole kernel development stuff and seem to be the only one working on this device family.
I know from comparing s3c2416 and s3c64xx manuals that the hsspi part is the same but still have some learning to do to get it to work and also need drivers for the other side of the spi connection.
The Asus eeeReader DR-900 uses a wlan chip supported by libertas. So having a "verified" driver on the other side might help me in getting the spi driver to work.
Heiko
[1] https://gitorious.org/oyo-hack every e-book reader with Sipix display seems to be made from the same model line.
PATCH 12/15 spi/s3c64xx: Add support DMA engine API
In reply to Jassi BrarQuoted 219 lines · Jassi Brar
Quoted 27 lines · Boojin Kim
This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs.
Signed-off-by Boojin Kim <[email protected]>Acked-by Grant Likely <[email protected]>Signed-off-by Kukjin Kim <[email protected]>---
?drivers/spi/spi_s3c64xx.c | ?141 ++++++++++++++++++++++----------------------- ?1 files changed, 69 insertions(+), 72 deletions(-)drivers/spi/spi_s3c64xx.c +3
-0@@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data { ? ? ? ?unsigned ? ? ? ? ? ? ? ? ? ? ? ?state; ? ? ? ?unsigned ? ? ? ? ? ? ? ? ? ? ? ?cur_mode, cur_bpw; ? ? ? ?unsigned ? ? ? ? ? ? ? ? ? ? ? ?cur_speed; + ? ? ? unsigned ? ? ? ? ? ? ? ? ? ? ? ?rx_ch; + ? ? ? unsigned ? ? ? ? ? ? ? ? ? ? ? ?tx_ch; + ? ? ? struct samsung_dma_ops ? ? ? ? ?*ops; ?}; ?static struct s3c2410_dma_client s3c64xx_spi_dma_client = {drivers/spi/spi_s3c64xx.c static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) · line 236
Quoted 7 lines
drivers/spi/spi_s3c64xx.c +4
-0@@ -227,6 +230,38 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) ? ? ? ?writel(val, regs + S3C64XX_SPI_CH_CFG); ?} +static void s3c64xx_spi_dma_rxcb (void *data) +{ + ? ? ? struct s3c64xx_spi_driver_data *sdd + ? ? ? ? ? ? ? = (struct s3c64xx_spi_driver_data *)data;void* doesn't need typecasting (same for all such occurances) IIRC someone already pointed it out?
Quoted 180 lines
drivers/spi/spi_s3c64xx.c +37
-4+ ? ? ? unsigned long flags; + + ? ? ? spin_lock_irqsave(&sdd->lock, flags); + + ? ? ? sdd->state &= ~RXBUSY; + ? ? ? /* If the other done */ + ? ? ? if (!(sdd->state & TXBUSY)) + ? ? ? ? ? ? ? complete(&sdd->xfer_completion); + + ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); +} + +static void s3c64xx_spi_dma_txcb (void *data) +{ + ? ? ? struct s3c64xx_spi_driver_data *sdd + ? ? ? ? ? ? ? = (struct s3c64xx_spi_driver_data *)data; + ? ? ? unsigned long flags; + + ? ? ? spin_lock_irqsave(&sdd->lock, flags); + + ? ? ? sdd->state &= ~TXBUSY; + ? ? ? /* If the other done */ + ? ? ? if (!(sdd->state & RXBUSY)) + ? ? ? ? ? ? ? complete(&sdd->xfer_completion); + + ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); +} + ?static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct spi_device *spi, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct spi_transfer *xfer, int dma_mode)@@ -234,6 +269,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ?struct s3c64xx_spi_info *sci = sdd->cntrlr_info; ? ? ? ?void __iomem *regs = sdd->regs; ? ? ? ?u32 modecfg, chcfg; + ? ? ? struct samsung_dma_prep_info info; ? ? ? ?modecfg = readl(regs + S3C64XX_SPI_MODE_CFG); ? ? ? ?modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);@@ -259,10 +295,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ?chcfg |= S3C64XX_SPI_CH_TXCH_ON; ? ? ? ? ? ? ? ?if (dma_mode) { ? ? ? ? ? ? ? ? ? ? ? ?modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? xfer->tx_dma, xfer->len); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START); + ? ? ? ? ? ? ? ? ? ? ? info.cap = DMA_SLAVE; + ? ? ? ? ? ? ? ? ? ? ? info.direction = DMA_TO_DEVICE; + ? ? ? ? ? ? ? ? ? ? ? info.buf = xfer->tx_dma; + ? ? ? ? ? ? ? ? ? ? ? info.len = xfer->len; + ? ? ? ? ? ? ? ? ? ? ? info.fp = s3c64xx_spi_dma_txcb; + ? ? ? ? ? ? ? ? ? ? ? info.fp_param = sdd; + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->prepare(sdd->tx_ch, &info); + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->trigger(sdd->tx_ch); ? ? ? ? ? ? ? ?} else { ? ? ? ? ? ? ? ? ? ? ? ?switch (sdd->cur_bpw) {? ? ? ? ? ? ? ? ? ? ? ?case 32:
drivers/spi/spi_s3c64xx.c +8
-44@@ -294,10 +334,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ? ? ? ? ?writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| S3C64XX_SPI_PACKET_CNT_EN, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?regs + S3C64XX_SPI_PACKET_CNT); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? xfer->rx_dma, xfer->len); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START); + ? ? ? ? ? ? ? ? ? ? ? info.cap = DMA_SLAVE; + ? ? ? ? ? ? ? ? ? ? ? info.direction = DMA_FROM_DEVICE; + ? ? ? ? ? ? ? ? ? ? ? info.buf = xfer->rx_dma; + ? ? ? ? ? ? ? ? ? ? ? info.len = xfer->len; + ? ? ? ? ? ? ? ? ? ? ? info.fp = s3c64xx_spi_dma_rxcb; + ? ? ? ? ? ? ? ? ? ? ? info.fp_param = sdd; + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->prepare(sdd->rx_ch, &info); + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->trigger(sdd->rx_ch); ? ? ? ? ? ? ? ?} ? ? ? ?}@@ -483,46 +527,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) ? ? ? ?} ?} -static void s3c64xx_spi_dma_rxcb (struct s3c2410_dma_chan *chan,void *buf_id, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int size, enum s3c2410_dma_buffresult res) -{ - ? ? ? struct s3c64xx_spi_driver_data *sdd = buf_id; - ? ? ? unsigned long flags; - - ? ? ? spin_lock_irqsave(&sdd->lock, flags); - - ? ? ? if (res == S3C2410_RES_OK) - ? ? ? ? ? ? ? sdd->state &= ~RXBUSY; - ? ? ? else - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size); - - ? ? ? /* If the other done */ - ? ? ? if (!(sdd->state & TXBUSY)) - ? ? ? ? ? ? ? complete(&sdd->xfer_completion); - - ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); -} - -static void s3c64xx_spi_dma_txcb (struct s3c2410_dma_chan *chan,void *buf_id, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int size, enum s3c2410_dma_buffresult res) -{ - ? ? ? struct s3c64xx_spi_driver_data *sdd = buf_id; - ? ? ? unsigned long flags; - - ? ? ? spin_lock_irqsave(&sdd->lock, flags); - - ? ? ? if (res == S3C2410_RES_OK) - ? ? ? ? ? ? ? sdd->state &= ~TXBUSY; - ? ? ? else - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size); - - ? ? ? /* If the other done */ - ? ? ? if (!(sdd->state & RXBUSY)) - ? ? ? ? ? ? ? complete(&sdd->xfer_completion); - - ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); -} - ?#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) ?static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,@@ -697,12 +701,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ? ? ? ? ?if (use_dma) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (
xfer->tx_buf!= NULL
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&& (sdd->state& TXBUSY))
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->tx_dmach,
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_DMAOP_FLUSH);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sdd->ops->stop(sdd->tx_ch); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (xfer->rx_buf!= NULL
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&& (sdd->state& RXBUSY))
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->rx_dmach,
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_DMAOP_FLUSH);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sdd->ops->stop(sdd->rx_ch); ? ? ? ? ? ? ? ? ? ? ? ?}? ? ? ? ? ? ? ? ? ? ? ?goto out;
drivers/spi/spi_s3c64xx.c +13
-18@@ -742,24 +744,19 @@ out: ?static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) ?{ - ? ? ? if (s3c2410_dma_request(sdd->rx_dmach, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &s3c64xx_spi_dma_client, NULL) < 0) { - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "cannot get RxDMA\n"); - ? ? ? ? ? ? ? return 0; - ? ? ? } - ? ? ? s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb); - ? ? ? s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sdd->sfr_start + S3C64XX_SPI_RX_DATA); - - ? ? ? if (s3c2410_dma_request(sdd->tx_dmach, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &s3c64xx_spi_dma_client, NULL) < 0) { - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "cannot get TxDMA\n"); - ? ? ? ? ? ? ? s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); - ? ? ? ? ? ? ? return 0; - ? ? ? } - ? ? ? s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb); - ? ? ? s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sdd->sfr_start + S3C64XX_SPI_TX_DATA); + + ? ? ? struct samsung_dma_info info; + ? ? ? sdd->ops = samsung_dma_get_ops(); + + ? ? ? info.cap = DMA_SLAVE; + ? ? ? info.client = &s3c64xx_spi_dma_client; + ? ? ? info.direction = DMA_FROM_DEVICE; + ? ? ? info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; + ? ? ? info.width = sdd->cur_bpw / 8; + ? ? ? sdd->rx_ch = sdd->ops->request(sdd->rx_dmach, &info); + ? ? ? info.direction = DMA_TO_DEVICE; + ? ? ? info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; + ? ? ? sdd->tx_ch = sdd->ops->request(sdd->tx_dmach, &info); ? ? ? ?return 1; ?}@@ -800,8 +797,8 @@ static void s3c64xx_spi_work(struct work_struct *work) ? ? ? ?spin_unlock_irqrestore(&sdd->lock, flags);
Quoted 13 lines
Quoted 6 lines
? ? ? ?/* Free DMA channels */
- ? ? ?s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
- ? ? ?s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
+ ? ? ?sdd->ops->release(sdd->rx_ch, &s3c64xx_spi_dma_client);
+ ? ? ?sdd->ops->release(sdd->tx_ch, &s3c64xx_spi_dma_client); ?}Btw, this spi driver is for S3C64xx(with pl080) and S5P(with pl330) series, both of which
have DMAENGINE drivers. May be it could be directly switched to using those, rather than
via Samsung's wrapper driver.
Or am I overlooking something ?
Exactly, spi_s3c64xx.c (including Sound driver) can not be used with pl080 and pl330 (DMAENGINE drivers) as it is.
Recently I was trying to use PL080 DMAENGINE driver, and i was ended up using some #ifdef in the spi driver.
something like
#ifdef CONFIG_PL080sdd->tx_dmac.bus_id = dmatx_res->name; sdd->rx_dmac.bus_id = dmarx_res->name;
#elsesdd->tx_dmac.bus_id = dmatx_res->start; sdd->tx_dmac.bus_id = dmatx_res->start;
#endif
This is because, Pl080 handle the channel as a char *(name) and pl330 expect the channel to be enum (a number).
I think the solution could be changes in the either of these drivers to follow some symmetry or we will be ending up with
two client driver for the same device or writing up some unnecessary warper code or finally using some #ifdef.
Please suggest if you guys have any other idea/approach to handle such kind of situation.
Below is the git diff of spi_s3c64xx driver using with PL080 DMAENGINE driver. This patch is against kgene's next-samsung-dma-v4
------------------------------------------------------------------------------------------------------------------
drivers/spi/spi_s3c64xx.c +6 -0
@@ -24,6 +24,7 @@#include <linux/delay.h> #include <linux/clk.h> #include <linux/dma-mapping.h> +#include <linux/amba/pl08x.h> #include <linux/platform_device.h> #include <linux/spi/spi.h>
@@ -165,8 +166,13 @@ struct s3c64xx_spi_driver_data {struct work_struct work;struct list_head queue;spinlock_t lock; +#ifdef CONFIG_DMADEV_PL080 +struct pl08x_channel_data rx_dmach; +struct pl08x_channel_data tx_dmach; +#else enum dma_ch rx_dmach;enum dma_ch tx_dmach; +#endif unsigned long sfr_start;struct completion xfer_completion;unsigned state;
@@ -753,10 +759,18 @@ static int acquire_dma(struct
s3c64xx_spi_driver_data *sdd)
info.direction = DMA_FROM_DEVICE;
info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; info.width = sdd->cur_bpw / 8;
+#ifdef CONFIG_DMADEV_PL080
+ sdd->rx_ch = sdd->ops->request(sdd->rx_dmach.bus_id, &info);
+#else
sdd->rx_ch = sdd->ops->request(sdd->rx_dmach, &info);
+#endif
info.direction = DMA_TO_DEVICE;
info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
- sdd->tx_ch = sdd->ops->request(sdd->tx_dmach, &info);
+#ifdef CONFIG_DMADEV_PL080
+ sdd->tx_ch = sdd->ops->request(sdd->tx_dmach.bus_id, &info);
+#else
+ sdd->tx_ch = sdd->ops->request(sdd->tx_dmach, &info);
+#endif
return 1;
}
@@ -982,7 +996,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
}
/* Check for availability of necessary resource */
-
dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (dmatx_res == NULL) {
dev_err(&pdev->dev, "Unable to get SPI-Tx dma resource\n");
@@ -1015,9 +1028,13 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
sdd->cntrlr_info = sci;
sdd->pdev = pdev;
sdd->sfr_start = mem_res->start;
+#ifdef CONFIG_DMADEV_PL080
+ sdd->tx_dmach.bus_id = dmatx_res->name;
+ sdd->rx_dmach.bus_id = dmarx_res->name;
+#else
sdd->tx_dmach = dmatx_res->start;
sdd->rx_dmach = dmarx_res->start;
-
+#endif
sdd->cur_bpw = 8;
master->bus_num = pdev->id;
@@ -1105,7 +1122,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n",
mem_res->end, mem_res->start, sdd->rx_dmach, sdd->tx_dmach);
-
return 0;
err8:
----------------------------------------------------------------------------------------------------------------------
Regards,
Alim
Quoted 5 lines
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 12/15 spi/s3c64xx: Add support DMA engine API
Quoted 340 lines · Alim Akhtar
Quoted 219 lines · Jassi Brar
Quoted 27 lines · Boojin Kim
This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs.
Signed-off-by Boojin Kim <[email protected]>Acked-by Grant Likely <[email protected]>Signed-off-by Kukjin Kim <[email protected]>---
?drivers/spi/spi_s3c64xx.c | ?141 ++++++++++++++++++++++----------------------- ?1 files changed, 69 insertions(+), 72 deletions(-)drivers/spi/spi_s3c64xx.c +3
-0@@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data { ? ? ? ?unsigned ? ? ? ? ? ? ? ? ? ? ? ?state; ? ? ? ?unsigned ? ? ? ? ? ? ? ? ? ? ? ?cur_mode, cur_bpw; ? ? ? ?unsigned ? ? ? ? ? ? ? ? ? ? ? ?cur_speed; + ? ? ? unsigned ? ? ? ? ? ? ? ? ? ? ? ?rx_ch; + ? ? ? unsigned ? ? ? ? ? ? ? ? ? ? ? ?tx_ch; + ? ? ? struct samsung_dma_ops ? ? ? ? ?*ops; ?}; ?static struct s3c2410_dma_client s3c64xx_spi_dma_client = {drivers/spi/spi_s3c64xx.c static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) · line 236
Quoted 7 lines
drivers/spi/spi_s3c64xx.c +4
-0@@ -227,6 +230,38 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) ? ? ? ?writel(val, regs + S3C64XX_SPI_CH_CFG); ?} +static void s3c64xx_spi_dma_rxcb (void *data) +{ + ? ? ? struct s3c64xx_spi_driver_data *sdd + ? ? ? ? ? ? ? = (struct s3c64xx_spi_driver_data *)data;void* doesn't need typecasting (same for all such occurances) IIRC someone already pointed it out?
Quoted 180 lines
drivers/spi/spi_s3c64xx.c +37
-4+ ? ? ? unsigned long flags; + + ? ? ? spin_lock_irqsave(&sdd->lock, flags); + + ? ? ? sdd->state &= ~RXBUSY; + ? ? ? /* If the other done */ + ? ? ? if (!(sdd->state & TXBUSY)) + ? ? ? ? ? ? ? complete(&sdd->xfer_completion); + + ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); +} + +static void s3c64xx_spi_dma_txcb (void *data) +{ + ? ? ? struct s3c64xx_spi_driver_data *sdd + ? ? ? ? ? ? ? = (struct s3c64xx_spi_driver_data *)data; + ? ? ? unsigned long flags; + + ? ? ? spin_lock_irqsave(&sdd->lock, flags); + + ? ? ? sdd->state &= ~TXBUSY; + ? ? ? /* If the other done */ + ? ? ? if (!(sdd->state & RXBUSY)) + ? ? ? ? ? ? ? complete(&sdd->xfer_completion); + + ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); +} + ?static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct spi_device *spi, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct spi_transfer *xfer, int dma_mode)@@ -234,6 +269,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ?struct s3c64xx_spi_info *sci = sdd->cntrlr_info; ? ? ? ?void __iomem *regs = sdd->regs; ? ? ? ?u32 modecfg, chcfg; + ? ? ? struct samsung_dma_prep_info info; ? ? ? ?modecfg = readl(regs + S3C64XX_SPI_MODE_CFG); ? ? ? ?modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);@@ -259,10 +295,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ?chcfg |= S3C64XX_SPI_CH_TXCH_ON; ? ? ? ? ? ? ? ?if (dma_mode) { ? ? ? ? ? ? ? ? ? ? ? ?modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? xfer->tx_dma, xfer->len); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START); + ? ? ? ? ? ? ? ? ? ? ? info.cap = DMA_SLAVE; + ? ? ? ? ? ? ? ? ? ? ? info.direction = DMA_TO_DEVICE; + ? ? ? ? ? ? ? ? ? ? ? info.buf = xfer->tx_dma; + ? ? ? ? ? ? ? ? ? ? ? info.len = xfer->len; + ? ? ? ? ? ? ? ? ? ? ? info.fp = s3c64xx_spi_dma_txcb; + ? ? ? ? ? ? ? ? ? ? ? info.fp_param = sdd; + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->prepare(sdd->tx_ch, &info); + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->trigger(sdd->tx_ch); ? ? ? ? ? ? ? ?} else { ? ? ? ? ? ? ? ? ? ? ? ?switch (sdd->cur_bpw) {? ? ? ? ? ? ? ? ? ? ? ?case 32:
drivers/spi/spi_s3c64xx.c +8
-44@@ -294,10 +334,14 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ? ? ? ? ?writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| S3C64XX_SPI_PACKET_CNT_EN, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?regs + S3C64XX_SPI_PACKET_CNT); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? xfer->rx_dma, xfer->len); - ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START); + ? ? ? ? ? ? ? ? ? ? ? info.cap = DMA_SLAVE; + ? ? ? ? ? ? ? ? ? ? ? info.direction = DMA_FROM_DEVICE; + ? ? ? ? ? ? ? ? ? ? ? info.buf = xfer->rx_dma; + ? ? ? ? ? ? ? ? ? ? ? info.len = xfer->len; + ? ? ? ? ? ? ? ? ? ? ? info.fp = s3c64xx_spi_dma_rxcb; + ? ? ? ? ? ? ? ? ? ? ? info.fp_param = sdd; + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->prepare(sdd->rx_ch, &info); + ? ? ? ? ? ? ? ? ? ? ? sdd->ops->trigger(sdd->rx_ch); ? ? ? ? ? ? ? ?} ? ? ? ?}@@ -483,46 +527,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) ? ? ? ?} ?} -static void s3c64xx_spi_dma_rxcb (struct s3c2410_dma_chan *chan,void *buf_id, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int size, enum s3c2410_dma_buffresult res) -{ - ? ? ? struct s3c64xx_spi_driver_data *sdd = buf_id; - ? ? ? unsigned long flags; - - ? ? ? spin_lock_irqsave(&sdd->lock, flags); - - ? ? ? if (res == S3C2410_RES_OK) - ? ? ? ? ? ? ? sdd->state &= ~RXBUSY; - ? ? ? else - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size); - - ? ? ? /* If the other done */ - ? ? ? if (!(sdd->state & TXBUSY)) - ? ? ? ? ? ? ? complete(&sdd->xfer_completion); - - ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); -} - -static void s3c64xx_spi_dma_txcb (struct s3c2410_dma_chan *chan,void *buf_id, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int size, enum s3c2410_dma_buffresult res) -{ - ? ? ? struct s3c64xx_spi_driver_data *sdd = buf_id; - ? ? ? unsigned long flags; - - ? ? ? spin_lock_irqsave(&sdd->lock, flags); - - ? ? ? if (res == S3C2410_RES_OK) - ? ? ? ? ? ? ? sdd->state &= ~TXBUSY; - ? ? ? else - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size); - - ? ? ? /* If the other done */ - ? ? ? if (!(sdd->state & RXBUSY)) - ? ? ? ? ? ? ? complete(&sdd->xfer_completion); - - ? ? ? spin_unlock_irqrestore(&sdd->lock, flags); -} - ?#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) ?static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,@@ -697,12 +701,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd, ? ? ? ? ? ? ? ? ? ? ? ?if (use_dma) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (
xfer->tx_buf!= NULL
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&& (sdd->state& TXBUSY))
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->tx_dmach,
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_DMAOP_FLUSH);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sdd->ops->stop(sdd->tx_ch); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (xfer->rx_buf!= NULL
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&& (sdd->state& RXBUSY))
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? s3c2410_dma_ctrl(sdd->rx_dmach,
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_DMAOP_FLUSH);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sdd->ops->stop(sdd->rx_ch); ? ? ? ? ? ? ? ? ? ? ? ?}? ? ? ? ? ? ? ? ? ? ? ?goto out;
drivers/spi/spi_s3c64xx.c +13
-18@@ -742,24 +744,19 @@ out: ?static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) ?{ - ? ? ? if (s3c2410_dma_request(sdd->rx_dmach, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &s3c64xx_spi_dma_client, NULL) < 0) { - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "cannot get RxDMA\n"); - ? ? ? ? ? ? ? return 0; - ? ? ? } - ? ? ? s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb); - ? ? ? s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sdd->sfr_start + S3C64XX_SPI_RX_DATA); - - ? ? ? if (s3c2410_dma_request(sdd->tx_dmach, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &s3c64xx_spi_dma_client, NULL) < 0) { - ? ? ? ? ? ? ? dev_err(&sdd->pdev->dev, "cannot get TxDMA\n"); - ? ? ? ? ? ? ? s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); - ? ? ? ? ? ? ? return 0; - ? ? ? } - ? ? ? s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb); - ? ? ? s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sdd->sfr_start + S3C64XX_SPI_TX_DATA); + + ? ? ? struct samsung_dma_info info; + ? ? ? sdd->ops = samsung_dma_get_ops(); + + ? ? ? info.cap = DMA_SLAVE; + ? ? ? info.client = &s3c64xx_spi_dma_client; + ? ? ? info.direction = DMA_FROM_DEVICE; + ? ? ? info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; + ? ? ? info.width = sdd->cur_bpw / 8; + ? ? ? sdd->rx_ch = sdd->ops->request(sdd->rx_dmach, &info); + ? ? ? info.direction = DMA_TO_DEVICE; + ? ? ? info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; + ? ? ? sdd->tx_ch = sdd->ops->request(sdd->tx_dmach, &info); ? ? ? ?return 1; ?}@@ -800,8 +797,8 @@ static void s3c64xx_spi_work(struct work_struct *work) ? ? ? ?spin_unlock_irqrestore(&sdd->lock, flags);Quoted 13 lines
Quoted 6 lines
? ? ? ?/* Free DMA channels */
- ? ? ?s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
- ? ? ?s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
+ ? ? ?sdd->ops->release(sdd->rx_ch, &s3c64xx_spi_dma_client);
+ ? ? ?sdd->ops->release(sdd->tx_ch, &s3c64xx_spi_dma_client); ?}Btw, this spi driver is for S3C64xx(with pl080) and S5P(with pl330) series, both of which
have DMAENGINE drivers. May be it could be directly switched to using those, rather than
via Samsung's wrapper driver.
Or am I overlooking something ?Exactly,
spi_s3c64xx.c(including Sound driver) can not be used with pl080 and pl330 (DMAENGINE drivers) as it is.
Recently I was trying to use PL080 DMAENGINE driver, and i was ended up using some #ifdef in the spi driver.
something like
#ifdefCONFIG_PL080sdd->tx_dmac.bus_id=dmatx_res->name;sdd->rx_dmac.bus_id=dmarx_res->name;
#elsesdd->tx_dmac.bus_id=dmatx_res->start;sdd->tx_dmac.bus_id=dmatx_res->start;
#endifThis is because, Pl080 handle the channel as a char *(name) and pl330 expect the channel to be enum (a number).
I think the solution could be changes in the either of these drivers to follow some symmetry or we will be ending up with
two client driver for the same device or writing up some unnecessary warper code or finally using some #ifdef.Please suggest if you guys have any other idea/approach to handle such kind of situation.
Below is the git diff of
spi_s3c64xxdriver using with PL080 DMAENGINE driver. This patch is against kgene's next-samsung-dma-v4
------------------------------------------------------------------------------------------------------------------drivers/spi/spi_s3c64xx.c +0
-0@@ -24,6 +24,7 @@?#include <
linux/delay.h>
?#include <linux/clk.h>
?#include <linux/dma-mapping.h>
+#include <linux/amba/pl08x.h>
?#include <linux/platform_device.h>
?#include <linux/spi/spi.h>drivers/spi/spi_s3c64xx.c +14
-1@@ -165,8 +166,13 @@ struct s3c64xx_spi_driver_data { ? ? ? ?struct work_struct ? ? ? ? ? ? ?work; ? ? ? ?struct list_head ? ? ? ? ? ? ? ?queue; ? ? ? ?spinlock_t ? ? ? ? ? ? ? ? ? ? ?lock; +#ifdef CONFIG_DMADEV_PL080 + ? ? ? struct pl08x_channel_data ? ? ? rx_dmach; + ? ? ? struct pl08x_channel_data ? ? ? tx_dmach; +#else ? ? ? ?enum dma_ch ? ? ? ? ? ? ? ? ? ? rx_dmach; ? ? ? ?enum dma_ch ? ? ? ? ? ? ? ? ? ? tx_dmach; +#endif ? ? ? ?unsigned long ? ? ? ? ? ? ? ? ? sfr_start; ? ? ? ?struct completion ? ? ? ? ? ? ? xfer_completion; ? ? ? ?unsigned ? ? ? ? ? ? ? ? ? ? ? ?state;@@ -753,10 +759,18 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) ? ? ? ?info.direction = DMA_FROM_DEVICE; ? ? ? ?info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; ? ? ? ?info.width = sdd->cur_bpw / 8; +#ifdef CONFIG_DMADEV_PL080 + ? ? ? sdd->rx_ch = sdd->ops->request(sdd->rx_dmach.bus_id, &info); +#else ? ? ? ?sdd->rx_ch = sdd->ops->request(sdd->rx_dmach, &info); +#endif ? ? ? ?info.direction = DMA_TO_DEVICE; ? ? ? ?info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; - ? ? ? sdd->tx_ch = sdd->ops->request(sdd->tx_dmach, &info); +#ifdef CONFIG_DMADEV_PL080 + ? ? ? sdd->tx_ch = sdd->ops->request(sdd->tx_dmach.bus_id, &info); +#else + ? ? ? ? ? ? ? sdd->tx_ch = sdd->ops->request(sdd->tx_dmach, &info); +#endif ? ? ? ?return 1;?}
drivers/spi/spi_s3c64xx.c +0
-0@@ -982,7 +996,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) ? ? ? ?}? ? ? ?/* Check for availability of necessary resource */
-
? ? ? ?dmatx_res =platform_get_resource(pdev, IORESOURCE_DMA, 0); ? ? ? ?if (dmatx_res== NULL) {
? ? ? ? ? ? ? ?dev_err(&pdev->dev, "Unable to get SPI-Tx dma resource\n");drivers/spi/spi_s3c64xx.c +5
-1@@ -1015,9 +1028,13 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) ? ? ? ?sdd->cntrlr_info = sci; ? ? ? ?sdd->pdev = pdev; ? ? ? ?sdd->sfr_start = mem_res->start; +#ifdef CONFIG_DMADEV_PL080 + ? ? ? sdd->tx_dmach.bus_id = dmatx_res->name; + ? ? ? sdd->rx_dmach.bus_id = dmarx_res->name; +#else ? ? ? ?sdd->tx_dmach = dmatx_res->start; ? ? ? ?sdd->rx_dmach = dmarx_res->start; - +#endif ? ? ? ?sdd->cur_bpw = 8;? ? ? ?master->bus_num =
pdev->id;drivers/spi/spi_s3c64xx.c +0
-1@@ -1105,7 +1122,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) ? ? ? ?dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?mem_res->end, mem_res->start, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sdd->rx_dmach, sdd->tx_dmach); - ? ? ? ?return 0;
Quoted 3 lines
?err8:
----------------------------------------------------------------------------------------------------------------------
Hi All,
Any suggestions/comments on my concerns?
Thanks!
Quoted 11 lines
Regards,
AlimQuoted 5 lines
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 12/15 spi/s3c64xx: Add support DMA engine API
In reply to Alim AkhtarQuoted 13 lines · Alim Akhtar
Exactly,
spi_s3c64xx.c(including Sound driver) can not be used with pl080 and pl330 (DMAENGINE drivers) as it is.
Recently I was trying to use PL080 DMAENGINE driver, and i was ended up using some #ifdef in the spi driver.
something like
#ifdefCONFIG_PL080sdd->tx_dmac.bus_id=dmatx_res->name;sdd->rx_dmac.bus_id=dmarx_res->name;
#elsesdd->tx_dmac.bus_id=dmatx_res->start;sdd->tx_dmac.bus_id=dmatx_res->start;
#endif
Quoted 2 lines
This is because, Pl080 handle the channel as a char *(name) and pl330 expect the channel to be enum (a number).
The alternative is that you do as the Primecell drivers do (which was designed from the outset to be independent of the specific dmaengine), and pass the DMA filter parameters as pointers via platform data.
PATCH 12/15 spi/s3c64xx: Add support DMA engine API
Quoted 14 lines · Russell King - ARM Linux
Quoted 13 lines · Alim Akhtar
Exactly,
spi_s3c64xx.c(including Sound driver) can not be used with pl080 and pl330 (DMAENGINE drivers) as it is.
Recently I was trying to use PL080 DMAENGINE driver, and i was ended up using some #ifdef in the spi driver.
something like
#ifdefCONFIG_PL080sdd->tx_dmac.bus_id=dmatx_res->name;sdd->rx_dmac.bus_id=dmarx_res->name;
#elsesdd->tx_dmac.bus_id=dmatx_res->start;sdd->tx_dmac.bus_id=dmatx_res->start;
#endif
Quoted 7 lines
Quoted 2 lines
This is because, Pl080 handle the channel as a char *(name) and pl330 expect the channel to be enum (a number).
The alternative is that you do as the Primecell drivers do (which was designed from the outset to be independent of the specific dmaengine), and pass the DMA filter parameters as pointers via platform data.
Thanks Russell for your suggestion and pointer.
I will Look into this alternative solution.
Regards,
Alim
PATCH v5 12/15 spi/s3c64xx: Add support DMA engine API
In reply to Jassi BrarJassi Brar Wrote:
Quoted 41 lines
Sent: Tuesday, August 09, 2011 2:48 AM
To: Boojin Kim
Cc: linux-arm-kernel at lists.infradead.org; linux-samsung- soc at vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Mark Brown; Grant Likely; Russell King
Subject: Re: [PATCH 12/15] spi/s3c64xx: Add support DMA engine APIQuoted 10 lines · Boojin Kim
This patch adds to support DMA generic API to transfer raw SPI data. Basiclly the spi driver uses DMA generic API if architecture supports it. Otherwise, uses Samsung specific S3C-PL330 APIs.
Signed-off-by Boojin Kim <[email protected]>Acked-by Grant Likely <[email protected]>Signed-off-by Kukjin Kim <[email protected]>--- drivers/spi/spi_s3c64xx.c | 141 ++++++++++++++++++++++-----------------------
drivers/spi/spi_s3c64xx.c static void flush_fifo(struct
Quoted 17 lines
1 files changed, 69 insertions(+), 72 deletions(-)drivers/spi/spi_s3c64xx.c +3
-0@@ -172,6 +172,9 @@ struct s3c64xx_spi_driver_data {unsigned state;unsigned cur_mode, cur_bpw;unsigned cur_speed; +unsigned rx_ch; +unsigned tx_ch; +struct samsung_dma_ops *ops; };static struct s3c2410_dma_client s3c64xx_spi_dma_client = {@@ -227,6 +230,38 @@ static void flush_fifo(struct
s3c64xx_spi_driver_data*sdd)Quoted 3 lines
drivers/spi/spi_s3c64xx.c +0
-0writel (val, regs +S3C64XX_SPI_CH_CFG ); }
Quoted 6 lines
drivers/spi/spi_s3c64xx.c static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) · line 236
Quoted 4 lines
drivers/spi/spi_s3c64xx.c +4
-0+static void s3c64xx_spi_dma_rxcb (void *data) +{ +struct s3c64xx_spi_driver_data *sdd + = (struct s3c64xx_spi_driver_data *)data;void* doesn't need typecasting (same for all such occurances) IIRC someone already pointed it out?
I'm sorry for late response. (I was in vacation.)
This comment was reflected on 13/15 patch.
Quoted 213 lines
drivers/spi/spi_s3c64xx.c static void enable_datapath(struct
Quoted 34 lines
drivers/spi/spi_s3c64xx.c +28
-0+unsigned long flags; + +spin_lock_irqsave (&sdd->lock, flags); + + sdd->state &= ~RXBUSY ; +/* If the other done */ +if (!(sdd->state &TXBUSY )) +complete (&sdd->xfer_completion); + +spin_unlock_irqrestore (&sdd->lock, flags); +} + +static void s3c64xx_spi_dma_txcb (void *data) +{ +struct s3c64xx_spi_driver_data *sdd + = (struct s3c64xx_spi_driver_data *)data; +unsigned long flags; + +spin_lock_irqsave (&sdd->lock, flags); + + sdd->state &= ~TXBUSY ; +/* If the other done */ +if (!(sdd->state &RXBUSY )) +complete (&sdd->xfer_completion); + +spin_unlock_irqrestore (&sdd->lock, flags); +} +static void enable_datapath (struct s3c64xx_spi_driver_data *sdd,struct spi_device *spi,struct spi_transfer *xfer,int dma_mode)@@ -234,6 +269,7 @@ static void enable_datapath(struct
s3c64xx_spi_driver_data*sdd,drivers/spi/spi_s3c64xx.c static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
Quoted 7 lines
drivers/spi/spi_s3c64xx.c +1
-0struct s3c64xx_spi_info *sci = sdd->cntrlr_info;void __iomem *regs = sdd->regs;u32 modecfg, chcfg; +struct samsung_dma_prep_info info; modecfg =readl (regs +S3C64XX_SPI_MODE_CFG ); modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON |
S3C64XX_SPI_MODE_RXDMA_ON);drivers/spi/spi_s3c64xx.c static void enable_datapath(struct
Quoted 1 line
drivers/spi/spi_s3c64xx.c +0
-0@@ -259,10 +295,14 @@ static void enable_datapath(struct
s3c64xx_spi_driver_data*sdd,drivers/spi/spi_s3c64xx.c static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
Quoted 4 lines
drivers/spi/spi_s3c64xx.c +0
-1chcfg |=S3C64XX_SPI_CH_TXCH_ON ;if (dma_mode) { modecfg |=S3C64XX_SPI_MODE_TXDMA_ON ; - s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw/ 8);
drivers/spi/spi_s3c64xx.c static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
Quoted 3 lines
drivers/spi/spi_s3c64xx.c +0
-3-s3c2410_dma_enqueue (sdd->tx_dmach, (void *)sdd, - xfer->tx_dma, xfer->len); - s3c2410_dma_ctrl(sdd->tx_dmach,
S3C2410_DMAOP_START);drivers/spi/spi_s3c64xx.c static void enable_datapath(struct
Quoted 12 lines
drivers/spi/spi_s3c64xx.c +8
-0+ info.cap =DMA_SLAVE ; + info.direction =DMA_TO_DEVICE ; + info.buf = xfer->tx_dma; + info.len = xfer->len; + info.fp = s3c64xx_spi_dma_txcb; + info.fp_param = sdd; + sdd->ops->prepare (sdd->tx_ch, &info); + sdd->ops->trigger (sdd->tx_ch); }else {switch (sdd->cur_bpw) {case 32 :@@ -294,10 +334,14 @@ static void enable_datapath(struct
s3c64xx_spi_driver_data*sdd,drivers/spi/spi_s3c64xx.c static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
Quoted 4 lines
drivers/spi/spi_s3c64xx.c +0
-1writel (((xfer->len *8 / sdd->cur_bpw) &0xffff ) |S3C64XX_SPI_PACKET_CNT_EN , regs +S3C64XX_SPI_PACKET_CNT ); - s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw/ 8);
drivers/spi/spi_s3c64xx.c static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
Quoted 3 lines
drivers/spi/spi_s3c64xx.c +0
-3-s3c2410_dma_enqueue (sdd->rx_dmach, (void *)sdd, - xfer->rx_dma, xfer->len); - s3c2410_dma_ctrl(sdd->rx_dmach,
S3C2410_DMAOP_START);drivers/spi/spi_s3c64xx.c static void s3c64xx_spi_config(struct
Quoted 12 lines
drivers/spi/spi_s3c64xx.c +8
-0+ info.cap =DMA_SLAVE ; + info.direction =DMA_FROM_DEVICE ; + info.buf = xfer->rx_dma; + info.len = xfer->len; + info.fp = s3c64xx_spi_dma_rxcb; + info.fp_param = sdd; + sdd->ops->prepare (sdd->rx_ch, &info); + sdd->ops->trigger (sdd->rx_ch); } }@@ -483,46 +527,6 @@ static void s3c64xx_spi_config(struct
s3c64xx_spi_driver_data*sdd)drivers/spi/spi_s3c64xx.c static void s3c64xx_spi_config(struct · line 486
Quoted 4 lines
drivers/spi/spi_s3c64xx.c +0
-1} } -static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan,void
*buf_id,drivers/spi/spi_s3c64xx.c static void s3c64xx_spi_config(struct · line 487
Quoted 1 line
drivers/spi/spi_s3c64xx.c +0
-1- int size, enum s3c2410_dma_buffresultres)
Quoted 9 lines
drivers/spi/spi_s3c64xx.c +0
-9-{ -struct s3c64xx_spi_driver_data *sdd = buf_id; -unsigned long flags; - -spin_lock_irqsave (&sdd->lock, flags); - -if (res ==S3C2410_RES_OK ) - sdd->state &= ~RXBUSY ; -else drivers/spi/spi_s3c64xx.c static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
Quoted 10 lines
drivers/spi/spi_s3c64xx.c +0
-10-dev_err (&sdd->pdev->dev,"DmaAbrtRx-%d\n" , size); - -/* If the other done */ -if (!(sdd->state &TXBUSY )) -complete (&sdd->xfer_completion); - -spin_unlock_irqrestore (&sdd->lock, flags); -} - -static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan,void
*buf_id,drivers/spi/spi_s3c64xx.c static void s3c64xx_spi_config(struct · line 507
Quoted 1 line
drivers/spi/spi_s3c64xx.c +0
-1- int size, enum s3c2410_dma_buffresultres)
drivers/spi/spi_s3c64xx.c static void handle_msg(struct
Quoted 22 lines
drivers/spi/spi_s3c64xx.c +0
-18-{ -struct s3c64xx_spi_driver_data *sdd = buf_id; -unsigned long flags; - -spin_lock_irqsave (&sdd->lock, flags); - -if (res ==S3C2410_RES_OK ) - sdd->state &= ~TXBUSY ; -else -dev_err (&sdd->pdev->dev,"DmaAbrtTx-%d \n" , size); - -/* If the other done */ -if (!(sdd->state &RXBUSY )) -complete (&sdd->xfer_completion); - -spin_unlock_irqrestore (&sdd->lock, flags); -} -#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,@@ -697,12 +701,10 @@ static void handle_msg(struct
s3c64xx_spi_driver_data*sdd,drivers/spi/spi_s3c64xx.c static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
Quoted 5 lines
drivers/spi/spi_s3c64xx.c +0
-2if (use_dma) {if (xfer->tx_buf !=NULL && (sdd->state &TXBUSY )) - s3c2410_dma_ctrl(sdd->tx_dmach, -S3C2410_DMAOP_FLUSH);drivers/spi/spi_s3c64xx.c static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
Quoted 5 lines
drivers/spi/spi_s3c64xx.c +1
-2+ sdd->ops->stop (sdd->tx_ch);if (xfer->rx_buf !=NULL && (sdd->state &RXBUSY )) - s3c2410_dma_ctrl(sdd->rx_dmach, -S3C2410_DMAOP_FLUSH);drivers/spi/spi_s3c64xx.c out: · line 746
Quoted 10 lines
drivers/spi/spi_s3c64xx.c +1
-2+ sdd->ops->stop (sdd->rx_ch); } goto out;@@ -742,24 +744,19 @@ out:static int acquire_dma (struct s3c64xx_spi_driver_data *sdd) { - if (s3c2410_dma_request(sdd->rx_dmach, - &s3c64xx_spi_dma_client, NULL) <0) {
drivers/spi/spi_s3c64xx.c out:
Quoted 4 lines
drivers/spi/spi_s3c64xx.c +0
-4-dev_err (&sdd->pdev->dev,"cannot get RxDMA\n" ); -return 0 ; - } - s3c2410_dma_set_buffdone_fn(sdd->rx_dmach,
s3c64xx_spi_dma_rxcb);drivers/spi/spi_s3c64xx.c out: · line 752
Quoted 2 lines
drivers/spi/spi_s3c64xx.c +0
-2- s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW, - sdd->sfr_start +
S3C64XX_SPI_RX_DATA);drivers/spi/spi_s3c64xx.c out:
Quoted 3 lines
drivers/spi/spi_s3c64xx.c +0
-3- - if (s3c2410_dma_request(sdd->tx_dmach, - &s3c64xx_spi_dma_client, NULL) <0) {
drivers/spi/spi_s3c64xx.c out: · line 757
Quoted 2 lines
drivers/spi/spi_s3c64xx.c +0
-2-dev_err (&sdd->pdev->dev,"cannot get TxDMA\n" ); - s3c2410_dma_free(sdd->rx_dmach,
&s3c64xx_spi_dma_client);drivers/spi/spi_s3c64xx.c out:
Quoted 3 lines
drivers/spi/spi_s3c64xx.c +0
-3-return 0 ; - } - s3c2410_dma_set_buffdone_fn(sdd->tx_dmach,
s3c64xx_spi_dma_txcb);drivers/spi/spi_s3c64xx.c out: · line 762
Quoted 2 lines
drivers/spi/spi_s3c64xx.c +0
-2- s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM, - sdd->sfr_start +
S3C64XX_SPI_TX_DATA);drivers/spi/spi_s3c64xx.c static void s3c64xx_spi_work(struct work_struct
Quoted 17 lines
drivers/spi/spi_s3c64xx.c +13
-0+ +struct samsung_dma_info info; + sdd->ops =samsung_dma_get_ops (); + + info.cap =DMA_SLAVE ; + info.client = &s3c64xx_spi_dma_client; + info.direction =DMA_FROM_DEVICE ; + info.fifo = sdd->sfr_start +S3C64XX_SPI_RX_DATA ; + info.width = sdd->cur_bpw /8 ; + sdd->rx_ch = sdd->ops->request (sdd->rx_dmach, &info); + info.direction =DMA_TO_DEVICE ; + info.fifo = sdd->sfr_start +S3C64XX_SPI_TX_DATA ; + sdd->tx_ch = sdd->ops->request (sdd->tx_dmach, &info);return 1 ; }@@ -800,8 +797,8 @@ static void s3c64xx_spi_work(struct work_struct*work)
drivers/spi/spi_s3c64xx.c static void s3c64xx_spi_work(struct work_struct *work) · line 802
Quoted 8 lines
drivers/spi/spi_s3c64xx.c +2
-2spin_unlock_irqrestore (&sdd->lock, flags);/* Free DMA channels */ -s3c2410_dma_free (sdd->tx_dmach, &s3c64xx_spi_dma_client); -s3c2410_dma_free (sdd->rx_dmach, &s3c64xx_spi_dma_client); + sdd->ops->release (sdd->rx_ch, &s3c64xx_spi_dma_client); + sdd->ops->release (sdd->tx_ch, &s3c64xx_spi_dma_client); }
Quoted 6 lines
Btw, this spi driver is for S3C64xx(with pl080) and S5P(with pl330) series, both of which
have DMAENGINE drivers. May be it could be directly switched to using those, rather than
via Samsung's wrapper driver.
Or am I overlooking something ?
Samsung is preparing to use PL080 with DMAENGINE. After this work is done, We will consider to using DMAENGINE API if required.
PATCH v5 13/15 spi/s3c64xx: Merge dma control code
In reply to Boojin KimThis patch modifies to merge the dma control code.
Original s3c64xx spi driver has each dma control code for rx and tx channel. This patch merges these dma control codes into one.
With this patch, a dma setup function and callback function handle for both rx and tx channel.
--- drivers/spi/spi_s3c64xx.c | 140 ++++++++++++++++++++++++-------------------- 1 files changed, 76 insertions(+), 64 deletions(-)
drivers/spi/spi_s3c64xx.c +76 -64
@@ -132,6 +132,12 @@#define RXBUSY (1<<2)#define TXBUSY (1<<3) +struct s3c64xx_spi_dma_data { +unsigned ch; +enum dma_data_direction direction; +enum dma_ch dmach; +}; +/** * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. * @clk: Pointer to the spi clock.
@@ -165,15 +171,13 @@ struct s3c64xx_spi_driver_data {struct work_struct work;struct list_head queue;spinlock_t lock; -enum dma_ch rx_dmach; -enum dma_ch tx_dmach;unsigned long sfr_start;struct completion xfer_completion;unsigned state;unsigned cur_mode, cur_bpw;unsigned cur_speed; -unsigned rx_ch; -unsigned tx_ch; +struct s3c64xx_spi_dma_data rx_dma; +struct s3c64xx_spi_dma_data tx_dma;struct samsung_dma_ops *ops; };
@@ -230,36 +234,76 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)writel (val, regs +S3C64XX_SPI_CH_CFG ); } -static void s3c64xx_spi_dma_rxcb (void *data) +static void s3c64xx_spi_dmacb (void *data) { -struct s3c64xx_spi_driver_data *sdd - = (struct s3c64xx_spi_driver_data *)data; +struct s3c64xx_spi_driver_data *sdd; +struct s3c64xx_spi_dma_data *dma = data;unsigned long flags; +if (dma->direction ==DMA_FROM_DEVICE ) + sdd =container_of (data, + struct s3c64xx_spi_driver_data, rx_dma); +else + sdd =container_of (data, + struct s3c64xx_spi_driver_data, tx_dma); +spin_lock_irqsave (&sdd->lock, flags); - sdd->state &= ~RXBUSY ; -/* If the other done */ -if (!(sdd->state &TXBUSY )) -complete (&sdd->xfer_completion); +if (dma->direction ==DMA_FROM_DEVICE ) { + sdd->state &= ~RXBUSY ; +if (!(sdd->state &TXBUSY )) +complete (&sdd->xfer_completion); + }else { + sdd->state &= ~TXBUSY ; +if (!(sdd->state &RXBUSY )) +complete (&sdd->xfer_completion); + }spin_unlock_irqrestore (&sdd->lock, flags); } -static void s3c64xx_spi_dma_txcb (void *data) +static void prepare_dma (struct s3c64xx_spi_dma_data *dma, +unsigned len,dma_addr_t buf) { -struct s3c64xx_spi_driver_data *sdd - = (struct s3c64xx_spi_driver_data *)data; -unsigned long flags; +struct s3c64xx_spi_driver_data *sdd; +struct samsung_dma_prep_info info; -spin_lock_irqsave (&sdd->lock, flags); +if (dma->direction ==DMA_FROM_DEVICE ) + sdd =container_of ((void *)dma, + struct s3c64xx_spi_driver_data, rx_dma); +else + sdd =container_of ((void *)dma, + struct s3c64xx_spi_driver_data, tx_dma); - sdd->state &= ~TXBUSY ; -/* If the other done */ -if (!(sdd->state &RXBUSY )) -complete (&sdd->xfer_completion); + info.cap =DMA_SLAVE ; + info.len = len; + info.fp = s3c64xx_spi_dmacb; + info.fp_param = dma; + info.direction = dma->direction; + info.buf = buf; + + sdd->ops->prepare (dma->ch, &info); + sdd->ops->trigger (dma->ch); +} -spin_unlock_irqrestore (&sdd->lock, flags); +static int acquire_dma (struct s3c64xx_spi_driver_data *sdd) +{ +struct samsung_dma_info info; + + sdd->ops =samsung_dma_get_ops (); + + info.cap =DMA_SLAVE ; + info.client = &s3c64xx_spi_dma_client; + info.width = sdd->cur_bpw /8 ; + + info.direction = sdd->rx_dma.direction; + info.fifo = sdd->sfr_start +S3C64XX_SPI_RX_DATA ; + sdd->rx_dma.ch = sdd->ops->request (sdd->rx_dma.dmach, &info); + info.direction = sdd->tx_dma.direction; + info.fifo = sdd->sfr_start +S3C64XX_SPI_TX_DATA ; + sdd->tx_dma.ch = sdd->ops->request (sdd->tx_dma.dmach, &info); + +return 1 ; } static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
@@ -269,7 +313,6 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,struct s3c64xx_spi_info *sci = sdd->cntrlr_info;void __iomem *regs = sdd->regs;u32 modecfg, chcfg; -struct samsung_dma_prep_info info; modecfg =readl (regs +S3C64XX_SPI_MODE_CFG ); modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON |S3C64XX_SPI_MODE_RXDMA_ON );
@@ -295,14 +338,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, chcfg |=S3C64XX_SPI_CH_TXCH_ON ;if (dma_mode) { modecfg |=S3C64XX_SPI_MODE_TXDMA_ON ; - info.cap =DMA_SLAVE ; - info.direction =DMA_TO_DEVICE ; - info.buf = xfer->tx_dma; - info.len = xfer->len; - info.fp = s3c64xx_spi_dma_txcb; - info.fp_param = sdd; - sdd->ops->prepare (sdd->tx_ch, &info); - sdd->ops->trigger (sdd->tx_ch); +prepare_dma (&sdd->tx_dma, xfer->len, xfer->tx_dma); }else {switch (sdd->cur_bpw) {case 32 :
@@ -334,14 +370,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,writel (((xfer->len *8 / sdd->cur_bpw) &0xffff ) |S3C64XX_SPI_PACKET_CNT_EN , regs +S3C64XX_SPI_PACKET_CNT ); - info.cap =DMA_SLAVE ; - info.direction =DMA_FROM_DEVICE ; - info.buf = xfer->rx_dma; - info.len = xfer->len; - info.fp = s3c64xx_spi_dma_rxcb; - info.fp_param = sdd; - sdd->ops->prepare (sdd->rx_ch, &info); - sdd->ops->trigger (sdd->rx_ch); +prepare_dma (&sdd->rx_dma, xfer->len, xfer->rx_dma); } }
@@ -701,10 +730,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,if (use_dma) {if (xfer->tx_buf !=NULL && (sdd->state &TXBUSY )) - sdd->ops->stop (sdd->tx_ch); + sdd->ops->stop (sdd->tx_dma.ch);if (xfer->rx_buf !=NULL && (sdd->state &RXBUSY )) - sdd->ops->stop (sdd->rx_ch); + sdd->ops->stop (sdd->rx_dma.ch); } goto out;
@@ -742,25 +771,6 @@ out: msg->complete (msg->context); } -static int acquire_dma (struct s3c64xx_spi_driver_data *sdd) -{ - -struct samsung_dma_info info; - sdd->ops =samsung_dma_get_ops (); - - info.cap =DMA_SLAVE ; - info.client = &s3c64xx_spi_dma_client; - info.direction =DMA_FROM_DEVICE ; - info.fifo = sdd->sfr_start +S3C64XX_SPI_RX_DATA ; - info.width = sdd->cur_bpw /8 ; - sdd->rx_ch = sdd->ops->request (sdd->rx_dmach, &info); - info.direction =DMA_TO_DEVICE ; - info.fifo = sdd->sfr_start +S3C64XX_SPI_TX_DATA ; - sdd->tx_ch = sdd->ops->request (sdd->tx_dmach, &info); - -return 1 ; -} -static void s3c64xx_spi_work (struct work_struct *work) { struct s3c64xx_spi_driver_data *sdd = container_of(work,
@@ -797,8 +807,8 @@ static void s3c64xx_spi_work(struct work_struct *work)spin_unlock_irqrestore (&sdd->lock, flags);/* Free DMA channels */ - sdd->ops->release (sdd->rx_ch, &s3c64xx_spi_dma_client); - sdd->ops->release (sdd->tx_ch, &s3c64xx_spi_dma_client); + sdd->ops->release (sdd->rx_dma.ch, &s3c64xx_spi_dma_client); + sdd->ops->release (sdd->tx_dma.ch, &s3c64xx_spi_dma_client); } static int s3c64xx_spi_transfer(struct spi_device *spi,
@@ -1015,8 +1025,10 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) sdd->cntrlr_info = sci; sdd->pdev = pdev; sdd->sfr_start = mem_res->start; - sdd->tx_dmach = dmatx_res->start; - sdd->rx_dmach = dmarx_res->start; + sdd->tx_dma.dmach = dmatx_res->start; + sdd->tx_dma.direction =DMA_TO_DEVICE ; + sdd->rx_dma.dmach = dmarx_res->start; + sdd->rx_dma.direction =DMA_FROM_DEVICE ; sdd->cur_bpw =8 ;
@@ -1104,7 +1116,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) pdev->id, master->num_chipselect);dev_dbg (&pdev->dev,"\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n" , mem_res->end, mem_res->start, - sdd->rx_dmach, sdd->tx_dmach); + sdd->rx_dma.dmach, sdd->tx_dma.dmach);return 0 ;
Signature · 1 line
1.7.1
PATCH 13/15 spi/s3c64xx: Merge dma control code
Quoted 5 lines · Boojin Kim
This patch modifies to merge the dma control code.
Original s3c64xx spi driver has each dma control code for rx and tx channel. This patch merges these dma control codes into one.
With this patch, a dma setup function and callback function handle for both rx and tx channel.
This is nothing really to do with underlying DMAENGINE API.
And, apparently it actually bloats the driver ? 76 insertions(+), 64
deletions(-)
Yet, I am not very against the idea.
If you must do it, maybe It would have been better to move it early in the patchset,
which would have resulted in a smaller and cleaner "spi/s3c64xx: Add support DMA engine API"
PATCH v5 14/15 ASoC: Samsung: Update DMA interface
In reply to Boojin KimThis patch adds to support the DMA PL330 driver that uses DMA generic API. Samsung sound driver uses DMA generic API if architecture supports it. Otherwise, use samsung specific S3C-PL330 API driver to transfer PCM data.
--- arch/arm/mach-s3c2410/include/mach/dma.h | 10 +- arch/arm/mach-s3c64xx/include/mach/dma.h | 2 +- arch/arm/plat-samsung/include/plat/dma-pl330.h | 2 +- sound/soc/samsung/ac97.c | 10 ++- sound/soc/samsung/dma.c | 144 ++++++++++-------------- sound/soc/samsung/dma.h | 4 +- 6 files changed, 78 insertions(+), 94 deletions(-)
arch/arm/mach-s3c2410/include/mach/dma.h +5 -5
@@ -50,6 +50,11 @@ enum dma_ch { DMACH_MAX, /* the end entry */ }; +static inline bool samsung_dma_has_circular (void ) +{ +return false; +} +static inline bool samsung_dma_is_dmadev (void ) {return false;
@@ -202,9 +207,4 @@ struct s3c2410_dma_chan {typedef unsigned long dma_device_t ; -static inline bool s3c_dma_has_circular (void ) -{ -return false; -} -#endif /* __ASM_ARCH_DMA_H */
arch/arm/mach-s3c64xx/include/mach/dma.h +1 -1
@@ -58,7 +58,7 @@ enum dma_ch { DMACH_MAX /* the end */ }; -static __inline__bool s3c_dma_has_circular (void ) +static inline bool samsung_dma_has_circular (void ) {return true; }
arch/arm/plat-samsung/include/plat/dma-pl330.h +1 -1
@@ -89,7 +89,7 @@ struct s3c2410_dma_client {char *name; }; -static inline bool s3c_dma_has_circular (void ) +static inline bool samsung_dma_has_circular (void ) {return true; }
sound/soc/samsung/ac97.c +8 -2
@@ -271,7 +271,10 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,writel (ac_glbctrl, s3c_ac97.regs +S3C_AC97_GLBCTRL ); -s3c2410_dma_ctrl (dma_data->channel,S3C2410_DMAOP_STARTED ); +if (!dma_data->ops) + dma_data->ops =samsung_dma_get_ops (); + + dma_data->ops->started (dma_data->channel);return 0 ; }
@@ -317,7 +320,10 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,writel (ac_glbctrl, s3c_ac97.regs +S3C_AC97_GLBCTRL ); -s3c2410_dma_ctrl (dma_data->channel,S3C2410_DMAOP_STARTED ); +if (!dma_data->ops) + dma_data->ops =samsung_dma_get_ops (); + + dma_data->ops->started (dma_data->channel);return 0 ; }
sound/soc/samsung/dma.c +60 -84
233 lines not on this page · raw message
sound/soc/samsung/dma.h +3 -1
@@ -6,7 +6,7 @@* Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * -* ALSA PCM interface for the Samsung S3C24xx CPU +* ALSA PCM interface for the Samsung SoC */ #ifndef _S3C_AUDIO_H
@@ -17,6 +17,8 @@ struct s3c_dma_params {int channel;/* Channel ID */ dma_addr_t dma_addr;int dma_size;/* Size of the DMA transfer */ +unsigned ch; + struct samsung_dma_ops *ops; };#endif
Signature · 1 line
1.7.1
PATCH 14/15 ASoC: Samsung: Update DMA interface
Quoted 8 lines · Boojin Kim
?static void
dma_enqueue(struct snd_pcm_substream *substream)?{
? ? ? ?structruntime_data*prtd =substream->runtime->private_data; ? ? ? ?dma_addr_t pos =prtd->dma_pos;
? ? ? ?unsigned int limit;
- ? ? ? int ret;
+ ? ? ? structsamsung_dma_prep_infodma_info;
Quoted 7 lines
? ? ? ?pr_debug("Entered %s\n",
__func__);- ? ? ? if (
s3c_dma_has_circular())
- ? ? ? ? ? ? ? limit = (prtd->dma_end-prtd->dma_start) /prtd->dma_period;
- ? ? ? else
- ? ? ? ? ? ? ? limit =prtd->dma_limit;
+ ? ? ? limit = (prtd->dma_end-prtd->dma_start) /prtd->dma_period;
'dma_limit' is rendered useless, so you might want to remove it from 'struct runtime_data'
as well.
Quoted 73 lines
? ? ? ?pr_debug("%s: loaded %d, limit %d\n",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?__func__,prtd->dma_loaded, limit);- ? ? ? while (
prtd->dma_loaded< limit) {
- ? ? ? ? ? ? ? unsigned long len =prtd->dma_period;
+ ? ? ? dma_info.cap = (samsung_dma_has_circular()?DMA_CYCLIC:DMA_SLAVE);
+ ? ? ? dma_info.direction =
+ ? ? ? ? ? ? ? (substream->stream==SNDRV_PCM_STREAM_PLAYBACK
+ ? ? ? ? ? ? ? ?DMA_TO_DEVICE:DMA_FROM_DEVICE);
+ ? ? ? dma_info.fp =audio_buffdone;
+ ? ? ? dma_info.fp_param = substream;
+ ? ? ? dma_info.period =prtd->dma_period;
+ ? ? ? dma_info.len = prtd->dma_period*limit;+ ? ? ? while (
prtd->dma_loaded< limit) {
? ? ? ? ? ? ? ?pr_debug("dma_loaded: %d\n",prtd->dma_loaded);- ? ? ? ? ? ? ? if ((pos + len) >
prtd->dma_end) {
- ? ? ? ? ? ? ? ? ? ? ? len ?=prtd->dma_end- pos;
- ? ? ? ? ? ? ? ? ? ? ?pr_debug("%s: corrected dma len %ld\n", __func__, len);
+ ? ? ? ? ? ? ? if ((pos + dma_info.period) >prtd->dma_end) {
+ ? ? ? ? ? ? ? ? ? ? ? dma_info.period ?=prtd->dma_end- pos;
+ ? ? ? ? ? ? ? ? ? ? ? pr_debug("%s: corrected dma len %ld\n",
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?__func__, dma_info.period); ? ? ? ? ? ? ? ?}- ? ? ? ? ? ? ? ret = s3c2410_dma_enqueue(prtd->params->channel,
- ? ? ? ? ? ? ? ? ? ? ? substream, pos, len);
+ ? ? ? ? ? ? ? dma_info.buf = pos;
+ ? ? ? ? ? ? ?prtd->params->ops->prepare(prtd->params->ch, &dma_info);- ? ? ? ? ? ? ? if (ret == 0) {
- ? ? ? ? ? ? ? ? ? ? ? prtd->dma_loaded++;
- ? ? ? ? ? ? ? ? ? ? ? pos +=prtd->dma_period;
- ? ? ? ? ? ? ? ? ? ? ? if (pos >=prtd->dma_end)
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pos =prtd->dma_start;
- ? ? ? ? ? ? ? } else
- ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? prtd->dma_loaded++;
+ ? ? ? ? ? ? ? pos +=prtd->dma_period;
+ ? ? ? ? ? ? ? if (pos >=prtd->dma_end)
+ ? ? ? ? ? ? ? ? ? ? ? pos =prtd->dma_start; ? ? ? ?}? ? ? ?prtd->dma_pos = pos;
?}sound/soc/samsung/dma.c +1
-3-static void audio_buffdone (struct s3c2410_dma_chan *channel, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void *dev_id, int size, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? enum s3c2410_dma_buffresult result) +static void audio_buffdone (void *data)?{
- ? ? ? structsnd_pcm_substream*substream =dev_id;
- ? ? ? structruntime_data*prtd;
+ ? ? ? structsnd_pcm_substream*substream = data;
+ ? ? ? structruntime_data*prtd =substream->runtime->private_data;? ? ? ?pr_debug("Entered %s\n",
__func__);- ? ? ? if (result ==
S3C2410_RES_ABORT|| result ==S3C2410_RES_ERR)
- ? ? ? ? ? ? ? return;
-
- ? ? ? prtd =substream->runtime->private_data;
+ ? ? ? if (prtd->state&ST_RUNNING) {
+ ? ? ? ? ? ? ?prtd->dma_pos+=prtd->dma_period;
+ ? ? ? ? ? ? ? if (prtd->dma_pos>=prtd->dma_end)
+ ? ? ? ? ? ? ? ? ? ? ?prtd->dma_pos=prtd->dma_start;- ? ? ? if (substream)
- ? ? ? ? ? ? ?snd_pcm_period_elapsed(substream);
+ ? ? ? ? ? ? ? if (substream)
+ ? ? ? ? ? ? ? ? ? ? ?snd_pcm_period_elapsed(substream);
Quoted 14 lines
- ? ? ?
spin_lock(&prtd->lock);
- ? ? ? if (prtd->state&ST_RUNNING&& !s3c_dma_has_circular()) {
- ? ? ? ? ? ? ? prtd->dma_loaded--;
- ? ? ? ? ? ? ?dma_enqueue(substream);
+ ? ? ? ? ? ? ?spin_lock(&prtd->lock);
+ ? ? ? ? ? ? ? if (!samsung_dma_has_circular()) {
+ ? ? ? ? ? ? ? ? ? ? ? prtd->dma_loaded--;
+ ? ? ? ? ? ? ? ? ? ? ?dma_enqueue(substream);
+ ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ?spin_unlock(&prtd->lock);
? ? ? ?}
-
- ? ? ?spin_unlock(&prtd->lock);
?}
Since we set integer-constraint on number of periods, you could also discard bothering fractional boundaries. That would make things a lot simpler.
Quoted 8 lines
(quoted diff) +0
-0@@ -265,14 +250,14 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd)? ? ? ?case
SNDRV_PCM_TRIGGER_RESUME:
? ? ? ?caseSNDRV_PCM_TRIGGER_PAUSE_RELEASE:
? ? ? ? ? ? ? ?prtd->state |=ST_RUNNING;
- ? ? ? ? ? ? ?s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
+ ? ? ? ? ? ? ?prtd->params->ops->trigger(prtd->params->ch);
? ? ? ? ? ? ? ?break;
Quoted 7 lines
? ? ? ?case
SNDRV_PCM_TRIGGER_STOP:
? ? ? ?caseSNDRV_PCM_TRIGGER_SUSPEND:
? ? ? ?caseSNDRV_PCM_TRIGGER_PAUSE_PUSH:
? ? ? ? ? ? ? ?prtd->state &= ~ST_RUNNING;
- ? ? ? ? ? ? ?s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP);
+ ? ? ? ? ? ? ?prtd->params->ops->stop(prtd->params->ch);
? ? ? ? ? ? ? ?break;
I wish you agreed and used
prtd->params->ops->cmd(ch, enum some_cmd_options)
rather than having 4 separate callbacks
prtd->params->ops->trigger(prtd->params->ch)
prtd->params->ops->stop(prtd->params->ch)
prtd->params->ops->flush(prtd->params->ch)
prtd->params->ops->started(prtd->params->ch)Quoted 22 lines
(quoted diff) +2
-11@@ -291,21 +276,12 @@ dma_pointer(struct snd_pcm_substream *substream) ? ? ? ?struct snd_pcm_runtime *runtime = substream->runtime; ? ? ? ?struct runtime_data *prtd = runtime->private_data; ? ? ? ?unsigned long res; - ? ? ? dma_addr_t src, dst; ? ? ? ?pr_debug("Entered %s\n", __func__); - ? ? ? spin_lock(&prtd->lock); - ? ? ? s3c2410_dma_getposition(prtd->params->channel, &src, &dst); - - ? ? ? if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ? ? ? ? ? ? ? res = dst - prtd->dma_start; - ? ? ? else - ? ? ? ? ? ? ? res = src - prtd->dma_start; - - ? ? ? spin_unlock(&prtd->lock); + ? ? ? res = prtd->dma_pos - prtd->dma_start; - ? ? ? pr_debug("Pointer %x %x\n", src, dst); + ? ? ? pr_debug("Pointer offset: %lu\n", res);
Quoted 2 lines
? ? ? ?/* we seem to be getting the odd error from the pcm library due ? ? ? ? * to out-of-bounds pointers. this is maybe due to the dma engine
Isn't this a regression ?dma_pointer() doesn't really return actual location of DMA activity anymore. Now it simply tells the last period done.
This would affect latencies in a bad way.
PATCH v5 14/15 ASoC: Samsung: Update DMA interface
Jassi Brar Wrote:
Quoted 27 lines
Sent: Tuesday, August 09, 2011 4:28 AM
To: Boojin Kim
Cc: linux-arm-kernel at lists.infradead.org; linux-samsung- soc at vger.kernel.org; Vinod Koul; Dan Williams; Kukjin Kim; Mark Brown; Grant Likely; Russell King; Liam Girdwood
Subject: Re: [PATCH 14/15] ASoC: Samsung: Update DMA interfaceQuoted 13 lines · Boojin Kim
static void
dma_enqueue(struct snd_pcm_substream *substream){ struct runtime_data *prtd = substream->runtime->private_data; dma_addr_t pos = prtd->dma_pos; unsigned int limit;sound/soc/samsung/dma.c +1
-3-int ret; +struct samsung_dma_prep_info dma_info;pr_debug ("Entered %s\n" , __func__); -if (s3c_dma_has_circular ()) - limit = (prtd->dma_end - prtd->dma_start) / prtd-
dma_period;sound/soc/samsung/dma.c struct runtime_data { · line 81
Quoted 3 lines
sound/soc/samsung/dma.c +1
-2-else - limit = prtd->dma_limit; + limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
Quoted 3 lines
'
dma_limit' is rendered useless, so you might want to remove it from 'structruntime_data'
as well.
You're right. I will remove it in next cleanup patch
Quoted 151 lines
sound/soc/samsung/dma.c struct runtime_data {
Quoted 7 lines
pr_debug("%s: loaded %d, limit %d\n", __func__, prtd->dma_loaded, limit);sound/soc/samsung/dma.c +1
-2-while (prtd->dma_loaded < limit) { -unsigned long len = prtd->dma_period; + dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC :
DMA_SLAVE);Quoted 4 lines
sound/soc/samsung/dma.c +4
-0+ dma_info.direction = + (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK + ?DMA_TO_DEVICE :DMA_FROM_DEVICE ); + dma_info.fp = audio_buffdone;sound/soc/samsung/dma.c struct runtime_data {
Quoted 10 lines
sound/soc/samsung/dma.c +4
-3+ dma_info.fp_param = substream; + dma_info.period = prtd->dma_period; + dma_info.len = prtd->dma_period*limit; +while (prtd->dma_loaded < limit) {pr_debug ("dma_loaded: %d\n" , prtd->dma_loaded); -if ((pos + len) > prtd->dma_end) { - len = prtd->dma_end - pos; - pr_debug("%s: corrected dma len %ld\n",
__func__, len);sound/soc/samsung/dma.c struct runtime_data {
Quoted 10 lines
sound/soc/samsung/dma.c +6
-2+if ((pos + dma_info.period) > prtd->dma_end) { + dma_info.period = prtd->dma_end - pos; +pr_debug ("%s: corrected dma len %ld\n" , + __func__, dma_info.period); } - ret =s3c2410_dma_enqueue (prtd->params->channel, - substream, pos, len); + dma_info.buf = pos; + prtd->params->ops->prepare(prtd->params->ch,
&dma_info);Quoted 47 lines
sound/soc/samsung/dma.c +13
-22-if (ret ==0 ) { - prtd->dma_loaded++; - pos += prtd->dma_period; -if (pos >= prtd->dma_end) - pos = prtd->dma_start; - }else -break ; + prtd->dma_loaded++; + pos += prtd->dma_period; +if (pos >= prtd->dma_end) + pos = prtd->dma_start; } prtd->dma_pos = pos; } -static void audio_buffdone (struct s3c2410_dma_chan *channel, -void *dev_id,int size, -enum s3c2410_dma_buffresult result) +static void audio_buffdone (void *data) { -struct snd_pcm_substream *substream = dev_id; -struct runtime_data *prtd; +struct snd_pcm_substream *substream = data; +struct runtime_data *prtd = substream->runtime->private_data;pr_debug ("Entered %s\n" , __func__); -if (result ==S3C2410_RES_ABORT || result ==S3C2410_RES_ERR ) -return ; - - prtd = substream->runtime->private_data; +if (prtd->state &ST_RUNNING ) { + prtd->dma_pos += prtd->dma_period; +if (prtd->dma_pos >= prtd->dma_end) + prtd->dma_pos = prtd->dma_start; -if (substream) -snd_pcm_period_elapsed (substream); +if (substream) +snd_pcm_period_elapsed (substream); -spin_lock (&prtd->lock); -if (prtd->state &ST_RUNNING && !s3c_dma_has_circular ()) { - prtd->dma_loaded--; -dma_enqueue (substream);sound/soc/samsung/dma.c struct runtime_data { · line 138
Quoted 10 lines
sound/soc/samsung/dma.c +6
-2+spin_lock (&prtd->lock); +if (!samsung_dma_has_circular ()) { + prtd->dma_loaded--; +dma_enqueue (substream); + } +spin_unlock (&prtd->lock); } - -spin_unlock (&prtd->lock); }Since we set integer-constraint on number of periods, you could also discard bothering fractional boundaries. That would make things a lot simpler.
Review static int dma_trigger(struct
Quoted 1 line
(quoted diff) +0
-0@@ -265,14 +250,14 @@ static int dma_trigger(struct
snd_pcm_substream*substream, int cmd)sound/soc/samsung/dma.c static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
Quoted 4 lines
sound/soc/samsung/dma.c +0
-1case SNDRV_PCM_TRIGGER_RESUME :case SNDRV_PCM_TRIGGER_PAUSE_RELEASE : prtd->state |=ST_RUNNING ; - s3c2410_dma_ctrl(prtd->params->channel,
S3C2410_DMAOP_START);sound/soc/samsung/dma.c static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
Quoted 8 lines
sound/soc/samsung/dma.c +1
-1+ prtd->params->ops->trigger (prtd->params->ch);break ;case SNDRV_PCM_TRIGGER_STOP :case SNDRV_PCM_TRIGGER_SUSPEND :case SNDRV_PCM_TRIGGER_PAUSE_PUSH : prtd->state &= ~ST_RUNNING ; - s3c2410_dma_ctrl(prtd->params->channel,
S3C2410_DMAOP_STOP);sound/soc/samsung/dma.c static int dma_trigger(struct snd_pcm_substream *substream, int cmd) · line 261
Quoted 2 lines
sound/soc/samsung/dma.c +1
-0+ prtd->params->ops->stop (prtd->params->ch);break ;I wish you agreed and used
prtd->params->ops->cmd(ch, enum some_cmd_options) rather than having 4 separate callbacks prtd->params->ops->trigger(prtd->params->ch) prtd->params->ops->stop(prtd->params->ch) prtd->params->ops->flush(prtd->params->ch) prtd->params->ops->started(prtd->params->ch)Review dma_pointer(struct snd_pcm_substream
Quoted 1 line
(quoted diff) +0
-0@@ -291,21 +276,12 @@ dma_pointer(struct snd_pcm_substream*substream)
Quoted 12 lines
sound/soc/samsung/dma.c +0
-6struct snd_pcm_runtime *runtime = substream->runtime;struct runtime_data *prtd = runtime->private_data;unsigned long res; -dma_addr_t src, dst;pr_debug ("Entered %s\n" , __func__); -spin_lock (&prtd->lock); -s3c2410_dma_getposition (prtd->params->channel, &src, &dst); - -if (substream->stream ==SNDRV_PCM_STREAM_CAPTURE ) - res = dst - prtd->dma_start;sound/soc/samsung/dma.c dma_pointer(struct snd_pcm_substream *substream)
Quoted 10 lines
sound/soc/samsung/dma.c +2
-5-else - res = src - prtd->dma_start; - -spin_unlock (&prtd->lock); + res = prtd->dma_pos - prtd->dma_start; -pr_debug ("Pointer %x %x\n" , src, dst); +pr_debug ("Pointer offset: %lu\n" , res);/* we seem to be getting the odd error from the pcm library due
Quoted 8 lines
Review dma_pointer(struct snd_pcm_substream · line 287
Quoted 1 line
(quoted diff) +0
-0* to out-of-bounds pointers. this is maybe due to the dmaengine
Isn't this a regression ?
dma_pointer()doesn't really return actual location of DMA activity anymore.
Now it simply tells the last period done.
This would affect latencies in a bad way.
Yes, This code makes the DMA position less accurately. But, This position is enough for audio DMA activity. Other drivers also use similar method to get the position.
PATCH v5 15/15 ARM: SAMSUNG: Remove Samsung specific enum type for dma direction
In reply to Boojin KimThis patch removes the samsung specific enum type 's3c2410_dmasrc' and uses 'dma_data_direction' instead.
--- arch/arm/mach-s3c2410/include/mach/dma.h | 2 +- arch/arm/mach-s3c2412/dma.c | 4 ++-- arch/arm/mach-s3c64xx/dma.c | 10 +++++----- arch/arm/mach-s3c64xx/include/mach/dma.h | 2 +- arch/arm/plat-s3c24xx/dma.c | 10 +++++----- arch/arm/plat-samsung/include/plat/dma-s3c24xx.h | 2 +- arch/arm/plat-samsung/include/plat/dma.h | 9 +++------ arch/arm/plat-samsung/s3c-dma-ops.c | 5 +---- drivers/mmc/host/s3cmci.c | 6 +++--- 9 files changed, 22 insertions(+), 28 deletions(-)
arch/arm/mach-s3c2410/include/mach/dma.h +1 -1
@@ -174,7 +174,7 @@ struct s3c2410_dma_chan {struct s3c2410_dma_client *client;/* channel configuration */ -enum s3c2410_dmasrc source; +enum dma_data_direction source;enum dma_ch req_ch;unsigned long dev_addr;unsigned long load_timeout;
arch/arm/mach-s3c2412/dma.c +2 -2
@@ -148,11 +148,11 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {static void s3c2412_dma_direction (struct s3c2410_dma_chan *chan,struct s3c24xx_dma_map *map, -enum s3c2410_dmasrc dir) +enum dma_data_direction dir) {unsigned long chsel; -if (dir ==S3C2410_DMASRC_HW ) +if (dir ==DMA_FROM_DEVICE ) chsel = map->channels_rx[0 ];else chsel = map->channels[0 ];
arch/arm/mach-s3c64xx/dma.c +5 -5
@@ -147,14 +147,14 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,u32 control0, control1;switch (chan->source) { -case S3C2410_DMASRC_HW : +case DMA_FROM_DEVICE : src = chan->dev_addr; dst = data; control0 =PL080_CONTROL_SRC_AHB2 ; control0 |=PL080_CONTROL_DST_INCR ;break ; -case S3C2410_DMASRC_MEM : +case DMA_TO_DEVICE : src = data; dst = chan->dev_addr; control0 =PL080_CONTROL_DST_AHB2 ;
@@ -416,7 +416,7 @@ EXPORT_SYMBOL(s3c2410_dma_enqueue);int s3c2410_dma_devconfig (unsigned int channel, -enum s3c2410_dmasrc source, +enum dma_data_direction source,unsigned long devaddr) {struct s3c2410_dma_chan *chan =s3c_dma_lookup_channel (channel);
@@ -437,11 +437,11 @@ int s3c2410_dma_devconfig(unsigned int channel,pr_debug ("%s: peripheral %d\n" , __func__, peripheral);switch (source) { -case S3C2410_DMASRC_HW : +case DMA_FROM_DEVICE : config =2 <<PL080_CONFIG_FLOW_CONTROL_SHIFT ; config |= peripheral <<PL080_CONFIG_SRC_SEL_SHIFT ;break ; -case S3C2410_DMASRC_MEM : +case DMA_TO_DEVICE : config =1 <<PL080_CONFIG_FLOW_CONTROL_SHIFT ; config |= peripheral <<PL080_CONFIG_DST_SEL_SHIFT ;break ;
arch/arm/mach-s3c64xx/include/mach/dma.h +1 -1
@@ -99,7 +99,7 @@ struct s3c2410_dma_chan {unsigned char peripheral;unsigned int flags; -enum s3c2410_dmasrc source; +enum dma_data_direction source;dma_addr_t dev_addr;
arch/arm/plat-s3c24xx/dma.c +5 -5
@@ -1094,14 +1094,14 @@ EXPORT_SYMBOL(s3c2410_dma_config);* * configure the dma source/destination hardware type and address * -* source: S3C2410_DMASRC_HW: source is hardware -* S3C2410_DMASRC_MEM: source is memory +* source: DMA_FROM_DEVICE: source is hardware +* DMA_TO_DEVICE: source is memory * * devaddr: physical address of the source */ int s3c2410_dma_devconfig (unsigned int channel, -enum s3c2410_dmasrc source, +enum dma_data_direction source,unsigned long devaddr) {struct s3c2410_dma_chan *chan =s3c_dma_lookup_channel (channel);
@@ -1131,7 +1131,7 @@ int s3c2410_dma_devconfig(unsigned int channel, hwcfg |=S3C2410_DISRCC_INC ;switch (source) { -case S3C2410_DMASRC_HW : +case DMA_FROME_DEVICE :/* source is hardware */ pr_debug ("%s: hw source, devaddr=%08lx, hwcfg=%d\n" , __func__, devaddr, hwcfg);
@@ -1142,7 +1142,7 @@ int s3c2410_dma_devconfig(unsigned int channel, chan->addr_reg =dma_regaddr (chan,S3C2410_DMA_DIDST );break ; -case S3C2410_DMASRC_MEM : +case DMA_TO_DEVICE :/* source is memory */ pr_debug ("%s: mem source, devaddr=%08lx, hwcfg=%d\n" , __func__, devaddr, hwcfg);
arch/arm/plat-samsung/include/plat/dma-s3c24xx.h +1 -1
@@ -47,7 +47,7 @@ struct s3c24xx_dma_selection {void (*direction)(struct s3c2410_dma_chan *chan,struct s3c24xx_dma_map *map, -enum s3c2410_dmasrc dir); +enum dma_data_direction dir); };extern int s3c24xx_dma_init_map (struct s3c24xx_dma_selection *sel);
arch/arm/plat-samsung/include/plat/dma.h +3 -6
@@ -10,17 +10,14 @@* published by the Free Software Foundation. */ +#include <linux/dma-mapping.h> +enum s3c2410_dma_buffresult {S3C2410_RES_OK ,S3C2410_RES_ERR ,S3C2410_RES_ABORT }; -enum s3c2410_dmasrc { -S3C2410_DMASRC_HW ,/* source is memory */ -S3C2410_DMASRC_MEM /* source is hardware */ -}; -/* enum s3c2410_chan_op * * operation codes passed to the DMA code by the user, and also used
@@ -111,7 +108,7 @@ extern int s3c2410_dma_config(unsigned int channel, int xferunit);*/ extern int s3c2410_dma_devconfig (unsigned int channel, -enum s3c2410_dmasrc source,unsigned long devaddr); +enum dma_data_direction source,unsigned long devaddr);/* s3c2410_dma_getposition *
arch/arm/plat-samsung/s3c-dma-ops.c +1 -4
@@ -48,10 +48,7 @@ static unsigned s3c_dma_request(enum dma_ch dma_ch, data->ch = dma_ch;list_add_tail (&data->node, &dma_list); -if (info->direction ==DMA_FROM_DEVICE ) -s3c2410_dma_devconfig (dma_ch,S3C2410_DMASRC_HW , info->fifo); -else -s3c2410_dma_devconfig (dma_ch,S3C2410_DMASRC_MEM , info->fifo); +s3c2410_dma_devconfig (dma_ch, info->direction, info->fifo);if (info->cap ==DMA_CYCLIC )s3c2410_dma_setflags (dma_ch,S3C2410_DMAF_CIRCULAR );
drivers/mmc/host/s3cmci.c +3 -3
@@ -913,9 +913,9 @@ request_done: }static void s3cmci_dma_setup (struct s3cmci_host *host, -enum s3c2410_dmasrc source) +enum dma_data_direction source) { -static enum s3c2410_dmasrc last_source =-1 ; +static enum dma_data_direction last_source =-1 ;static int setup_ok;if (last_source == source)
@@ -1087,7 +1087,7 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)BUG_ON ((data->flags &BOTH_DIR ) ==BOTH_DIR ); -s3cmci_dma_setup (host, rw ?S3C2410_DMASRC_MEM :S3C2410_DMASRC_HW ); +s3cmci_dma_setup (host, rw ?DMA_TO_DEVICE :DMA_FROM_DEVICE );s3c2410_dma_ctrl (host->dma,S3C2410_DMAOP_FLUSH ); dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
Signature · 1 line
1.7.1
v5 cover To use DMA generic APIs for Samsung DMA
In reply to Boojin KimQuoted 1 line · Boojin Kim
This patchset adds support DMA generic APIs for Samsung DMA.
Patches look good to me,
Are there any more users of the code in arch/arm/common/pl330.c? Else I think next step should be to move that file to drivers/dma/ and optionally merge it with the other pl330.c file there.
Thanks!
Linus Walleij
v5 cover To use DMA generic APIs for Samsung DMA
Quoted 6 lines · Linus Walleij
Quoted 1 line · Boojin Kim
This patchset adds support DMA generic APIs for Samsung DMA.
Patches look good to me,
Acked-by Linus Walleij <[email protected]>
Do you want these to go thru slave-dma tree or arm tree, I am okay with either...
Signature · 1 line
~Vinod
v5 cover To use DMA generic APIs for Samsung DMA
Quoted 6 lines · Vinod
Quoted 4 lines · Linus Walleij
Quoted 1 line · Boojin Kim
This patchset adds support DMA generic APIs for Samsung DMA.
Quoted 7 lines
Quoted 2 lines
Patches look good to me,
Acked-by Linus Walleij <[email protected]>Acked-by Vinod Koul <[email protected]>Do you want these to go thru slave-dma tree or arm tree, I am okay with either...
Hi Vinod,
Thanks.
I'd like to keep its topic branch in my tree to avoid conflicts with other samsung stuff and I think, it should be merged into your slave-dma tree also for same reason.
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git #next/topic-dma-pl330
Or if you want to make some branch for it in your tree, please let me know so that I can merge it in my tree also.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.
v5 cover To use DMA generic APIs for Samsung DMA
Quoted 17 lines · Kukjin Kim
Quoted 6 lines · Vinod
Quoted 4 lines · Linus Walleij
Quoted 1 line · Boojin Kim
This patchset adds support DMA generic APIs for Samsung DMA.
Quoted 7 lines
Quoted 2 lines
Patches look good to me,
Acked-by Linus Walleij <[email protected]>Acked-by Vinod Koul <[email protected]>Do you want these to go thru slave-dma tree or arm tree, I am okay with either...
Hi Vinod,
Quoted 7 lines
Thanks.
I'd like to keep its topic branch in my tree to avoid conflicts with other samsung stuff and I think, it should be merged into your slave-dma tree also for same reason.
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git#next/topic-dma-pl330Or if you want to make some branch for it in your tree, please let me know so that I can merge it in my tree also.
Okay can you update this branch with latest patchset (I think there were few comments on last patchset). Once you add all acks let me know the branch, I will merge it to my next
Signature · 1 line
~Vinod
v5 cover To use DMA generic APIs for Samsung DMA
Quoted 26 lines · Vinod
Quoted 4 lines · Kukjin Kim
Quoted 3 lines · Vinod
Quoted 1 line · Linus Walleij
On Wed, Jul 27, 2011 at 7:31 AM, Boojin Kim <[email protected]>
Quoted 8 lines · wrote:
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
This patchset adds support DMA generic APIs for Samsung DMA.
Patches look good to me,
Acked-by Linus Walleij <[email protected]>Acked-by Vinod Koul <[email protected]>Quoted 8 lines
Quoted 2 lines
Do you want these to go thru slave-dma tree or arm tree, I am okay with either...
Hi Vinod,
Thanks.
I'd like to keep its topic branch in my tree to avoid conflicts with other samsung
stuff and I think, it should be merged into your slave-dma tree also for same reason.
Quoted 1 line
Quoted 8 lines
Quoted 1 line
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git#next/topic-dma-pl330
Quoted 2 lines
Or if you want to make some branch for it in your tree, please let me know so
that I can merge it in my tree also.
Okay can you update this branch with latest patchset (I think there were few comments on last patchset). Once you add all acks let me know the branch, I will merge it to my next
Hi,
I updated it so that you can merge it to yours.
I think, if any fixing is required on that, it should be small so can be fixed easily after this merging.
If any problems, please let me know :)
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.
v5 cover To use DMA generic APIs for Samsung DMA
Quoted 36 lines · Kukjin Kim
Quoted 26 lines · Vinod
Quoted 4 lines · Kukjin Kim
Quoted 3 lines · Vinod
Quoted 1 line · Linus Walleij
On Wed, Jul 27, 2011 at 7:31 AM, Boojin Kim <[email protected]>
Quoted 8 lines · wrote:
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
This patchset adds support DMA generic APIs for Samsung DMA.
Patches look good to me,
Acked-by Linus Walleij <[email protected]>Acked-by Vinod Koul <[email protected]>Quoted 8 lines
Quoted 2 lines
Do you want these to go thru slave-dma tree or arm tree, I am okay with either...
Hi Vinod,
Thanks.
I'd like to keep its topic branch in my tree to avoid conflicts with other samsung
stuff and I think, it should be merged into your slave-dma tree also for same reason.
Quoted 1 line
Quoted 8 lines
Quoted 1 line
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git#next/topic-dma-pl330
Quoted 2 lines
Or if you want to make some branch for it in your tree, please let me know so
that I can merge it in my tree also.
Okay can you update this branch with latest patchset (I think there were few comments on last patchset). Once you add all acks let me know the branch, I will merge it to my next
Quoted 7 lines
Hi,
I updated it so that you can merge it to yours.
I think, if any fixing is required on that, it should be small so can be fixed easily after this merging.If any problems, please let me know :)
Well, that not how things are supposed to be done. Fixing an error introduced is not recommended, rather original patch set should be fixed.
Since you have already done 5 posting of your patch series, I am okay if you split things up, send me the parts that have already been reviewed and acked. I will host them on a branch for you. Once rest is reviewed and acked, I will merge this entire branch to my next.
Signature · 1 line
~Vinod
v5 cover To use DMA generic APIs for Samsung DMA
Quoted 49 lines · Vinod
Quoted 7 lines · Kukjin Kim
Quoted 6 lines · Vinod
Quoted 4 lines · Kukjin Kim
Quoted 3 lines · Vinod
Quoted 1 line · Linus Walleij
On Wed, Jul 27, 2011 at 7:31 AM, Boojin Kim
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines · wrote:
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
This patchset adds support DMA generic APIs for Samsung DMA.
Patches look good to me,
Acked-by Linus Walleij <[email protected]>Acked-by Vinod Koul <[email protected]>Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 2 lines
Do you want these to go thru slave-dma tree or arm tree, I am okay with either...
Hi Vinod,
Thanks.
I'd like to keep its topic branch in my tree to avoid conflicts with other
samsung
Quoted 4 lines
Quoted 4 lines
stuff and I think, it should be merged into your slave-dma tree also for same reason.
Quoted 2 lines
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git#next/topic-
Quoted 8 lines
Quoted 7 lines
dma-pl330
Quoted 2 lines
Or if you want to make some branch for it in your tree, please let me know so
that I can merge it in my tree also.
Okay can you update this branch with latest patchset (I think there were few comments on last patchset). Once you add all acks let me know the branch, I will merge it to my nextQuoted 4 lines
Hi,
I updated it so that you can merge it to yours.
I think, if any fixing is required on that, it should be small so can be fixed easilyafter this merging.
Quoted 3 lines
If any problems, please let me know :)
Quoted 8 lines
Well, that not how things are supposed to be done. Fixing an error introduced is not recommended, rather original patch set should be fixed.
Since you have already done 5 posting of your patch series, I am okay if you split things up, send me the parts that have already been reviewed and acked. I will host them on a branch for you. Once rest is reviewed and acked, I will merge this entire branch to my next.
OK, Boojin will send whole series soon.
Then if you make a branch for me, I will merge it too.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.
v5 cover To use DMA generic APIs for Samsung DMA
Quoted 4 lines · Kukjin Kim
Quoted 1 line · Vinod
OK, Boojin will send whole series soon.
Then if you make a branch for me, I will merge it too.
Sure,
I have created a branh for you off my next
git://git.infradead.org/users/vkoul/slave-dma.git samsung_dma
I will apply your series after reviewing and once its acked by other maintainers will merge to my next
Signature · 1 line
~Vinod