Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
89b7e78f
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
14
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
89b7e78f
编写于
8月 17, 2018
作者:
V
Vinod Koul
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/renesas' into for-linus
上级
35e0db66
218c2104
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
47 addition
and
66 deletion
+47
-66
Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt
Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt
+1
-0
drivers/dma/sh/rcar-dmac.c
drivers/dma/sh/rcar-dmac.c
+46
-66
未找到文件。
Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt
浏览文件 @
89b7e78f
...
...
@@ -29,6 +29,7 @@ Required Properties:
- "renesas,dmac-r8a77965" (R-Car M3-N)
- "renesas,dmac-r8a77970" (R-Car V3M)
- "renesas,dmac-r8a77980" (R-Car V3H)
- "renesas,dmac-r8a77990" (R-Car E3)
- "renesas,dmac-r8a77995" (R-Car D3)
- reg: base address and length of the registers block for the DMAC
...
...
drivers/dma/sh/rcar-dmac.c
浏览文件 @
89b7e78f
// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car Gen2 DMA Controller Driver
*
* Copyright (C) 2014 Renesas Electronics Inc.
*
* Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
*
* This is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
...
...
@@ -431,7 +428,8 @@ static void rcar_dmac_chan_start_xfer(struct rcar_dmac_chan *chan)
chcr
|=
RCAR_DMACHCR_DPM_DISABLED
|
RCAR_DMACHCR_IE
;
}
rcar_dmac_chan_write
(
chan
,
RCAR_DMACHCR
,
chcr
|
RCAR_DMACHCR_DE
);
rcar_dmac_chan_write
(
chan
,
RCAR_DMACHCR
,
chcr
|
RCAR_DMACHCR_DE
|
RCAR_DMACHCR_CAIE
);
}
static
int
rcar_dmac_init
(
struct
rcar_dmac
*
dmac
)
...
...
@@ -761,21 +759,15 @@ static void rcar_dmac_chcr_de_barrier(struct rcar_dmac_chan *chan)
dev_err
(
chan
->
chan
.
device
->
dev
,
"CHCR DE check error
\n
"
);
}
static
void
rcar_dmac_
sync_tcr
(
struct
rcar_dmac_chan
*
chan
)
static
void
rcar_dmac_
clear_chcr_de
(
struct
rcar_dmac_chan
*
chan
)
{
u32
chcr
=
rcar_dmac_chan_read
(
chan
,
RCAR_DMACHCR
);
if
(
!
(
chcr
&
RCAR_DMACHCR_DE
))
return
;
/* set DE=0 and flush remaining data */
rcar_dmac_chan_write
(
chan
,
RCAR_DMACHCR
,
(
chcr
&
~
RCAR_DMACHCR_DE
));
/* make sure all remaining data was flushed */
rcar_dmac_chcr_de_barrier
(
chan
);
/* back DE */
rcar_dmac_chan_write
(
chan
,
RCAR_DMACHCR
,
chcr
);
}
static
void
rcar_dmac_chan_halt
(
struct
rcar_dmac_chan
*
chan
)
...
...
@@ -783,7 +775,8 @@ static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
u32
chcr
=
rcar_dmac_chan_read
(
chan
,
RCAR_DMACHCR
);
chcr
&=
~
(
RCAR_DMACHCR_DSE
|
RCAR_DMACHCR_DSIE
|
RCAR_DMACHCR_IE
|
RCAR_DMACHCR_TE
|
RCAR_DMACHCR_DE
);
RCAR_DMACHCR_TE
|
RCAR_DMACHCR_DE
|
RCAR_DMACHCR_CAE
|
RCAR_DMACHCR_CAIE
);
rcar_dmac_chan_write
(
chan
,
RCAR_DMACHCR
,
chcr
);
rcar_dmac_chcr_de_barrier
(
chan
);
}
...
...
@@ -812,12 +805,7 @@ static void rcar_dmac_chan_reinit(struct rcar_dmac_chan *chan)
}
}
static
void
rcar_dmac_stop
(
struct
rcar_dmac
*
dmac
)
{
rcar_dmac_write
(
dmac
,
RCAR_DMAOR
,
0
);
}
static
void
rcar_dmac_abort
(
struct
rcar_dmac
*
dmac
)
static
void
rcar_dmac_stop_all_chan
(
struct
rcar_dmac
*
dmac
)
{
unsigned
int
i
;
...
...
@@ -826,14 +814,24 @@ static void rcar_dmac_abort(struct rcar_dmac *dmac)
struct
rcar_dmac_chan
*
chan
=
&
dmac
->
channels
[
i
];
/* Stop and reinitialize the channel. */
spin_lock
(
&
chan
->
lock
);
spin_lock
_irq
(
&
chan
->
lock
);
rcar_dmac_chan_halt
(
chan
);
spin_unlock
(
&
chan
->
lock
);
rcar_dmac_chan_reinit
(
chan
);
spin_unlock_irq
(
&
chan
->
lock
);
}
}
static
int
rcar_dmac_chan_pause
(
struct
dma_chan
*
chan
)
{
unsigned
long
flags
;
struct
rcar_dmac_chan
*
rchan
=
to_rcar_dmac_chan
(
chan
);
spin_lock_irqsave
(
&
rchan
->
lock
,
flags
);
rcar_dmac_clear_chcr_de
(
rchan
);
spin_unlock_irqrestore
(
&
rchan
->
lock
,
flags
);
return
0
;
}
/* -----------------------------------------------------------------------------
* Descriptors preparation
*/
...
...
@@ -1355,9 +1353,6 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
residue
+=
chunk
->
size
;
}
if
(
desc
->
direction
==
DMA_DEV_TO_MEM
)
rcar_dmac_sync_tcr
(
chan
);
/* Add the residue for the current chunk. */
residue
+=
rcar_dmac_chan_read
(
chan
,
RCAR_DMATCRB
)
<<
desc
->
xfer_shift
;
...
...
@@ -1522,11 +1517,26 @@ static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev)
u32
mask
=
RCAR_DMACHCR_DSE
|
RCAR_DMACHCR_TE
;
struct
rcar_dmac_chan
*
chan
=
dev
;
irqreturn_t
ret
=
IRQ_NONE
;
bool
reinit
=
false
;
u32
chcr
;
spin_lock
(
&
chan
->
lock
);
chcr
=
rcar_dmac_chan_read
(
chan
,
RCAR_DMACHCR
);
if
(
chcr
&
RCAR_DMACHCR_CAE
)
{
struct
rcar_dmac
*
dmac
=
to_rcar_dmac
(
chan
->
chan
.
device
);
/*
* We don't need to call rcar_dmac_chan_halt()
* because channel is already stopped in error case.
* We need to clear register and check DE bit as recovery.
*/
rcar_dmac_write
(
dmac
,
RCAR_DMACHCLR
,
1
<<
chan
->
index
);
rcar_dmac_chcr_de_barrier
(
chan
);
reinit
=
true
;
goto
spin_lock_end
;
}
if
(
chcr
&
RCAR_DMACHCR_TE
)
mask
|=
RCAR_DMACHCR_DE
;
rcar_dmac_chan_write
(
chan
,
RCAR_DMACHCR
,
chcr
&
~
mask
);
...
...
@@ -1539,8 +1549,16 @@ static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev)
if
(
chcr
&
RCAR_DMACHCR_TE
)
ret
|=
rcar_dmac_isr_transfer_end
(
chan
);
spin_lock_end:
spin_unlock
(
&
chan
->
lock
);
if
(
reinit
)
{
dev_err
(
chan
->
chan
.
device
->
dev
,
"Channel Address Error
\n
"
);
rcar_dmac_chan_reinit
(
chan
);
ret
=
IRQ_HANDLED
;
}
return
ret
;
}
...
...
@@ -1597,24 +1615,6 @@ static irqreturn_t rcar_dmac_isr_channel_thread(int irq, void *dev)
return
IRQ_HANDLED
;
}
static
irqreturn_t
rcar_dmac_isr_error
(
int
irq
,
void
*
data
)
{
struct
rcar_dmac
*
dmac
=
data
;
if
(
!
(
rcar_dmac_read
(
dmac
,
RCAR_DMAOR
)
&
RCAR_DMAOR_AE
))
return
IRQ_NONE
;
/*
* An unrecoverable error occurred on an unknown channel. Halt the DMAC,
* abort transfers on all channels, and reinitialize the DMAC.
*/
rcar_dmac_stop
(
dmac
);
rcar_dmac_abort
(
dmac
);
rcar_dmac_init
(
dmac
);
return
IRQ_HANDLED
;
}
/* -----------------------------------------------------------------------------
* OF xlate and channel filter
*/
...
...
@@ -1784,8 +1784,6 @@ static int rcar_dmac_probe(struct platform_device *pdev)
struct
rcar_dmac
*
dmac
;
struct
resource
*
mem
;
unsigned
int
i
;
char
*
irqname
;
int
irq
;
int
ret
;
dmac
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
dmac
),
GFP_KERNEL
);
...
...
@@ -1824,17 +1822,6 @@ static int rcar_dmac_probe(struct platform_device *pdev)
if
(
IS_ERR
(
dmac
->
iomem
))
return
PTR_ERR
(
dmac
->
iomem
);
irq
=
platform_get_irq_byname
(
pdev
,
"error"
);
if
(
irq
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"no error IRQ specified
\n
"
);
return
-
ENODEV
;
}
irqname
=
devm_kasprintf
(
dmac
->
dev
,
GFP_KERNEL
,
"%s:error"
,
dev_name
(
dmac
->
dev
));
if
(
!
irqname
)
return
-
ENOMEM
;
/* Enable runtime PM and initialize the device. */
pm_runtime_enable
(
&
pdev
->
dev
);
ret
=
pm_runtime_get_sync
(
&
pdev
->
dev
);
...
...
@@ -1871,6 +1858,7 @@ static int rcar_dmac_probe(struct platform_device *pdev)
engine
->
device_prep_slave_sg
=
rcar_dmac_prep_slave_sg
;
engine
->
device_prep_dma_cyclic
=
rcar_dmac_prep_dma_cyclic
;
engine
->
device_config
=
rcar_dmac_device_config
;
engine
->
device_pause
=
rcar_dmac_chan_pause
;
engine
->
device_terminate_all
=
rcar_dmac_chan_terminate_all
;
engine
->
device_tx_status
=
rcar_dmac_tx_status
;
engine
->
device_issue_pending
=
rcar_dmac_issue_pending
;
...
...
@@ -1885,14 +1873,6 @@ static int rcar_dmac_probe(struct platform_device *pdev)
goto
error
;
}
ret
=
devm_request_irq
(
&
pdev
->
dev
,
irq
,
rcar_dmac_isr_error
,
0
,
irqname
,
dmac
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to request IRQ %u (%d)
\n
"
,
irq
,
ret
);
return
ret
;
}
/* Register the DMAC as a DMA provider for DT. */
ret
=
of_dma_controller_register
(
pdev
->
dev
.
of_node
,
rcar_dmac_of_xlate
,
NULL
);
...
...
@@ -1932,7 +1912,7 @@ static void rcar_dmac_shutdown(struct platform_device *pdev)
{
struct
rcar_dmac
*
dmac
=
platform_get_drvdata
(
pdev
);
rcar_dmac_stop
(
dmac
);
rcar_dmac_stop
_all_chan
(
dmac
);
}
static
const
struct
of_device_id
rcar_dmac_of_ids
[]
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录