Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
dd58ffcf
Commit
dd58ffcf
authored
Mar 03, 2010
by
Dan Williams
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'coh' into dmaengine
parents
aa4d72ae
56a5d3cf
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
116 additions
and
123 deletions
+116
-123
arch/arm/mach-u300/include/mach/coh901318.h
arch/arm/mach-u300/include/mach/coh901318.h
+1
-1
drivers/dma/coh901318.c
drivers/dma/coh901318.c
+96
-88
drivers/dma/coh901318_lli.c
drivers/dma/coh901318_lli.c
+9
-14
drivers/dma/dmaengine.c
drivers/dma/dmaengine.c
+1
-0
drivers/dma/dmatest.c
drivers/dma/dmatest.c
+1
-1
drivers/dma/ioat/dma_v2.c
drivers/dma/ioat/dma_v2.c
+1
-1
drivers/dma/ipu/ipu_idmac.c
drivers/dma/ipu/ipu_idmac.c
+7
-18
No files found.
arch/arm/mach-u300/include/mach/coh901318.h
View file @
dd58ffcf
...
@@ -53,7 +53,7 @@ struct coh901318_params {
...
@@ -53,7 +53,7 @@ struct coh901318_params {
* struct coh_dma_channel - dma channel base
* struct coh_dma_channel - dma channel base
* @name: ascii name of dma channel
* @name: ascii name of dma channel
* @number: channel id number
* @number: channel id number
* @desc_nbr_max: number of preallocated descriptor
tor
s
* @desc_nbr_max: number of preallocated descriptors
* @priority_high: prio of channel, 0 low otherwise high.
* @priority_high: prio of channel, 0 low otherwise high.
* @param: configuration parameters
* @param: configuration parameters
* @dev_addr: physical address of periphal connected to channel
* @dev_addr: physical address of periphal connected to channel
...
...
drivers/dma/coh901318.c
View file @
dd58ffcf
...
@@ -39,7 +39,6 @@ struct coh901318_desc {
...
@@ -39,7 +39,6 @@ struct coh901318_desc {
unsigned
int
sg_len
;
unsigned
int
sg_len
;
struct
coh901318_lli
*
data
;
struct
coh901318_lli
*
data
;
enum
dma_data_direction
dir
;
enum
dma_data_direction
dir
;
int
pending_irqs
;
unsigned
long
flags
;
unsigned
long
flags
;
};
};
...
@@ -72,7 +71,6 @@ struct coh901318_chan {
...
@@ -72,7 +71,6 @@ struct coh901318_chan {
unsigned
long
nbr_active_done
;
unsigned
long
nbr_active_done
;
unsigned
long
busy
;
unsigned
long
busy
;
int
pending_irqs
;
struct
coh901318_base
*
base
;
struct
coh901318_base
*
base
;
};
};
...
@@ -80,18 +78,16 @@ struct coh901318_chan {
...
@@ -80,18 +78,16 @@ struct coh901318_chan {
static
void
coh901318_list_print
(
struct
coh901318_chan
*
cohc
,
static
void
coh901318_list_print
(
struct
coh901318_chan
*
cohc
,
struct
coh901318_lli
*
lli
)
struct
coh901318_lli
*
lli
)
{
{
struct
coh901318_lli
*
l
;
struct
coh901318_lli
*
l
=
lli
;
dma_addr_t
addr
=
virt_to_phys
(
lli
);
int
i
=
0
;
int
i
=
0
;
while
(
addr
)
{
while
(
l
)
{
l
=
phys_to_virt
(
addr
);
dev_vdbg
(
COHC_2_DEV
(
cohc
),
"i %d, lli %p, ctrl 0x%x, src 0x%x"
dev_vdbg
(
COHC_2_DEV
(
cohc
),
"i %d, lli %p, ctrl 0x%x, src 0x%x"
", dst 0x%x, link 0x%x
link_virt
0x%p
\n
"
,
", dst 0x%x, link 0x%x
virt_link_addr
0x%p
\n
"
,
i
,
l
,
l
->
control
,
l
->
src_addr
,
l
->
dst_addr
,
i
,
l
,
l
->
control
,
l
->
src_addr
,
l
->
dst_addr
,
l
->
link_addr
,
phys_to_virt
(
l
->
link_addr
)
);
l
->
link_addr
,
l
->
virt_link_addr
);
i
++
;
i
++
;
addr
=
l
->
link_addr
;
l
=
l
->
virt_
link_addr
;
}
}
}
}
...
@@ -125,7 +121,7 @@ static int coh901318_debugfs_read(struct file *file, char __user *buf,
...
@@ -125,7 +121,7 @@ static int coh901318_debugfs_read(struct file *file, char __user *buf,
goto
err_kmalloc
;
goto
err_kmalloc
;
tmp
=
dev_buf
;
tmp
=
dev_buf
;
tmp
+=
sprintf
(
tmp
,
"DMA -- enable dma channels
\n
"
);
tmp
+=
sprintf
(
tmp
,
"DMA -- enable
d
dma channels
\n
"
);
for
(
i
=
0
;
i
<
debugfs_dma_base
->
platform
->
max_channels
;
i
++
)
for
(
i
=
0
;
i
<
debugfs_dma_base
->
platform
->
max_channels
;
i
++
)
if
(
started_channels
&
(
1
<<
i
))
if
(
started_channels
&
(
1
<<
i
))
...
@@ -337,16 +333,22 @@ coh901318_desc_get(struct coh901318_chan *cohc)
...
@@ -337,16 +333,22 @@ coh901318_desc_get(struct coh901318_chan *cohc)
* TODO: alloc a pile of descs instead of just one,
* TODO: alloc a pile of descs instead of just one,
* avoid many small allocations.
* avoid many small allocations.
*/
*/
desc
=
k
m
alloc
(
sizeof
(
struct
coh901318_desc
),
GFP_NOWAIT
);
desc
=
k
z
alloc
(
sizeof
(
struct
coh901318_desc
),
GFP_NOWAIT
);
if
(
desc
==
NULL
)
if
(
desc
==
NULL
)
goto
out
;
goto
out
;
INIT_LIST_HEAD
(
&
desc
->
node
);
INIT_LIST_HEAD
(
&
desc
->
node
);
dma_async_tx_descriptor_init
(
&
desc
->
desc
,
&
cohc
->
chan
);
}
else
{
}
else
{
/* Reuse an old desc. */
/* Reuse an old desc. */
desc
=
list_first_entry
(
&
cohc
->
free
,
desc
=
list_first_entry
(
&
cohc
->
free
,
struct
coh901318_desc
,
struct
coh901318_desc
,
node
);
node
);
list_del
(
&
desc
->
node
);
list_del
(
&
desc
->
node
);
/* Initialize it a bit so it's not insane */
desc
->
sg
=
NULL
;
desc
->
sg_len
=
0
;
desc
->
desc
.
callback
=
NULL
;
desc
->
desc
.
callback_param
=
NULL
;
}
}
out:
out:
...
@@ -364,10 +366,6 @@ static void
...
@@ -364,10 +366,6 @@ static void
coh901318_desc_submit
(
struct
coh901318_chan
*
cohc
,
struct
coh901318_desc
*
desc
)
coh901318_desc_submit
(
struct
coh901318_chan
*
cohc
,
struct
coh901318_desc
*
desc
)
{
{
list_add_tail
(
&
desc
->
node
,
&
cohc
->
active
);
list_add_tail
(
&
desc
->
node
,
&
cohc
->
active
);
BUG_ON
(
cohc
->
pending_irqs
!=
0
);
cohc
->
pending_irqs
=
desc
->
pending_irqs
;
}
}
static
struct
coh901318_desc
*
static
struct
coh901318_desc
*
...
@@ -592,6 +590,10 @@ static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc)
...
@@ -592,6 +590,10 @@ static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc)
return
cohd_que
;
return
cohd_que
;
}
}
/*
* This tasklet is called from the interrupt handler to
* handle each descriptor (DMA job) that is sent to a channel.
*/
static
void
dma_tasklet
(
unsigned
long
data
)
static
void
dma_tasklet
(
unsigned
long
data
)
{
{
struct
coh901318_chan
*
cohc
=
(
struct
coh901318_chan
*
)
data
;
struct
coh901318_chan
*
cohc
=
(
struct
coh901318_chan
*
)
data
;
...
@@ -600,57 +602,58 @@ static void dma_tasklet(unsigned long data)
...
@@ -600,57 +602,58 @@ static void dma_tasklet(unsigned long data)
dma_async_tx_callback
callback
;
dma_async_tx_callback
callback
;
void
*
callback_param
;
void
*
callback_param
;
dev_vdbg
(
COHC_2_DEV
(
cohc
),
"[%s] chan_id %d"
" nbr_active_done %ld
\n
"
,
__func__
,
cohc
->
id
,
cohc
->
nbr_active_done
);
spin_lock_irqsave
(
&
cohc
->
lock
,
flags
);
spin_lock_irqsave
(
&
cohc
->
lock
,
flags
);
/* get first active entry from list */
/* get first active
descriptor
entry from list */
cohd_fin
=
coh901318_first_active_get
(
cohc
);
cohd_fin
=
coh901318_first_active_get
(
cohc
);
BUG_ON
(
cohd_fin
->
pending_irqs
==
0
);
if
(
cohd_fin
==
NULL
)
if
(
cohd_fin
==
NULL
)
goto
err
;
goto
err
;
cohd_fin
->
pending_irqs
--
;
/* locate callback to client */
cohc
->
completed
=
cohd_fin
->
desc
.
cookie
;
callback
=
cohd_fin
->
desc
.
callback
;
callback_param
=
cohd_fin
->
desc
.
callback_param
;
BUG_ON
(
cohc
->
nbr_active_done
&&
cohd_fin
==
NULL
);
if
(
cohc
->
nbr_active_done
==
0
)
/* sign this job as completed on the channel */
return
;
cohc
->
completed
=
cohd_fin
->
desc
.
cookie
;
if
(
!
cohd_fin
->
pending_irqs
)
{
/* release the lli allocation and remove the descriptor */
/* release the lli allocation*/
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd_fin
->
data
);
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd_fin
->
data
);
}
dev_vdbg
(
COHC_2_DEV
(
cohc
),
"[%s] chan_id %d pending_irqs %d"
/* return desc to free-list */
" nbr_active_done %ld
\n
"
,
__func__
,
coh901318_desc_remove
(
cohd_fin
);
cohc
->
id
,
cohc
->
pending_irqs
,
cohc
->
nbr_active_done
);
coh901318_desc_free
(
cohc
,
cohd_fin
);
/* callback to client */
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flags
);
callback
=
cohd_fin
->
desc
.
callback
;
callback_param
=
cohd_fin
->
desc
.
callback_param
;
if
(
!
cohd_fin
->
pending_irqs
)
{
/* Call the callback when we're done */
coh901318_desc_remove
(
cohd_fin
);
if
(
callback
)
callback
(
callback_param
);
/* return desc to free-list */
spin_lock_irqsave
(
&
cohc
->
lock
,
flags
);
coh901318_desc_free
(
cohc
,
cohd_fin
);
}
if
(
cohc
->
nbr_active_done
)
/*
* If another interrupt fired while the tasklet was scheduling,
* we don't get called twice, so we have this number of active
* counter that keep track of the number of IRQs expected to
* be handled for this channel. If there happen to be more than
* one IRQ to be ack:ed, we simply schedule this tasklet again.
*/
cohc
->
nbr_active_done
--
;
cohc
->
nbr_active_done
--
;
if
(
cohc
->
nbr_active_done
)
{
if
(
cohc
->
nbr_active_done
)
{
dev_dbg
(
COHC_2_DEV
(
cohc
),
"scheduling tasklet again, new IRQs "
"came in while we were scheduling this tasklet
\n
"
);
if
(
cohc_chan_conf
(
cohc
)
->
priority_high
)
if
(
cohc_chan_conf
(
cohc
)
->
priority_high
)
tasklet_hi_schedule
(
&
cohc
->
tasklet
);
tasklet_hi_schedule
(
&
cohc
->
tasklet
);
else
else
tasklet_schedule
(
&
cohc
->
tasklet
);
tasklet_schedule
(
&
cohc
->
tasklet
);
}
}
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flags
);
if
(
callback
)
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flags
);
callback
(
callback_param
);
return
;
return
;
...
@@ -669,16 +672,17 @@ static void dma_tc_handle(struct coh901318_chan *cohc)
...
@@ -669,16 +672,17 @@ static void dma_tc_handle(struct coh901318_chan *cohc)
if
(
!
cohc
->
allocated
)
if
(
!
cohc
->
allocated
)
return
;
return
;
BUG_ON
(
cohc
->
pending_irqs
==
0
);
spin_lock
(
&
cohc
->
lock
);
cohc
->
pending_irqs
--
;
cohc
->
nbr_active_done
++
;
cohc
->
nbr_active_done
++
;
if
(
coh
c
->
pending_irqs
==
0
&&
coh
901318_queue_start
(
cohc
)
==
NULL
)
if
(
coh901318_queue_start
(
cohc
)
==
NULL
)
cohc
->
busy
=
0
;
cohc
->
busy
=
0
;
BUG_ON
(
list_empty
(
&
cohc
->
active
));
BUG_ON
(
list_empty
(
&
cohc
->
active
));
spin_unlock
(
&
cohc
->
lock
);
if
(
cohc_chan_conf
(
cohc
)
->
priority_high
)
if
(
cohc_chan_conf
(
cohc
)
->
priority_high
)
tasklet_hi_schedule
(
&
cohc
->
tasklet
);
tasklet_hi_schedule
(
&
cohc
->
tasklet
);
else
else
...
@@ -872,6 +876,7 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
...
@@ -872,6 +876,7 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
struct
coh901318_chan
*
cohc
=
to_coh901318_chan
(
chan
);
struct
coh901318_chan
*
cohc
=
to_coh901318_chan
(
chan
);
int
lli_len
;
int
lli_len
;
u32
ctrl_last
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_last
;
u32
ctrl_last
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_last
;
int
ret
;
spin_lock_irqsave
(
&
cohc
->
lock
,
flg
);
spin_lock_irqsave
(
&
cohc
->
lock
,
flg
);
...
@@ -892,22 +897,19 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
...
@@ -892,22 +897,19 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
if
(
data
==
NULL
)
if
(
data
==
NULL
)
goto
err
;
goto
err
;
cohd
=
coh901318_desc_get
(
cohc
);
ret
=
coh901318_lli_fill_memcpy
(
cohd
->
sg
=
NULL
;
cohd
->
sg_len
=
0
;
cohd
->
data
=
data
;
cohd
->
pending_irqs
=
coh901318_lli_fill_memcpy
(
&
cohc
->
base
->
pool
,
data
,
src
,
size
,
dest
,
&
cohc
->
base
->
pool
,
data
,
src
,
size
,
dest
,
cohc_chan_param
(
cohc
)
->
ctrl_lli_chained
,
cohc_chan_param
(
cohc
)
->
ctrl_lli_chained
,
ctrl_last
);
ctrl_last
);
cohd
->
flags
=
flags
;
if
(
ret
)
goto
err
;
COH_DBG
(
coh901318_list_print
(
cohc
,
data
));
COH_DBG
(
coh901318_list_print
(
cohc
,
data
));
dma_async_tx_descriptor_init
(
&
cohd
->
desc
,
chan
);
/* Pick a descriptor to handle this transfer */
cohd
=
coh901318_desc_get
(
cohc
);
cohd
->
data
=
data
;
cohd
->
flags
=
flags
;
cohd
->
desc
.
tx_submit
=
coh901318_tx_submit
;
cohd
->
desc
.
tx_submit
=
coh901318_tx_submit
;
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
...
@@ -926,6 +928,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
...
@@ -926,6 +928,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
struct
coh901318_chan
*
cohc
=
to_coh901318_chan
(
chan
);
struct
coh901318_chan
*
cohc
=
to_coh901318_chan
(
chan
);
struct
coh901318_lli
*
data
;
struct
coh901318_lli
*
data
;
struct
coh901318_desc
*
cohd
;
struct
coh901318_desc
*
cohd
;
const
struct
coh901318_params
*
params
;
struct
scatterlist
*
sg
;
struct
scatterlist
*
sg
;
int
len
=
0
;
int
len
=
0
;
int
size
;
int
size
;
...
@@ -933,7 +936,9 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
...
@@ -933,7 +936,9 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
u32
ctrl_chained
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_chained
;
u32
ctrl_chained
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_chained
;
u32
ctrl
=
cohc_chan_param
(
cohc
)
->
ctrl_lli
;
u32
ctrl
=
cohc_chan_param
(
cohc
)
->
ctrl_lli
;
u32
ctrl_last
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_last
;
u32
ctrl_last
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_last
;
u32
config
;
unsigned
long
flg
;
unsigned
long
flg
;
int
ret
;
if
(
!
sgl
)
if
(
!
sgl
)
goto
out
;
goto
out
;
...
@@ -949,15 +954,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
...
@@ -949,15 +954,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
/* Trigger interrupt after last lli */
/* Trigger interrupt after last lli */
ctrl_last
|=
COH901318_CX_CTRL_TC_IRQ_ENABLE
;
ctrl_last
|=
COH901318_CX_CTRL_TC_IRQ_ENABLE
;
cohd
=
coh901318_desc_get
(
cohc
);
params
=
cohc_chan_param
(
cohc
);
cohd
->
sg
=
NULL
;
config
=
params
->
config
;
cohd
->
sg_len
=
0
;
cohd
->
dir
=
direction
;
if
(
direction
==
DMA_TO_DEVICE
)
{
if
(
direction
==
DMA_TO_DEVICE
)
{
u32
tx_flags
=
COH901318_CX_CTRL_PRDD_SOURCE
|
u32
tx_flags
=
COH901318_CX_CTRL_PRDD_SOURCE
|
COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE
;
COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE
;
config
|=
COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY
;
ctrl_chained
|=
tx_flags
;
ctrl_chained
|=
tx_flags
;
ctrl_last
|=
tx_flags
;
ctrl_last
|=
tx_flags
;
ctrl
|=
tx_flags
;
ctrl
|=
tx_flags
;
...
@@ -965,16 +969,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
...
@@ -965,16 +969,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
u32
rx_flags
=
COH901318_CX_CTRL_PRDD_DEST
|
u32
rx_flags
=
COH901318_CX_CTRL_PRDD_DEST
|
COH901318_CX_CTRL_DST_ADDR_INC_ENABLE
;
COH901318_CX_CTRL_DST_ADDR_INC_ENABLE
;
config
|=
COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY
;
ctrl_chained
|=
rx_flags
;
ctrl_chained
|=
rx_flags
;
ctrl_last
|=
rx_flags
;
ctrl_last
|=
rx_flags
;
ctrl
|=
rx_flags
;
ctrl
|=
rx_flags
;
}
else
}
else
goto
err_direction
;
goto
err_direction
;
dma_async_tx_descriptor_init
(
&
cohd
->
desc
,
chan
);
coh901318_set_conf
(
cohc
,
config
);
cohd
->
desc
.
tx_submit
=
coh901318_tx_submit
;
/* The dma only supports transmitting packages up to
/* The dma only supports transmitting packages up to
* MAX_DMA_PACKET_SIZE. Calculate to total number of
* MAX_DMA_PACKET_SIZE. Calculate to total number of
...
@@ -996,32 +998,37 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
...
@@ -996,32 +998,37 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
len
+=
factor
;
len
+=
factor
;
}
}
pr_debug
(
"Allocate %d lli:s for this transfer
\n
"
,
len
);
data
=
coh901318_lli_alloc
(
&
cohc
->
base
->
pool
,
len
);
data
=
coh901318_lli_alloc
(
&
cohc
->
base
->
pool
,
len
);
if
(
data
==
NULL
)
if
(
data
==
NULL
)
goto
err_dma_alloc
;
goto
err_dma_alloc
;
/* initiate allocated data list */
/* initiate allocated data list */
cohd
->
pending_irqs
=
ret
=
coh901318_lli_fill_sg
(
&
cohc
->
base
->
pool
,
data
,
sgl
,
sg_len
,
coh901318_lli_fill_sg
(
&
cohc
->
base
->
pool
,
data
,
sgl
,
sg_len
,
cohc_dev_addr
(
cohc
),
cohc_dev_addr
(
cohc
),
ctrl_chained
,
ctrl_chained
,
ctrl
,
ctrl
,
ctrl_last
,
ctrl_last
,
direction
,
COH901318_CX_CTRL_TC_IRQ_ENABLE
);
direction
,
COH901318_CX_CTRL_TC_IRQ_ENABLE
);
cohd
->
data
=
data
;
if
(
ret
)
goto
err_lli_fill
;
cohd
->
flags
=
flags
;
COH_DBG
(
coh901318_list_print
(
cohc
,
data
));
COH_DBG
(
coh901318_list_print
(
cohc
,
data
));
/* Pick a descriptor to handle this transfer */
cohd
=
coh901318_desc_get
(
cohc
);
cohd
->
dir
=
direction
;
cohd
->
flags
=
flags
;
cohd
->
desc
.
tx_submit
=
coh901318_tx_submit
;
cohd
->
data
=
data
;
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
return
&
cohd
->
desc
;
return
&
cohd
->
desc
;
err_lli_fill:
err_dma_alloc:
err_dma_alloc:
err_direction:
err_direction:
coh901318_desc_remove
(
cohd
);
coh901318_desc_free
(
cohc
,
cohd
);
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
out:
out:
return
NULL
;
return
NULL
;
...
@@ -1094,9 +1101,8 @@ coh901318_terminate_all(struct dma_chan *chan)
...
@@ -1094,9 +1101,8 @@ coh901318_terminate_all(struct dma_chan *chan)
/* release the lli allocation*/
/* release the lli allocation*/
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd
->
data
);
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd
->
data
);
coh901318_desc_remove
(
cohd
);
/* return desc to free-list */
/* return desc to free-list */
coh901318_desc_remove
(
cohd
);
coh901318_desc_free
(
cohc
,
cohd
);
coh901318_desc_free
(
cohc
,
cohd
);
}
}
...
@@ -1104,16 +1110,14 @@ coh901318_terminate_all(struct dma_chan *chan)
...
@@ -1104,16 +1110,14 @@ coh901318_terminate_all(struct dma_chan *chan)
/* release the lli allocation*/
/* release the lli allocation*/
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd
->
data
);
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd
->
data
);
coh901318_desc_remove
(
cohd
);
/* return desc to free-list */
/* return desc to free-list */
coh901318_desc_remove
(
cohd
);
coh901318_desc_free
(
cohc
,
cohd
);
coh901318_desc_free
(
cohc
,
cohd
);
}
}
cohc
->
nbr_active_done
=
0
;
cohc
->
nbr_active_done
=
0
;
cohc
->
busy
=
0
;
cohc
->
busy
=
0
;
cohc
->
pending_irqs
=
0
;
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flags
);
}
}
...
@@ -1140,7 +1144,6 @@ void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
...
@@ -1140,7 +1144,6 @@ void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
spin_lock_init
(
&
cohc
->
lock
);
spin_lock_init
(
&
cohc
->
lock
);
cohc
->
pending_irqs
=
0
;
cohc
->
nbr_active_done
=
0
;
cohc
->
nbr_active_done
=
0
;
cohc
->
busy
=
0
;
cohc
->
busy
=
0
;
INIT_LIST_HEAD
(
&
cohc
->
free
);
INIT_LIST_HEAD
(
&
cohc
->
free
);
...
@@ -1256,12 +1259,17 @@ static int __init coh901318_probe(struct platform_device *pdev)
...
@@ -1256,12 +1259,17 @@ static int __init coh901318_probe(struct platform_device *pdev)
base
->
dma_memcpy
.
device_issue_pending
=
coh901318_issue_pending
;
base
->
dma_memcpy
.
device_issue_pending
=
coh901318_issue_pending
;
base
->
dma_memcpy
.
device_terminate_all
=
coh901318_terminate_all
;
base
->
dma_memcpy
.
device_terminate_all
=
coh901318_terminate_all
;
base
->
dma_memcpy
.
dev
=
&
pdev
->
dev
;
base
->
dma_memcpy
.
dev
=
&
pdev
->
dev
;
/*
* This controller can only access address at even 32bit boundaries,
* i.e. 2^2
*/
base
->
dma_memcpy
.
copy_align
=
2
;
err
=
dma_async_device_register
(
&
base
->
dma_memcpy
);
err
=
dma_async_device_register
(
&
base
->
dma_memcpy
);
if
(
err
)
if
(
err
)
goto
err_register_memcpy
;
goto
err_register_memcpy
;
dev_
dbg
(
&
pdev
->
dev
,
"Initialized COH901318 DMA on virtual base 0x%08x
\n
"
,
dev_
info
(
&
pdev
->
dev
,
"Initialized COH901318 DMA on virtual base 0x%08x
\n
"
,
(
u32
)
base
->
virtbase
);
(
u32
)
base
->
virtbase
);
return
err
;
return
err
;
...
...
drivers/dma/coh901318_lli.c
View file @
dd58ffcf
...
@@ -74,6 +74,8 @@ coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
...
@@ -74,6 +74,8 @@ coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
lli
=
head
;
lli
=
head
;
lli
->
phy_this
=
phy
;
lli
->
phy_this
=
phy
;
lli
->
link_addr
=
0x00000000
;
lli
->
virt_link_addr
=
0x00000000U
;
for
(
i
=
1
;
i
<
len
;
i
++
)
{
for
(
i
=
1
;
i
<
len
;
i
++
)
{
lli_prev
=
lli
;
lli_prev
=
lli
;
...
@@ -85,13 +87,13 @@ coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
...
@@ -85,13 +87,13 @@ coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
DEBUGFS_POOL_COUNTER_ADD
(
pool
,
1
);
DEBUGFS_POOL_COUNTER_ADD
(
pool
,
1
);
lli
->
phy_this
=
phy
;
lli
->
phy_this
=
phy
;
lli
->
link_addr
=
0x00000000
;
lli
->
virt_link_addr
=
0x00000000U
;
lli_prev
->
link_addr
=
phy
;
lli_prev
->
link_addr
=
phy
;
lli_prev
->
virt_link_addr
=
lli
;
lli_prev
->
virt_link_addr
=
lli
;
}
}
lli
->
link_addr
=
0x00000000U
;
spin_unlock
(
&
pool
->
lock
);
spin_unlock
(
&
pool
->
lock
);
return
head
;
return
head
;
...
@@ -166,8 +168,7 @@ coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
...
@@ -166,8 +168,7 @@ coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
lli
->
src_addr
=
src
;
lli
->
src_addr
=
src
;
lli
->
dst_addr
=
dst
;
lli
->
dst_addr
=
dst
;
/* One irq per single transfer */
return
0
;
return
1
;
}
}
int
int
...
@@ -223,8 +224,7 @@ coh901318_lli_fill_single(struct coh901318_pool *pool,
...
@@ -223,8 +224,7 @@ coh901318_lli_fill_single(struct coh901318_pool *pool,
lli
->
src_addr
=
src
;
lli
->
src_addr
=
src
;
lli
->
dst_addr
=
dst
;
lli
->
dst_addr
=
dst
;
/* One irq per single transfer */
return
0
;
return
1
;
}
}
int
int
...
@@ -240,7 +240,6 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
...
@@ -240,7 +240,6 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
u32
ctrl_sg
;
u32
ctrl_sg
;
dma_addr_t
src
=
0
;
dma_addr_t
src
=
0
;
dma_addr_t
dst
=
0
;
dma_addr_t
dst
=
0
;
int
nbr_of_irq
=
0
;
u32
bytes_to_transfer
;
u32
bytes_to_transfer
;
u32
elem_size
;
u32
elem_size
;
...
@@ -269,15 +268,12 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
...
@@ -269,15 +268,12 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
ctrl_sg
=
ctrl
?
ctrl
:
ctrl_last
;
ctrl_sg
=
ctrl
?
ctrl
:
ctrl_last
;
if
((
ctrl_sg
&
ctrl_irq_mask
))
nbr_of_irq
++
;
if
(
dir
==
DMA_TO_DEVICE
)
if
(
dir
==
DMA_TO_DEVICE
)
/* increment source address */
/* increment source address */
src
=
sg_
dma_addres
s
(
sg
);
src
=
sg_
phy
s
(
sg
);
else
else
/* increment destination address */
/* increment destination address */
dst
=
sg_
dma_addres
s
(
sg
);
dst
=
sg_
phy
s
(
sg
);
bytes_to_transfer
=
sg_dma_len
(
sg
);
bytes_to_transfer
=
sg_dma_len
(
sg
);
...
@@ -310,8 +306,7 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
...
@@ -310,8 +306,7 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
}
}
spin_unlock
(
&
pool
->
lock
);
spin_unlock
(
&
pool
->
lock
);
/* There can be many IRQs per sg transfer */
return
0
;
return
nbr_of_irq
;
err:
err:
spin_unlock
(
&
pool
->
lock
);
spin_unlock
(
&
pool
->
lock
);
return
-
EINVAL
;
return
-
EINVAL
;
...
...
drivers/dma/dmaengine.c
View file @
dd58ffcf
...
@@ -826,6 +826,7 @@ void dma_async_device_unregister(struct dma_device *device)
...
@@ -826,6 +826,7 @@ void dma_async_device_unregister(struct dma_device *device)
chan
->
dev
->
chan
=
NULL
;
chan
->
dev
->
chan
=
NULL
;
mutex_unlock
(
&
dma_list_mutex
);
mutex_unlock
(
&
dma_list_mutex
);
device_unregister
(
&
chan
->
dev
->
device
);
device_unregister
(
&
chan
->
dev
->
device
);
free_percpu
(
chan
->
local
);
}
}
}
}
EXPORT_SYMBOL
(
dma_async_device_unregister
);
EXPORT_SYMBOL
(
dma_async_device_unregister
);
...
...
drivers/dma/dmatest.c
View file @
dd58ffcf
...
@@ -467,7 +467,7 @@ static int dmatest_func(void *data)
...
@@ -467,7 +467,7 @@ static int dmatest_func(void *data)
if
(
iterations
>
0
)
if
(
iterations
>
0
)
while
(
!
kthread_should_stop
())
{
while
(
!
kthread_should_stop
())
{
DECLARE_WAIT_QUEUE_HEAD
(
wait_dmatest_exit
);
DECLARE_WAIT_QUEUE_HEAD
_ONSTACK
(
wait_dmatest_exit
);
interruptible_sleep_on
(
&
wait_dmatest_exit
);
interruptible_sleep_on
(
&
wait_dmatest_exit
);
}
}
...
...
drivers/dma/ioat/dma_v2.c
View file @
dd58ffcf
...
@@ -241,7 +241,7 @@ int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo)
...
@@ -241,7 +241,7 @@ int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo)
if
(
is_ioat_active
(
status
)
||
is_ioat_idle
(
status
))
if
(
is_ioat_active
(
status
)
||
is_ioat_idle
(
status
))
ioat_suspend
(
chan
);
ioat_suspend
(
chan
);
while
(
is_ioat_active
(
status
)
||
is_ioat_idle
(
status
))
{
while
(
is_ioat_active
(
status
)
||
is_ioat_idle
(
status
))
{
if
(
end
&&
time_after
(
jiffies
,
end
))
{
if
(
tmo
&&
time_after
(
jiffies
,
end
))
{
err
=
-
ETIMEDOUT
;
err
=
-
ETIMEDOUT
;
break
;
break
;
}
}
...
...
drivers/dma/ipu/ipu_idmac.c
View file @
dd58ffcf
...
@@ -748,11 +748,9 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
...
@@ -748,11 +748,9 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
* @buffer_n: buffer number to update.
* @buffer_n: buffer number to update.
* 0 or 1 are the only valid values.
* 0 or 1 are the only valid values.
* @phyaddr: buffer physical address.
* @phyaddr: buffer physical address.
* @return: Returns 0 on success or negative error code on failure. This
* function will fail if the buffer is set to ready.
*/
*/
/* Called under spin_lock(_irqsave)(&ichan->lock) */
/* Called under spin_lock(_irqsave)(&ichan->lock) */
static
int
ipu_update_channel_buffer
(
struct
idmac_channel
*
ichan
,
static
void
ipu_update_channel_buffer
(
struct
idmac_channel
*
ichan
,
int
buffer_n
,
dma_addr_t
phyaddr
)
int
buffer_n
,
dma_addr_t
phyaddr
)
{
{
enum
ipu_channel
channel
=
ichan
->
dma_chan
.
chan_id
;
enum
ipu_channel
channel
=
ichan
->
dma_chan
.
chan_id
;
...
@@ -793,8 +791,6 @@ static int ipu_update_channel_buffer(struct idmac_channel *ichan,
...
@@ -793,8 +791,6 @@ static int ipu_update_channel_buffer(struct idmac_channel *ichan,
}
}
spin_unlock_irqrestore
(
&
ipu_data
.
lock
,
flags
);
spin_unlock_irqrestore
(
&
ipu_data
.
lock
,
flags
);
return
0
;
}
}
/* Called under spin_lock_irqsave(&ichan->lock) */
/* Called under spin_lock_irqsave(&ichan->lock) */
...
@@ -803,7 +799,6 @@ static int ipu_submit_buffer(struct idmac_channel *ichan,
...
@@ -803,7 +799,6 @@ static int ipu_submit_buffer(struct idmac_channel *ichan,
{
{
unsigned
int
chan_id
=
ichan
->
dma_chan
.
chan_id
;
unsigned
int
chan_id
=
ichan
->
dma_chan
.
chan_id
;
struct
device
*
dev
=
&
ichan
->
dma_chan
.
dev
->
device
;
struct
device
*
dev
=
&
ichan
->
dma_chan
.
dev
->
device
;
int
ret
;
if
(
async_tx_test_ack
(
&
desc
->
txd
))
if
(
async_tx_test_ack
(
&
desc
->
txd
))
return
-
EINTR
;
return
-
EINTR
;
...
@@ -814,14 +809,7 @@ static int ipu_submit_buffer(struct idmac_channel *ichan,
...
@@ -814,14 +809,7 @@ static int ipu_submit_buffer(struct idmac_channel *ichan,
* could make it conditional on status >= IPU_CHANNEL_ENABLED, but
* could make it conditional on status >= IPU_CHANNEL_ENABLED, but
* doing it again shouldn't hurt either.
* doing it again shouldn't hurt either.
*/
*/
ret
=
ipu_update_channel_buffer
(
ichan
,
buf_idx
,
ipu_update_channel_buffer
(
ichan
,
buf_idx
,
sg_dma_address
(
sg
));
sg_dma_address
(
sg
));
if
(
ret
<
0
)
{
dev_err
(
dev
,
"Updating sg %p on channel 0x%x buffer %d failed!
\n
"
,
sg
,
chan_id
,
buf_idx
);
return
ret
;
}
ipu_select_buffer
(
chan_id
,
buf_idx
);
ipu_select_buffer
(
chan_id
,
buf_idx
);
dev_dbg
(
dev
,
"Updated sg %p on channel 0x%x buffer %d
\n
"
,
dev_dbg
(
dev
,
"Updated sg %p on channel 0x%x buffer %d
\n
"
,
...
@@ -1366,9 +1354,10 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
...
@@ -1366,9 +1354,10 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
if
(
likely
(
sgnew
)
&&
if
(
likely
(
sgnew
)
&&
ipu_submit_buffer
(
ichan
,
descnew
,
sgnew
,
ichan
->
active_buffer
)
<
0
)
{
ipu_submit_buffer
(
ichan
,
descnew
,
sgnew
,
ichan
->
active_buffer
)
<
0
)
{
callback
=
desc
->
txd
.
callback
;
callback
=
desc
new
->
txd
.
callback
;
callback_param
=
desc
->
txd
.
callback_param
;
callback_param
=
desc
new
->
txd
.
callback_param
;
spin_unlock
(
&
ichan
->
lock
);
spin_unlock
(
&
ichan
->
lock
);
if
(
callback
)
callback
(
callback_param
);
callback
(
callback_param
);
spin_lock
(
&
ichan
->
lock
);
spin_lock
(
&
ichan
->
lock
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment