Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
2f8e7285
K
Kernel
项目概览
openeuler
/
Kernel
大约 1 年 前同步成功
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2f8e7285
编写于
1月 25, 2011
作者:
R
Russell King
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'mmci' into fixes
上级
250c7a61
8cb28155
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
21 addition
and
82 deletion
+21
-82
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.c
+20
-78
drivers/mmc/host/mmci.h
drivers/mmc/host/mmci.h
+1
-4
未找到文件。
drivers/mmc/host/mmci.c
浏览文件 @
2f8e7285
...
...
@@ -46,10 +46,6 @@ static unsigned int fmax = 515633;
* is asserted (likewise for RX)
* @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
* is asserted (likewise for RX)
* @broken_blockend: the MCI_DATABLOCKEND is broken on the hardware
* and will not work at all.
* @broken_blockend_dma: the MCI_DATABLOCKEND is broken on the hardware when
* using DMA.
* @sdio: variant supports SDIO
* @st_clkdiv: true if using a ST-specific clock divider algorithm
*/
...
...
@@ -59,8 +55,6 @@ struct variant_data {
unsigned
int
datalength_bits
;
unsigned
int
fifosize
;
unsigned
int
fifohalfsize
;
bool
broken_blockend
;
bool
broken_blockend_dma
;
bool
sdio
;
bool
st_clkdiv
;
};
...
...
@@ -76,7 +70,6 @@ static struct variant_data variant_u300 = {
.
fifohalfsize
=
8
*
4
,
.
clkreg_enable
=
1
<<
13
,
/* HWFCEN */
.
datalength_bits
=
16
,
.
broken_blockend_dma
=
true
,
.
sdio
=
true
,
};
...
...
@@ -86,7 +79,6 @@ static struct variant_data variant_ux500 = {
.
clkreg
=
MCI_CLK_ENABLE
,
.
clkreg_enable
=
1
<<
14
,
/* HWFCEN */
.
datalength_bits
=
24
,
.
broken_blockend
=
true
,
.
sdio
=
true
,
.
st_clkdiv
=
true
,
};
...
...
@@ -210,8 +202,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
host
->
data
=
data
;
host
->
size
=
data
->
blksz
*
data
->
blocks
;
host
->
data_xfered
=
0
;
host
->
blockend
=
false
;
host
->
dataend
=
false
;
mmci_init_sg
(
host
,
data
);
...
...
@@ -288,21 +278,26 @@ static void
mmci_data_irq
(
struct
mmci_host
*
host
,
struct
mmc_data
*
data
,
unsigned
int
status
)
{
struct
variant_data
*
variant
=
host
->
variant
;
/* First check for errors */
if
(
status
&
(
MCI_DATACRCFAIL
|
MCI_DATATIMEOUT
|
MCI_TXUNDERRUN
|
MCI_RXOVERRUN
))
{
u32
remain
,
success
;
/* Calculate how far we are into the transfer */
remain
=
readl
(
host
->
base
+
MMCIDATACNT
)
<<
2
;
success
=
data
->
blksz
*
data
->
blocks
-
remain
;
dev_dbg
(
mmc_dev
(
host
->
mmc
),
"MCI ERROR IRQ (status %08x)
\n
"
,
status
);
if
(
status
&
MCI_DATACRCFAIL
)
if
(
status
&
MCI_DATACRCFAIL
)
{
/* Last block was not successful */
host
->
data_xfered
=
((
success
/
data
->
blksz
)
-
1
*
data
->
blksz
);
data
->
error
=
-
EILSEQ
;
else
if
(
status
&
MCI_DATATIMEOUT
)
}
else
if
(
status
&
MCI_DATATIMEOUT
)
{
host
->
data_xfered
=
success
;
data
->
error
=
-
ETIMEDOUT
;
else
if
(
status
&
(
MCI_TXUNDERRUN
|
MCI_RXOVERRUN
))
}
else
if
(
status
&
(
MCI_TXUNDERRUN
|
MCI_RXOVERRUN
))
{
host
->
data_xfered
=
success
;
data
->
error
=
-
EIO
;
/* Force-complete the transaction */
host
->
blockend
=
true
;
host
->
dataend
=
true
;
}
/*
* We hit an error condition. Ensure that any data
...
...
@@ -321,61 +316,14 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
}
}
/*
* On ARM variants in PIO mode, MCI_DATABLOCKEND
* is always sent first, and we increase the
* transfered number of bytes for that IRQ. Then
* MCI_DATAEND follows and we conclude the transaction.
*
* On the Ux500 single-IRQ variant MCI_DATABLOCKEND
* doesn't seem to immediately clear from the status,
* so we can't use it keep count when only one irq is
* used because the irq will hit for other reasons, and
* then the flag is still up. So we use the MCI_DATAEND
* IRQ at the end of the entire transfer because
* MCI_DATABLOCKEND is broken.
*
* In the U300, the IRQs can arrive out-of-order,
* e.g. MCI_DATABLOCKEND sometimes arrives after MCI_DATAEND,
* so for this case we use the flags "blockend" and
* "dataend" to make sure both IRQs have arrived before
* concluding the transaction. (This does not apply
* to the Ux500 which doesn't fire MCI_DATABLOCKEND
* at all.) In DMA mode it suffers from the same problem
* as the Ux500.
*/
if
(
status
&
MCI_DATABLOCKEND
)
{
/*
* Just being a little over-cautious, we do not
* use this progressive update if the hardware blockend
* flag is unreliable: since it can stay high between
* IRQs it will corrupt the transfer counter.
*/
if
(
!
variant
->
broken_blockend
)
host
->
data_xfered
+=
data
->
blksz
;
host
->
blockend
=
true
;
}
if
(
status
&
MCI_DATAEND
)
host
->
dataend
=
true
;
if
(
status
&
MCI_DATABLOCKEND
)
dev_err
(
mmc_dev
(
host
->
mmc
),
"stray MCI_DATABLOCKEND interrupt
\n
"
);
/*
* On variants with broken blockend we shall only wait for dataend,
* on others we must sync with the blockend signal since they can
* appear out-of-order.
*/
if
(
host
->
dataend
&&
(
host
->
blockend
||
variant
->
broken_blockend
))
{
if
(
status
&
MCI_DATAEND
)
{
mmci_stop_data
(
host
);
/* Reset these flags */
host
->
blockend
=
false
;
host
->
dataend
=
false
;
/*
* Variants with broken blockend flags need to handle the
* end of the entire transfer here.
*/
if
(
variant
->
broken_blockend
&&
!
data
->
error
)
if
(
!
data
->
error
)
/* The error clause is handled above, success! */
host
->
data_xfered
+=
data
->
blksz
*
data
->
blocks
;
if
(
!
data
->
stop
)
{
...
...
@@ -770,7 +718,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
struct
variant_data
*
variant
=
id
->
data
;
struct
mmci_host
*
host
;
struct
mmc_host
*
mmc
;
unsigned
int
mask
;
int
ret
;
/* must have platform data */
...
...
@@ -951,12 +898,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
goto
irq0_free
;
}
mask
=
MCI_IRQENABLE
;
/* Don't use the datablockend flag if it's broken */
if
(
variant
->
broken_blockend
)
mask
&=
~
MCI_DATABLOCKEND
;
writel
(
mask
,
host
->
base
+
MMCIMASK0
);
writel
(
MCI_IRQENABLE
,
host
->
base
+
MMCIMASK0
);
amba_set_drvdata
(
dev
,
mmc
);
...
...
drivers/mmc/host/mmci.h
浏览文件 @
2f8e7285
...
...
@@ -137,7 +137,7 @@
#define MCI_IRQENABLE \
(MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK
|MCI_DATABLOCKENDMASK
)
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK)
/* These interrupts are directed to IRQ1 when two IRQ lines are available */
#define MCI_IRQ1MASK \
...
...
@@ -177,9 +177,6 @@ struct mmci_host {
struct
timer_list
timer
;
unsigned
int
oldstat
;
bool
blockend
;
bool
dataend
;
/* pio stuff */
struct
sg_mapping_iter
sg_miter
;
unsigned
int
size
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录