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
nexedi
linux
Commits
9523366f
Commit
9523366f
authored
Oct 03, 2016
by
Vinod Koul
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/cppi' into for-linus
parents
99823374
f2f6f828
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
116 additions
and
24 deletions
+116
-24
drivers/dma/cppi41.c
drivers/dma/cppi41.c
+116
-24
No files found.
drivers/dma/cppi41.c
View file @
9523366f
...
...
@@ -108,6 +108,8 @@ struct cppi41_channel {
unsigned
td_queued
:
1
;
unsigned
td_seen
:
1
;
unsigned
td_desc_seen
:
1
;
struct
list_head
node
;
/* Node for pending list */
};
struct
cppi41_desc
{
...
...
@@ -146,6 +148,9 @@ struct cppi41_dd {
const
struct
chan_queues
*
queues_tx
;
struct
chan_queues
td_queue
;
struct
list_head
pending
;
/* Pending queued transfers */
spinlock_t
lock
;
/* Lock for pending list */
/* context for suspend/resume */
unsigned
int
dma_tdfdq
;
};
...
...
@@ -332,6 +337,10 @@ static irqreturn_t cppi41_irq(int irq, void *data)
c
->
residue
=
pd_trans_len
(
c
->
desc
->
pd6
)
-
len
;
dma_cookie_complete
(
&
c
->
txd
);
c
->
txd
.
callback
(
c
->
txd
.
callback_param
);
/* Paired with cppi41_dma_issue_pending */
pm_runtime_mark_last_busy
(
cdd
->
ddev
.
dev
);
pm_runtime_put_autosuspend
(
cdd
->
ddev
.
dev
);
}
}
return
IRQ_HANDLED
;
...
...
@@ -349,6 +358,12 @@ static dma_cookie_t cppi41_tx_submit(struct dma_async_tx_descriptor *tx)
static
int
cppi41_dma_alloc_chan_resources
(
struct
dma_chan
*
chan
)
{
struct
cppi41_channel
*
c
=
to_cpp41_chan
(
chan
);
struct
cppi41_dd
*
cdd
=
c
->
cdd
;
int
error
;
error
=
pm_runtime_get_sync
(
cdd
->
ddev
.
dev
);
if
(
error
<
0
)
return
error
;
dma_cookie_init
(
chan
);
dma_async_tx_descriptor_init
(
&
c
->
txd
,
chan
);
...
...
@@ -357,11 +372,26 @@ static int cppi41_dma_alloc_chan_resources(struct dma_chan *chan)
if
(
!
c
->
is_tx
)
cppi_writel
(
c
->
q_num
,
c
->
gcr_reg
+
RXHPCRA0
);
pm_runtime_mark_last_busy
(
cdd
->
ddev
.
dev
);
pm_runtime_put_autosuspend
(
cdd
->
ddev
.
dev
);
return
0
;
}
static
void
cppi41_dma_free_chan_resources
(
struct
dma_chan
*
chan
)
{
struct
cppi41_channel
*
c
=
to_cpp41_chan
(
chan
);
struct
cppi41_dd
*
cdd
=
c
->
cdd
;
int
error
;
error
=
pm_runtime_get_sync
(
cdd
->
ddev
.
dev
);
if
(
error
<
0
)
return
;
WARN_ON
(
!
list_empty
(
&
cdd
->
pending
));
pm_runtime_mark_last_busy
(
cdd
->
ddev
.
dev
);
pm_runtime_put_autosuspend
(
cdd
->
ddev
.
dev
);
}
static
enum
dma_status
cppi41_dma_tx_status
(
struct
dma_chan
*
chan
,
...
...
@@ -386,21 +416,6 @@ static void push_desc_queue(struct cppi41_channel *c)
u32
desc_phys
;
u32
reg
;
desc_phys
=
lower_32_bits
(
c
->
desc_phys
);
desc_num
=
(
desc_phys
-
cdd
->
descs_phys
)
/
sizeof
(
struct
cppi41_desc
);
WARN_ON
(
cdd
->
chan_busy
[
desc_num
]);
cdd
->
chan_busy
[
desc_num
]
=
c
;
reg
=
(
sizeof
(
struct
cppi41_desc
)
-
24
)
/
4
;
reg
|=
desc_phys
;
cppi_writel
(
reg
,
cdd
->
qmgr_mem
+
QMGR_QUEUE_D
(
c
->
q_num
));
}
static
void
cppi41_dma_issue_pending
(
struct
dma_chan
*
chan
)
{
struct
cppi41_channel
*
c
=
to_cpp41_chan
(
chan
);
u32
reg
;
c
->
residue
=
0
;
reg
=
GCR_CHAN_ENABLE
;
...
...
@@ -418,7 +433,46 @@ static void cppi41_dma_issue_pending(struct dma_chan *chan)
* before starting the dma engine.
*/
__iowmb
();
push_desc_queue
(
c
);
desc_phys
=
lower_32_bits
(
c
->
desc_phys
);
desc_num
=
(
desc_phys
-
cdd
->
descs_phys
)
/
sizeof
(
struct
cppi41_desc
);
WARN_ON
(
cdd
->
chan_busy
[
desc_num
]);
cdd
->
chan_busy
[
desc_num
]
=
c
;
reg
=
(
sizeof
(
struct
cppi41_desc
)
-
24
)
/
4
;
reg
|=
desc_phys
;
cppi_writel
(
reg
,
cdd
->
qmgr_mem
+
QMGR_QUEUE_D
(
c
->
q_num
));
}
static
void
pending_desc
(
struct
cppi41_channel
*
c
)
{
struct
cppi41_dd
*
cdd
=
c
->
cdd
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
cdd
->
lock
,
flags
);
list_add_tail
(
&
c
->
node
,
&
cdd
->
pending
);
spin_unlock_irqrestore
(
&
cdd
->
lock
,
flags
);
}
static
void
cppi41_dma_issue_pending
(
struct
dma_chan
*
chan
)
{
struct
cppi41_channel
*
c
=
to_cpp41_chan
(
chan
);
struct
cppi41_dd
*
cdd
=
c
->
cdd
;
int
error
;
/* PM runtime paired with dmaengine_desc_get_callback_invoke */
error
=
pm_runtime_get
(
cdd
->
ddev
.
dev
);
if
((
error
!=
-
EINPROGRESS
)
&&
error
<
0
)
{
dev_err
(
cdd
->
ddev
.
dev
,
"Failed to pm_runtime_get: %i
\n
"
,
error
);
return
;
}
if
(
likely
(
pm_runtime_active
(
cdd
->
ddev
.
dev
)))
push_desc_queue
(
c
);
else
pending_desc
(
c
);
}
static
u32
get_host_pd0
(
u32
length
)
...
...
@@ -940,12 +994,18 @@ static int cppi41_dma_probe(struct platform_device *pdev)
cdd
->
ctrl_mem
=
of_iomap
(
dev
->
of_node
,
1
);
cdd
->
sched_mem
=
of_iomap
(
dev
->
of_node
,
2
);
cdd
->
qmgr_mem
=
of_iomap
(
dev
->
of_node
,
3
);
spin_lock_init
(
&
cdd
->
lock
);
INIT_LIST_HEAD
(
&
cdd
->
pending
);
platform_set_drvdata
(
pdev
,
cdd
);
if
(
!
cdd
->
usbss_mem
||
!
cdd
->
ctrl_mem
||
!
cdd
->
sched_mem
||
!
cdd
->
qmgr_mem
)
return
-
ENXIO
;
pm_runtime_enable
(
dev
);
pm_runtime_set_autosuspend_delay
(
dev
,
100
);
pm_runtime_use_autosuspend
(
dev
);
ret
=
pm_runtime_get_sync
(
dev
);
if
(
ret
<
0
)
goto
err_get_sync
;
...
...
@@ -985,7 +1045,9 @@ static int cppi41_dma_probe(struct platform_device *pdev)
if
(
ret
)
goto
err_of
;
platform_set_drvdata
(
pdev
,
cdd
);
pm_runtime_mark_last_busy
(
dev
);
pm_runtime_put_autosuspend
(
dev
);
return
0
;
err_of:
dma_async_device_unregister
(
&
cdd
->
ddev
);
...
...
@@ -996,7 +1058,8 @@ static int cppi41_dma_probe(struct platform_device *pdev)
err_chans:
deinit_cppi41
(
dev
,
cdd
);
err_init_cppi:
pm_runtime_put
(
dev
);
pm_runtime_dont_use_autosuspend
(
dev
);
pm_runtime_put_sync
(
dev
);
err_get_sync:
pm_runtime_disable
(
dev
);
iounmap
(
cdd
->
usbss_mem
);
...
...
@@ -1021,13 +1084,13 @@ static int cppi41_dma_remove(struct platform_device *pdev)
iounmap
(
cdd
->
ctrl_mem
);
iounmap
(
cdd
->
sched_mem
);
iounmap
(
cdd
->
qmgr_mem
);
pm_runtime_put
(
&
pdev
->
dev
);
pm_runtime_dont_use_autosuspend
(
&
pdev
->
dev
);
pm_runtime_put_sync
(
&
pdev
->
dev
);
pm_runtime_disable
(
&
pdev
->
dev
);
return
0
;
}
#ifdef CONFIG_PM_SLEEP
static
int
cppi41_suspend
(
struct
device
*
dev
)
static
int
__maybe_unused
cppi41_suspend
(
struct
device
*
dev
)
{
struct
cppi41_dd
*
cdd
=
dev_get_drvdata
(
dev
);
...
...
@@ -1038,7 +1101,7 @@ static int cppi41_suspend(struct device *dev)
return
0
;
}
static
int
cppi41_resume
(
struct
device
*
dev
)
static
int
__maybe_unused
cppi41_resume
(
struct
device
*
dev
)
{
struct
cppi41_dd
*
cdd
=
dev_get_drvdata
(
dev
);
struct
cppi41_channel
*
c
;
...
...
@@ -1062,9 +1125,38 @@ static int cppi41_resume(struct device *dev)
return
0
;
}
#endif
static
SIMPLE_DEV_PM_OPS
(
cppi41_pm_ops
,
cppi41_suspend
,
cppi41_resume
);
static
int
__maybe_unused
cppi41_runtime_suspend
(
struct
device
*
dev
)
{
struct
cppi41_dd
*
cdd
=
dev_get_drvdata
(
dev
);
WARN_ON
(
!
list_empty
(
&
cdd
->
pending
));
return
0
;
}
static
int
__maybe_unused
cppi41_runtime_resume
(
struct
device
*
dev
)
{
struct
cppi41_dd
*
cdd
=
dev_get_drvdata
(
dev
);
struct
cppi41_channel
*
c
,
*
_c
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
cdd
->
lock
,
flags
);
list_for_each_entry_safe
(
c
,
_c
,
&
cdd
->
pending
,
node
)
{
push_desc_queue
(
c
);
list_del
(
&
c
->
node
);
}
spin_unlock_irqrestore
(
&
cdd
->
lock
,
flags
);
return
0
;
}
static
const
struct
dev_pm_ops
cppi41_pm_ops
=
{
SET_LATE_SYSTEM_SLEEP_PM_OPS
(
cppi41_suspend
,
cppi41_resume
)
SET_RUNTIME_PM_OPS
(
cppi41_runtime_suspend
,
cppi41_runtime_resume
,
NULL
)
};
static
struct
platform_driver
cpp41_dma_driver
=
{
.
probe
=
cppi41_dma_probe
,
...
...
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