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
4d3c4636
Commit
4d3c4636
authored
Jul 13, 2012
by
Kukjin Kim
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next/devel-dma-ops' into next/dt-samsung
parents
bd0a521e
3688be49
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
105 additions
and
81 deletions
+105
-81
arch/arm/plat-samsung/dma-ops.c
arch/arm/plat-samsung/dma-ops.c
+42
-34
arch/arm/plat-samsung/include/plat/dma-ops.h
arch/arm/plat-samsung/include/plat/dma-ops.h
+12
-8
arch/arm/plat-samsung/s3c-dma-ops.c
arch/arm/plat-samsung/s3c-dma-ops.c
+22
-17
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-s3c64xx.c
+19
-14
sound/soc/samsung/dma.c
sound/soc/samsung/dma.c
+10
-8
No files found.
arch/arm/plat-samsung/dma-ops.c
View file @
4d3c4636
...
...
@@ -19,72 +19,79 @@
#include <mach/dma.h>
static
unsigned
samsung_dmadev_request
(
enum
dma_ch
dma_ch
,
struct
samsung_dma_
info
*
info
)
struct
samsung_dma_
req
*
param
)
{
struct
dma_chan
*
chan
;
dma_cap_mask_t
mask
;
struct
dma_slave_config
slave_config
;
void
*
filter_param
;
dma_cap_zero
(
mask
);
dma_cap_set
(
info
->
cap
,
mask
);
dma_cap_set
(
param
->
cap
,
mask
);
/*
* If a dma channel property of a device node from device tree is
* specified, use that as the fliter parameter.
*/
filter_param
=
(
dma_ch
==
DMACH_DT_PROP
)
?
(
void
*
)
info
->
dt_dmach_prop
:
(
void
*
)
dma_ch
;
chan
=
dma_request_channel
(
mask
,
pl330_filter
,
filter_param
);
filter_param
=
(
dma_ch
==
DMACH_DT_PROP
)
?
(
void
*
)
param
->
dt_dmach_prop
:
(
void
*
)
dma_ch
;
return
(
unsigned
)
dma_request_channel
(
mask
,
pl330_filter
,
filter_param
);
}
static
int
samsung_dmadev_release
(
unsigned
ch
,
void
*
param
)
{
dma_release_channel
((
struct
dma_chan
*
)
ch
);
if
(
info
->
direction
==
DMA_DEV_TO_MEM
)
{
return
0
;
}
static
int
samsung_dmadev_config
(
unsigned
ch
,
struct
samsung_dma_config
*
param
)
{
struct
dma_chan
*
chan
=
(
struct
dma_chan
*
)
ch
;
struct
dma_slave_config
slave_config
;
if
(
param
->
direction
==
DMA_DEV_TO_MEM
)
{
memset
(
&
slave_config
,
0
,
sizeof
(
struct
dma_slave_config
));
slave_config
.
direction
=
info
->
direction
;
slave_config
.
src_addr
=
info
->
fifo
;
slave_config
.
src_addr_width
=
info
->
width
;
slave_config
.
direction
=
param
->
direction
;
slave_config
.
src_addr
=
param
->
fifo
;
slave_config
.
src_addr_width
=
param
->
width
;
slave_config
.
src_maxburst
=
1
;
dmaengine_slave_config
(
chan
,
&
slave_config
);
}
else
if
(
info
->
direction
==
DMA_MEM_TO_DEV
)
{
}
else
if
(
param
->
direction
==
DMA_MEM_TO_DEV
)
{
memset
(
&
slave_config
,
0
,
sizeof
(
struct
dma_slave_config
));
slave_config
.
direction
=
info
->
direction
;
slave_config
.
dst_addr
=
info
->
fifo
;
slave_config
.
dst_addr_width
=
info
->
width
;
slave_config
.
direction
=
param
->
direction
;
slave_config
.
dst_addr
=
param
->
fifo
;
slave_config
.
dst_addr_width
=
param
->
width
;
slave_config
.
dst_maxburst
=
1
;
dmaengine_slave_config
(
chan
,
&
slave_config
);
}
else
{
pr_warn
(
"unsupported direction
\n
"
);
return
-
EINVAL
;
}
return
(
unsigned
)
chan
;
}
static
int
samsung_dmadev_release
(
unsigned
ch
,
struct
s3c2410_dma_client
*
client
)
{
dma_release_channel
((
struct
dma_chan
*
)
ch
);
return
0
;
}
static
int
samsung_dmadev_prepare
(
unsigned
ch
,
struct
samsung_dma_prep
_info
*
info
)
struct
samsung_dma_prep
*
param
)
{
struct
scatterlist
sg
;
struct
dma_chan
*
chan
=
(
struct
dma_chan
*
)
ch
;
struct
dma_async_tx_descriptor
*
desc
;
switch
(
info
->
cap
)
{
switch
(
param
->
cap
)
{
case
DMA_SLAVE
:
sg_init_table
(
&
sg
,
1
);
sg_dma_len
(
&
sg
)
=
info
->
len
;
sg_set_page
(
&
sg
,
pfn_to_page
(
PFN_DOWN
(
info
->
buf
)),
info
->
len
,
offset_in_page
(
info
->
buf
));
sg_dma_address
(
&
sg
)
=
info
->
buf
;
sg_dma_len
(
&
sg
)
=
param
->
len
;
sg_set_page
(
&
sg
,
pfn_to_page
(
PFN_DOWN
(
param
->
buf
)),
param
->
len
,
offset_in_page
(
param
->
buf
));
sg_dma_address
(
&
sg
)
=
param
->
buf
;
desc
=
dmaengine_prep_slave_sg
(
chan
,
&
sg
,
1
,
info
->
direction
,
DMA_PREP_INTERRUPT
);
&
sg
,
1
,
param
->
direction
,
DMA_PREP_INTERRUPT
);
break
;
case
DMA_CYCLIC
:
desc
=
dmaengine_prep_dma_cyclic
(
chan
,
info
->
buf
,
info
->
len
,
info
->
period
,
info
->
direction
);
desc
=
dmaengine_prep_dma_cyclic
(
chan
,
param
->
buf
,
param
->
len
,
param
->
period
,
param
->
direction
);
break
;
default:
dev_err
(
&
chan
->
dev
->
device
,
"unsupported format
\n
"
);
...
...
@@ -96,8 +103,8 @@ static int samsung_dmadev_prepare(unsigned ch,
return
-
EFAULT
;
}
desc
->
callback
=
info
->
fp
;
desc
->
callback_param
=
info
->
fp_param
;
desc
->
callback
=
param
->
fp
;
desc
->
callback_param
=
param
->
fp_param
;
dmaengine_submit
((
struct
dma_async_tx_descriptor
*
)
desc
);
...
...
@@ -119,6 +126,7 @@ static inline int samsung_dmadev_flush(unsigned ch)
static
struct
samsung_dma_ops
dmadev_ops
=
{
.
request
=
samsung_dmadev_request
,
.
release
=
samsung_dmadev_release
,
.
config
=
samsung_dmadev_config
,
.
prepare
=
samsung_dmadev_prepare
,
.
trigger
=
samsung_dmadev_trigger
,
.
started
=
NULL
,
...
...
arch/arm/plat-samsung/include/plat/dma-ops.h
View file @
4d3c4636
...
...
@@ -16,7 +16,13 @@
#include <linux/dmaengine.h>
#include <mach/dma.h>
struct
samsung_dma_prep_info
{
struct
samsung_dma_req
{
enum
dma_transaction_type
cap
;
struct
property
*
dt_dmach_prop
;
struct
s3c2410_dma_client
*
client
;
};
struct
samsung_dma_prep
{
enum
dma_transaction_type
cap
;
enum
dma_transfer_direction
direction
;
dma_addr_t
buf
;
...
...
@@ -26,19 +32,17 @@ struct samsung_dma_prep_info {
void
*
fp_param
;
};
struct
samsung_dma_info
{
enum
dma_transaction_type
cap
;
struct
samsung_dma_config
{
enum
dma_transfer_direction
direction
;
enum
dma_slave_buswidth
width
;
dma_addr_t
fifo
;
struct
s3c2410_dma_client
*
client
;
struct
property
*
dt_dmach_prop
;
};
struct
samsung_dma_ops
{
unsigned
(
*
request
)(
enum
dma_ch
ch
,
struct
samsung_dma_info
*
info
);
int
(
*
release
)(
unsigned
ch
,
struct
s3c2410_dma_client
*
client
);
int
(
*
prepare
)(
unsigned
ch
,
struct
samsung_dma_prep_info
*
info
);
unsigned
(
*
request
)(
enum
dma_ch
ch
,
struct
samsung_dma_req
*
param
);
int
(
*
release
)(
unsigned
ch
,
void
*
param
);
int
(
*
config
)(
unsigned
ch
,
struct
samsung_dma_config
*
param
);
int
(
*
prepare
)(
unsigned
ch
,
struct
samsung_dma_prep
*
param
);
int
(
*
trigger
)(
unsigned
ch
);
int
(
*
started
)(
unsigned
ch
);
int
(
*
flush
)(
unsigned
ch
);
...
...
arch/arm/plat-samsung/s3c-dma-ops.c
View file @
4d3c4636
...
...
@@ -36,30 +36,26 @@ static void s3c_dma_cb(struct s3c2410_dma_chan *channel, void *param,
}
static
unsigned
s3c_dma_request
(
enum
dma_ch
dma_ch
,
struct
samsung_dma_info
*
info
)
struct
samsung_dma_req
*
param
)
{
struct
cb_data
*
data
;
if
(
s3c2410_dma_request
(
dma_ch
,
info
->
client
,
NULL
)
<
0
)
{
s3c2410_dma_free
(
dma_ch
,
info
->
client
);
if
(
s3c2410_dma_request
(
dma_ch
,
param
->
client
,
NULL
)
<
0
)
{
s3c2410_dma_free
(
dma_ch
,
param
->
client
);
return
0
;
}
if
(
param
->
cap
==
DMA_CYCLIC
)
s3c2410_dma_setflags
(
dma_ch
,
S3C2410_DMAF_CIRCULAR
);
data
=
kzalloc
(
sizeof
(
struct
cb_data
),
GFP_KERNEL
);
data
->
ch
=
dma_ch
;
list_add_tail
(
&
data
->
node
,
&
dma_list
);
s3c2410_dma_devconfig
(
dma_ch
,
info
->
direction
,
info
->
fifo
);
if
(
info
->
cap
==
DMA_CYCLIC
)
s3c2410_dma_setflags
(
dma_ch
,
S3C2410_DMAF_CIRCULAR
);
s3c2410_dma_config
(
dma_ch
,
info
->
width
);
return
(
unsigned
)
dma_ch
;
}
static
int
s3c_dma_release
(
unsigned
ch
,
struct
s3c2410_dma_client
*
client
)
static
int
s3c_dma_release
(
unsigned
ch
,
void
*
param
)
{
struct
cb_data
*
data
;
...
...
@@ -68,16 +64,24 @@ static int s3c_dma_release(unsigned ch, struct s3c2410_dma_client *client)
break
;
list_del
(
&
data
->
node
);
s3c2410_dma_free
(
ch
,
client
);
s3c2410_dma_free
(
ch
,
param
);
kfree
(
data
);
return
0
;
}
static
int
s3c_dma_prepare
(
unsigned
ch
,
struct
samsung_dma_prep_info
*
info
)
static
int
s3c_dma_config
(
unsigned
ch
,
struct
samsung_dma_config
*
param
)
{
s3c2410_dma_devconfig
(
ch
,
param
->
direction
,
param
->
fifo
);
s3c2410_dma_config
(
ch
,
param
->
width
);
return
0
;
}
static
int
s3c_dma_prepare
(
unsigned
ch
,
struct
samsung_dma_prep
*
param
)
{
struct
cb_data
*
data
;
int
len
=
(
info
->
cap
==
DMA_CYCLIC
)
?
info
->
period
:
info
->
len
;
int
len
=
(
param
->
cap
==
DMA_CYCLIC
)
?
param
->
period
:
param
->
len
;
list_for_each_entry
(
data
,
&
dma_list
,
node
)
if
(
data
->
ch
==
ch
)
...
...
@@ -85,11 +89,11 @@ static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep_info *info)
if
(
!
data
->
fp
)
{
s3c2410_dma_set_buffdone_fn
(
ch
,
s3c_dma_cb
);
data
->
fp
=
info
->
fp
;
data
->
fp_param
=
info
->
fp_param
;
data
->
fp
=
param
->
fp
;
data
->
fp_param
=
param
->
fp_param
;
}
s3c2410_dma_enqueue
(
ch
,
(
void
*
)
data
,
info
->
buf
,
len
);
s3c2410_dma_enqueue
(
ch
,
(
void
*
)
data
,
param
->
buf
,
len
);
return
0
;
}
...
...
@@ -117,6 +121,7 @@ static inline int s3c_dma_stop(unsigned ch)
static
struct
samsung_dma_ops
s3c_dma_ops
=
{
.
request
=
s3c_dma_request
,
.
release
=
s3c_dma_release
,
.
config
=
s3c_dma_config
,
.
prepare
=
s3c_dma_prepare
,
.
trigger
=
s3c_dma_trigger
,
.
started
=
s3c_dma_started
,
...
...
drivers/spi/spi-s3c64xx.c
View file @
4d3c4636
...
...
@@ -262,14 +262,24 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
unsigned
len
,
dma_addr_t
buf
)
{
struct
s3c64xx_spi_driver_data
*
sdd
;
struct
samsung_dma_prep_info
info
;
struct
samsung_dma_prep
info
;
struct
samsung_dma_config
config
;
if
(
dma
->
direction
==
DMA_DEV_TO_MEM
)
if
(
dma
->
direction
==
DMA_DEV_TO_MEM
)
{
sdd
=
container_of
((
void
*
)
dma
,
struct
s3c64xx_spi_driver_data
,
rx_dma
);
else
config
.
direction
=
sdd
->
rx_dma
.
direction
;
config
.
fifo
=
sdd
->
sfr_start
+
S3C64XX_SPI_RX_DATA
;
config
.
width
=
sdd
->
cur_bpw
/
8
;
sdd
->
ops
->
config
(
sdd
->
rx_dma
.
ch
,
&
config
);
}
else
{
sdd
=
container_of
((
void
*
)
dma
,
struct
s3c64xx_spi_driver_data
,
tx_dma
);
config
.
direction
=
sdd
->
tx_dma
.
direction
;
config
.
fifo
=
sdd
->
sfr_start
+
S3C64XX_SPI_TX_DATA
;
config
.
width
=
sdd
->
cur_bpw
/
8
;
sdd
->
ops
->
config
(
sdd
->
tx_dma
.
ch
,
&
config
);
}
info
.
cap
=
DMA_SLAVE
;
info
.
len
=
len
;
...
...
@@ -284,20 +294,15 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
static
int
acquire_dma
(
struct
s3c64xx_spi_driver_data
*
sdd
)
{
struct
samsung_dma_
info
info
;
struct
samsung_dma_
req
req
;
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
);
req
.
cap
=
DMA_SLAVE
;
req
.
client
=
&
s3c64xx_spi_dma_client
;
sdd
->
rx_dma
.
ch
=
sdd
->
ops
->
request
(
sdd
->
rx_dma
.
dmach
,
&
req
);
sdd
->
tx_dma
.
ch
=
sdd
->
ops
->
request
(
sdd
->
tx_dma
.
dmach
,
&
req
);
return
1
;
}
...
...
sound/soc/samsung/dma.c
View file @
4d3c4636
...
...
@@ -74,7 +74,7 @@ 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
;
struct
samsung_dma_prep
_info
dma_info
;
struct
samsung_dma_prep
dma_info
;
pr_debug
(
"Entered %s
\n
"
,
__func__
);
...
...
@@ -146,7 +146,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
unsigned
long
totbytes
=
params_buffer_bytes
(
params
);
struct
s3c_dma_params
*
dma
=
snd_soc_dai_get_dma_data
(
rtd
->
cpu_dai
,
substream
);
struct
samsung_dma_info
dma_info
;
struct
samsung_dma_req
req
;
struct
samsung_dma_config
config
;
pr_debug
(
"Entered %s
\n
"
,
__func__
);
...
...
@@ -166,16 +167,17 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
prtd
->
params
->
ops
=
samsung_dma_get_ops
();
dma_info
.
cap
=
(
samsung_dma_has_circular
()
?
req
.
cap
=
(
samsung_dma_has_circular
()
?
DMA_CYCLIC
:
DMA_SLAVE
);
dma_info
.
client
=
prtd
->
params
->
client
;
dma_info
.
direction
=
req
.
client
=
prtd
->
params
->
client
;
config
.
direction
=
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
?
DMA_MEM_TO_DEV
:
DMA_DEV_TO_MEM
);
dma_info
.
width
=
prtd
->
params
->
dma_size
;
dma_info
.
fifo
=
prtd
->
params
->
dma_addr
;
config
.
width
=
prtd
->
params
->
dma_size
;
config
.
fifo
=
prtd
->
params
->
dma_addr
;
prtd
->
params
->
ch
=
prtd
->
params
->
ops
->
request
(
prtd
->
params
->
channel
,
&
dma_info
);
prtd
->
params
->
channel
,
&
req
);
prtd
->
params
->
ops
->
config
(
prtd
->
params
->
ch
,
&
config
);
}
snd_pcm_set_runtime_buffer
(
substream
,
&
substream
->
dma_buffer
);
...
...
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