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
2a2d0f63
Commit
2a2d0f63
authored
Jan 06, 2016
by
Vinod Koul
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/tegra' into for-linus
parents
c8b9dd2b
05e866b4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
40 additions
and
33 deletions
+40
-33
drivers/dma/tegra20-apb-dma.c
drivers/dma/tegra20-apb-dma.c
+40
-33
No files found.
drivers/dma/tegra20-apb-dma.c
View file @
2a2d0f63
...
@@ -296,7 +296,7 @@ static struct tegra_dma_desc *tegra_dma_desc_get(
...
@@ -296,7 +296,7 @@ static struct tegra_dma_desc *tegra_dma_desc_get(
spin_unlock_irqrestore
(
&
tdc
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
tdc
->
lock
,
flags
);
/* Allocate DMA desc */
/* Allocate DMA desc */
dma_desc
=
kzalloc
(
sizeof
(
*
dma_desc
),
GFP_
ATOMIC
);
dma_desc
=
kzalloc
(
sizeof
(
*
dma_desc
),
GFP_
NOWAIT
);
if
(
!
dma_desc
)
{
if
(
!
dma_desc
)
{
dev_err
(
tdc2dev
(
tdc
),
"dma_desc alloc failed
\n
"
);
dev_err
(
tdc2dev
(
tdc
),
"dma_desc alloc failed
\n
"
);
return
NULL
;
return
NULL
;
...
@@ -336,7 +336,7 @@ static struct tegra_dma_sg_req *tegra_dma_sg_req_get(
...
@@ -336,7 +336,7 @@ static struct tegra_dma_sg_req *tegra_dma_sg_req_get(
}
}
spin_unlock_irqrestore
(
&
tdc
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
tdc
->
lock
,
flags
);
sg_req
=
kzalloc
(
sizeof
(
struct
tegra_dma_sg_req
),
GFP_
ATOMIC
);
sg_req
=
kzalloc
(
sizeof
(
struct
tegra_dma_sg_req
),
GFP_
NOWAIT
);
if
(
!
sg_req
)
if
(
!
sg_req
)
dev_err
(
tdc2dev
(
tdc
),
"sg_req alloc failed
\n
"
);
dev_err
(
tdc2dev
(
tdc
),
"sg_req alloc failed
\n
"
);
return
sg_req
;
return
sg_req
;
...
@@ -1186,10 +1186,12 @@ static int tegra_dma_alloc_chan_resources(struct dma_chan *dc)
...
@@ -1186,10 +1186,12 @@ static int tegra_dma_alloc_chan_resources(struct dma_chan *dc)
dma_cookie_init
(
&
tdc
->
dma_chan
);
dma_cookie_init
(
&
tdc
->
dma_chan
);
tdc
->
config_init
=
false
;
tdc
->
config_init
=
false
;
ret
=
clk_prepare_enable
(
tdma
->
dma_clk
);
ret
=
pm_runtime_get_sync
(
tdma
->
dev
);
if
(
ret
<
0
)
if
(
ret
<
0
)
dev_err
(
tdc2dev
(
tdc
),
"clk_prepare_enable failed: %d
\n
"
,
ret
);
return
ret
;
return
ret
;
return
0
;
}
}
static
void
tegra_dma_free_chan_resources
(
struct
dma_chan
*
dc
)
static
void
tegra_dma_free_chan_resources
(
struct
dma_chan
*
dc
)
...
@@ -1232,7 +1234,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
...
@@ -1232,7 +1234,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
list_del
(
&
sg_req
->
node
);
list_del
(
&
sg_req
->
node
);
kfree
(
sg_req
);
kfree
(
sg_req
);
}
}
clk_disable_unprepare
(
tdma
->
dma_clk
);
pm_runtime_put
(
tdma
->
dev
);
tdc
->
slave_id
=
0
;
tdc
->
slave_id
=
0
;
}
}
...
@@ -1356,20 +1358,14 @@ static int tegra_dma_probe(struct platform_device *pdev)
...
@@ -1356,20 +1358,14 @@ static int tegra_dma_probe(struct platform_device *pdev)
spin_lock_init
(
&
tdma
->
global_lock
);
spin_lock_init
(
&
tdma
->
global_lock
);
pm_runtime_enable
(
&
pdev
->
dev
);
pm_runtime_enable
(
&
pdev
->
dev
);
if
(
!
pm_runtime_enabled
(
&
pdev
->
dev
))
{
if
(
!
pm_runtime_enabled
(
&
pdev
->
dev
))
ret
=
tegra_dma_runtime_resume
(
&
pdev
->
dev
);
ret
=
tegra_dma_runtime_resume
(
&
pdev
->
dev
);
if
(
ret
)
{
else
dev_err
(
&
pdev
->
dev
,
"dma_runtime_resume failed %d
\n
"
,
ret
=
pm_runtime_get_sync
(
&
pdev
->
dev
);
ret
);
goto
err_pm_disable
;
}
}
/* Enable clock before accessing registers */
ret
=
clk_prepare_enable
(
tdma
->
dma_clk
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"clk_prepare_enable failed: %d
\n
"
,
ret
);
pm_runtime_disable
(
&
pdev
->
dev
);
goto
err_pm_disable
;
return
ret
;
}
}
/* Reset DMA controller */
/* Reset DMA controller */
...
@@ -1382,7 +1378,7 @@ static int tegra_dma_probe(struct platform_device *pdev)
...
@@ -1382,7 +1378,7 @@ static int tegra_dma_probe(struct platform_device *pdev)
tdma_write
(
tdma
,
TEGRA_APBDMA_CONTROL
,
0
);
tdma_write
(
tdma
,
TEGRA_APBDMA_CONTROL
,
0
);
tdma_write
(
tdma
,
TEGRA_APBDMA_IRQ_MASK_SET
,
0xFFFFFFFFul
);
tdma_write
(
tdma
,
TEGRA_APBDMA_IRQ_MASK_SET
,
0xFFFFFFFFul
);
clk_disable_unprepare
(
tdma
->
dma_clk
);
pm_runtime_put
(
&
pdev
->
dev
);
INIT_LIST_HEAD
(
&
tdma
->
dma_dev
.
channels
);
INIT_LIST_HEAD
(
&
tdma
->
dma_dev
.
channels
);
for
(
i
=
0
;
i
<
cdata
->
nr_channels
;
i
++
)
{
for
(
i
=
0
;
i
<
cdata
->
nr_channels
;
i
++
)
{
...
@@ -1400,8 +1396,7 @@ static int tegra_dma_probe(struct platform_device *pdev)
...
@@ -1400,8 +1396,7 @@ static int tegra_dma_probe(struct platform_device *pdev)
}
}
tdc
->
irq
=
res
->
start
;
tdc
->
irq
=
res
->
start
;
snprintf
(
tdc
->
name
,
sizeof
(
tdc
->
name
),
"apbdma.%d"
,
i
);
snprintf
(
tdc
->
name
,
sizeof
(
tdc
->
name
),
"apbdma.%d"
,
i
);
ret
=
devm_request_irq
(
&
pdev
->
dev
,
tdc
->
irq
,
ret
=
request_irq
(
tdc
->
irq
,
tegra_dma_isr
,
0
,
tdc
->
name
,
tdc
);
tegra_dma_isr
,
0
,
tdc
->
name
,
tdc
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
dev_err
(
&
pdev
->
dev
,
"request_irq failed with err %d channel %d
\n
"
,
"request_irq failed with err %d channel %d
\n
"
,
...
@@ -1482,10 +1477,11 @@ static int tegra_dma_probe(struct platform_device *pdev)
...
@@ -1482,10 +1477,11 @@ static int tegra_dma_probe(struct platform_device *pdev)
err_irq:
err_irq:
while
(
--
i
>=
0
)
{
while
(
--
i
>=
0
)
{
struct
tegra_dma_channel
*
tdc
=
&
tdma
->
channels
[
i
];
struct
tegra_dma_channel
*
tdc
=
&
tdma
->
channels
[
i
];
free_irq
(
tdc
->
irq
,
tdc
);
tasklet_kill
(
&
tdc
->
tasklet
);
tasklet_kill
(
&
tdc
->
tasklet
);
}
}
err_pm_disable:
pm_runtime_disable
(
&
pdev
->
dev
);
pm_runtime_disable
(
&
pdev
->
dev
);
if
(
!
pm_runtime_status_suspended
(
&
pdev
->
dev
))
if
(
!
pm_runtime_status_suspended
(
&
pdev
->
dev
))
tegra_dma_runtime_suspend
(
&
pdev
->
dev
);
tegra_dma_runtime_suspend
(
&
pdev
->
dev
);
...
@@ -1502,6 +1498,7 @@ static int tegra_dma_remove(struct platform_device *pdev)
...
@@ -1502,6 +1498,7 @@ static int tegra_dma_remove(struct platform_device *pdev)
for
(
i
=
0
;
i
<
tdma
->
chip_data
->
nr_channels
;
++
i
)
{
for
(
i
=
0
;
i
<
tdma
->
chip_data
->
nr_channels
;
++
i
)
{
tdc
=
&
tdma
->
channels
[
i
];
tdc
=
&
tdma
->
channels
[
i
];
free_irq
(
tdc
->
irq
,
tdc
);
tasklet_kill
(
&
tdc
->
tasklet
);
tasklet_kill
(
&
tdc
->
tasklet
);
}
}
...
@@ -1514,8 +1511,7 @@ static int tegra_dma_remove(struct platform_device *pdev)
...
@@ -1514,8 +1511,7 @@ static int tegra_dma_remove(struct platform_device *pdev)
static
int
tegra_dma_runtime_suspend
(
struct
device
*
dev
)
static
int
tegra_dma_runtime_suspend
(
struct
device
*
dev
)
{
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
tegra_dma
*
tdma
=
dev_get_drvdata
(
dev
);
struct
tegra_dma
*
tdma
=
platform_get_drvdata
(
pdev
);
clk_disable_unprepare
(
tdma
->
dma_clk
);
clk_disable_unprepare
(
tdma
->
dma_clk
);
return
0
;
return
0
;
...
@@ -1523,8 +1519,7 @@ static int tegra_dma_runtime_suspend(struct device *dev)
...
@@ -1523,8 +1519,7 @@ static int tegra_dma_runtime_suspend(struct device *dev)
static
int
tegra_dma_runtime_resume
(
struct
device
*
dev
)
static
int
tegra_dma_runtime_resume
(
struct
device
*
dev
)
{
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
tegra_dma
*
tdma
=
dev_get_drvdata
(
dev
);
struct
tegra_dma
*
tdma
=
platform_get_drvdata
(
pdev
);
int
ret
;
int
ret
;
ret
=
clk_prepare_enable
(
tdma
->
dma_clk
);
ret
=
clk_prepare_enable
(
tdma
->
dma_clk
);
...
@@ -1543,7 +1538,7 @@ static int tegra_dma_pm_suspend(struct device *dev)
...
@@ -1543,7 +1538,7 @@ static int tegra_dma_pm_suspend(struct device *dev)
int
ret
;
int
ret
;
/* Enable clock before accessing register */
/* Enable clock before accessing register */
ret
=
tegra_dma_runtime_resume
(
dev
);
ret
=
pm_runtime_get_sync
(
dev
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -1552,15 +1547,22 @@ static int tegra_dma_pm_suspend(struct device *dev)
...
@@ -1552,15 +1547,22 @@ static int tegra_dma_pm_suspend(struct device *dev)
struct
tegra_dma_channel
*
tdc
=
&
tdma
->
channels
[
i
];
struct
tegra_dma_channel
*
tdc
=
&
tdma
->
channels
[
i
];
struct
tegra_dma_channel_regs
*
ch_reg
=
&
tdc
->
channel_reg
;
struct
tegra_dma_channel_regs
*
ch_reg
=
&
tdc
->
channel_reg
;
/* Only save the state of DMA channels that are in use */
if
(
!
tdc
->
config_init
)
continue
;
ch_reg
->
csr
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_CSR
);
ch_reg
->
csr
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_CSR
);
ch_reg
->
ahb_ptr
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_AHBPTR
);
ch_reg
->
ahb_ptr
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_AHBPTR
);
ch_reg
->
apb_ptr
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_APBPTR
);
ch_reg
->
apb_ptr
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_APBPTR
);
ch_reg
->
ahb_seq
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_AHBSEQ
);
ch_reg
->
ahb_seq
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_AHBSEQ
);
ch_reg
->
apb_seq
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_APBSEQ
);
ch_reg
->
apb_seq
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_APBSEQ
);
if
(
tdma
->
chip_data
->
support_separate_wcount_reg
)
ch_reg
->
wcount
=
tdc_read
(
tdc
,
TEGRA_APBDMA_CHAN_WCOUNT
);
}
}
/* Disable clock */
/* Disable clock */
tegra_dma_runtime_suspend
(
dev
);
pm_runtime_put
(
dev
);
return
0
;
return
0
;
}
}
...
@@ -1571,7 +1573,7 @@ static int tegra_dma_pm_resume(struct device *dev)
...
@@ -1571,7 +1573,7 @@ static int tegra_dma_pm_resume(struct device *dev)
int
ret
;
int
ret
;
/* Enable clock before accessing register */
/* Enable clock before accessing register */
ret
=
tegra_dma_runtime_resume
(
dev
);
ret
=
pm_runtime_get_sync
(
dev
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -1583,6 +1585,13 @@ static int tegra_dma_pm_resume(struct device *dev)
...
@@ -1583,6 +1585,13 @@ static int tegra_dma_pm_resume(struct device *dev)
struct
tegra_dma_channel
*
tdc
=
&
tdma
->
channels
[
i
];
struct
tegra_dma_channel
*
tdc
=
&
tdma
->
channels
[
i
];
struct
tegra_dma_channel_regs
*
ch_reg
=
&
tdc
->
channel_reg
;
struct
tegra_dma_channel_regs
*
ch_reg
=
&
tdc
->
channel_reg
;
/* Only restore the state of DMA channels that are in use */
if
(
!
tdc
->
config_init
)
continue
;
if
(
tdma
->
chip_data
->
support_separate_wcount_reg
)
tdc_write
(
tdc
,
TEGRA_APBDMA_CHAN_WCOUNT
,
ch_reg
->
wcount
);
tdc_write
(
tdc
,
TEGRA_APBDMA_CHAN_APBSEQ
,
ch_reg
->
apb_seq
);
tdc_write
(
tdc
,
TEGRA_APBDMA_CHAN_APBSEQ
,
ch_reg
->
apb_seq
);
tdc_write
(
tdc
,
TEGRA_APBDMA_CHAN_APBPTR
,
ch_reg
->
apb_ptr
);
tdc_write
(
tdc
,
TEGRA_APBDMA_CHAN_APBPTR
,
ch_reg
->
apb_ptr
);
tdc_write
(
tdc
,
TEGRA_APBDMA_CHAN_AHBSEQ
,
ch_reg
->
ahb_seq
);
tdc_write
(
tdc
,
TEGRA_APBDMA_CHAN_AHBSEQ
,
ch_reg
->
ahb_seq
);
...
@@ -1592,16 +1601,14 @@ static int tegra_dma_pm_resume(struct device *dev)
...
@@ -1592,16 +1601,14 @@ static int tegra_dma_pm_resume(struct device *dev)
}
}
/* Disable clock */
/* Disable clock */
tegra_dma_runtime_suspend
(
dev
);
pm_runtime_put
(
dev
);
return
0
;
return
0
;
}
}
#endif
#endif
static
const
struct
dev_pm_ops
tegra_dma_dev_pm_ops
=
{
static
const
struct
dev_pm_ops
tegra_dma_dev_pm_ops
=
{
#ifdef CONFIG_PM
SET_RUNTIME_PM_OPS
(
tegra_dma_runtime_suspend
,
tegra_dma_runtime_resume
,
.
runtime_suspend
=
tegra_dma_runtime_suspend
,
NULL
)
.
runtime_resume
=
tegra_dma_runtime_resume
,
#endif
SET_SYSTEM_SLEEP_PM_OPS
(
tegra_dma_pm_suspend
,
tegra_dma_pm_resume
)
SET_SYSTEM_SLEEP_PM_OPS
(
tegra_dma_pm_suspend
,
tegra_dma_pm_resume
)
};
};
...
...
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