Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
9cd0ef2b
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 3 年多
通知
13
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
9cd0ef2b
编写于
1月 20, 2015
作者:
U
Ulf Hansson
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'tmio' into next
上级
87a50745
de122cb1
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
166 addition
and
151 deletion
+166
-151
drivers/mmc/host/sh_mobile_sdhi.c
drivers/mmc/host/sh_mobile_sdhi.c
+65
-52
drivers/mmc/host/tmio_mmc.c
drivers/mmc/host/tmio_mmc.c
+11
-4
drivers/mmc/host/tmio_mmc.h
drivers/mmc/host/tmio_mmc.h
+32
-11
drivers/mmc/host/tmio_mmc_dma.c
drivers/mmc/host/tmio_mmc_dma.c
+20
-18
drivers/mmc/host/tmio_mmc_pio.c
drivers/mmc/host/tmio_mmc_pio.c
+36
-25
include/linux/mfd/tmio.h
include/linux/mfd/tmio.h
+2
-26
include/linux/mmc/sh_mobile_sdhi.h
include/linux/mmc/sh_mobile_sdhi.h
+0
-15
未找到文件。
drivers/mmc/host/sh_mobile_sdhi.c
浏览文件 @
9cd0ef2b
...
...
@@ -35,10 +35,13 @@
#define EXT_ACC 0xe4
#define host_to_priv(host) container_of((host)->pdata, struct sh_mobile_sdhi, mmc_data)
struct
sh_mobile_sdhi_of_data
{
unsigned
long
tmio_flags
;
unsigned
long
capabilities
;
unsigned
long
capabilities2
;
enum
dma_slave_buswidth
dma_buswidth
;
dma_addr_t
dma_rx_offset
;
};
...
...
@@ -58,6 +61,7 @@ static const struct sh_mobile_sdhi_of_data of_rcar_gen2_compatible = {
.
tmio_flags
=
TMIO_MMC_HAS_IDLE_WAIT
|
TMIO_MMC_WRPROTECT_DISABLE
|
TMIO_MMC_CLK_ACTUAL
,
.
capabilities
=
MMC_CAP_SD_HIGHSPEED
|
MMC_CAP_SDIO_IRQ
,
.
dma_buswidth
=
DMA_SLAVE_BUSWIDTH_4_BYTES
,
.
dma_rx_offset
=
0x2000
,
};
...
...
@@ -84,16 +88,43 @@ struct sh_mobile_sdhi {
struct
tmio_mmc_dma
dma_priv
;
};
static
void
sh_mobile_sdhi_sdbuf_width
(
struct
tmio_mmc_host
*
host
,
int
width
)
{
u32
val
;
/*
* see also
* sh_mobile_sdhi_of_data :: dma_buswidth
*/
switch
(
sd_ctrl_read16
(
host
,
CTL_VERSION
))
{
case
0x490C
:
val
=
(
width
==
32
)
?
0x0001
:
0x0000
;
break
;
case
0xCB0D
:
val
=
(
width
==
32
)
?
0x0000
:
0x0001
;
break
;
default:
/* nothing to do */
return
;
}
sd_ctrl_write16
(
host
,
EXT_ACC
,
val
);
}
static
int
sh_mobile_sdhi_clk_enable
(
struct
platform_device
*
pdev
,
unsigned
int
*
f
)
{
struct
mmc_host
*
mmc
=
platform_get_drvdata
(
pdev
);
struct
tmio_mmc_host
*
host
=
mmc_priv
(
mmc
);
struct
sh_mobile_sdhi
*
priv
=
container_of
(
host
->
pdata
,
struct
sh_mobile_sdhi
,
mmc_data
);
struct
sh_mobile_sdhi
*
priv
=
host_to_priv
(
host
);
int
ret
=
clk_prepare_enable
(
priv
->
clk
);
if
(
ret
<
0
)
return
ret
;
*
f
=
clk_get_rate
(
priv
->
clk
);
/* enable 16bit data access on SDBUF as default */
sh_mobile_sdhi_sdbuf_width
(
host
,
16
);
return
0
;
}
...
...
@@ -101,7 +132,7 @@ static void sh_mobile_sdhi_clk_disable(struct platform_device *pdev)
{
struct
mmc_host
*
mmc
=
platform_get_drvdata
(
pdev
);
struct
tmio_mmc_host
*
host
=
mmc_priv
(
mmc
);
struct
sh_mobile_sdhi
*
priv
=
container_of
(
host
->
pdata
,
struct
sh_mobile_sdhi
,
mmc_data
);
struct
sh_mobile_sdhi
*
priv
=
host_to_priv
(
host
);
clk_disable_unprepare
(
priv
->
clk
);
}
...
...
@@ -113,7 +144,7 @@ static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host)
udelay
(
1
);
if
(
!
timeout
)
{
dev_warn
(
host
->
pdata
->
dev
,
"timeout waiting for SD bus idle
\n
"
);
dev_warn
(
&
host
->
pdev
->
dev
,
"timeout waiting for SD bus idle
\n
"
);
return
-
EBUSY
;
}
...
...
@@ -156,14 +187,13 @@ static int sh_mobile_sdhi_multi_io_quirk(struct mmc_card *card,
return
blk_size
;
}
static
void
sh_mobile_sdhi_
cd_wakeup
(
const
struct
platform_device
*
pdev
)
static
void
sh_mobile_sdhi_
enable_dma
(
struct
tmio_mmc_host
*
host
,
bool
enable
)
{
mmc_detect_change
(
platform_get_drvdata
(
pdev
),
msecs_to_jiffies
(
100
));
}
sd_ctrl_write16
(
host
,
CTL_DMA_ENABLE
,
enable
?
2
:
0
);
static
const
struct
sh_mobile_sdhi_ops
sdhi_ops
=
{
.
cd_wakeup
=
sh_mobile_sdhi_cd_wakeup
,
}
;
/* enable 32bit access if DMA mode if possibile */
sh_mobile_sdhi_sdbuf_width
(
host
,
enable
?
32
:
16
);
}
static
int
sh_mobile_sdhi_probe
(
struct
platform_device
*
pdev
)
{
...
...
@@ -177,7 +207,6 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
int
irq
,
ret
,
i
=
0
;
bool
multiplexed_isr
=
true
;
struct
tmio_mmc_dma
*
dma_priv
;
u16
ver
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
res
)
...
...
@@ -192,26 +221,31 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
mmc_data
=
&
priv
->
mmc_data
;
dma_priv
=
&
priv
->
dma_priv
;
if
(
p
)
{
if
(
p
->
init
)
{
ret
=
p
->
init
(
pdev
,
&
sdhi_ops
);
if
(
ret
)
return
ret
;
}
}
priv
->
clk
=
devm_clk_get
(
&
pdev
->
dev
,
NULL
);
if
(
IS_ERR
(
priv
->
clk
))
{
ret
=
PTR_ERR
(
priv
->
clk
);
dev_err
(
&
pdev
->
dev
,
"cannot get clock: %d
\n
"
,
ret
);
goto
e
clkget
;
goto
e
probe
;
}
mmc_data
->
clk_enable
=
sh_mobile_sdhi_clk_enable
;
mmc_data
->
clk_disable
=
sh_mobile_sdhi_clk_disable
;
host
=
tmio_mmc_host_alloc
(
pdev
);
if
(
!
host
)
{
ret
=
-
ENOMEM
;
goto
eprobe
;
}
host
->
dma
=
dma_priv
;
host
->
write16_hook
=
sh_mobile_sdhi_write16_hook
;
host
->
clk_enable
=
sh_mobile_sdhi_clk_enable
;
host
->
clk_disable
=
sh_mobile_sdhi_clk_disable
;
host
->
multi_io_quirk
=
sh_mobile_sdhi_multi_io_quirk
;
/* SD control register space size is 0x100, 0x200 for bus_shift=1 */
if
(
resource_size
(
res
)
>
0x100
)
host
->
bus_shift
=
1
;
else
host
->
bus_shift
=
0
;
mmc_data
->
capabilities
=
MMC_CAP_MMC_HIGHSPEED
;
mmc_data
->
write16_hook
=
sh_mobile_sdhi_write16_hook
;
mmc_data
->
multi_io_quirk
=
sh_mobile_sdhi_multi_io_quirk
;
if
(
p
)
{
mmc_data
->
flags
=
p
->
tmio_flags
;
mmc_data
->
ocr_mask
=
p
->
tmio_ocr_mask
;
...
...
@@ -231,11 +265,10 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
dma_priv
->
slave_id_rx
=
p
->
dma_slave_rx
;
}
}
dma_priv
->
alignment_shift
=
1
;
/* 2-byte alignment */
dma_priv
->
filter
=
shdma_chan_filter
;
dma_priv
->
enable
=
sh_mobile_sdhi_enable_dma
;
mmc_data
->
dma
=
dma_priv
;
mmc_data
->
alignment_shift
=
1
;
/* 2-byte alignment */
/*
* All SDHI blocks support 2-byte and larger block sizes in 4-bit
...
...
@@ -258,33 +291,18 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
*/
mmc_data
->
flags
|=
TMIO_MMC_SDIO_STATUS_QUIRK
;
/*
* All SDHI have DMA control register
*/
mmc_data
->
flags
|=
TMIO_MMC_HAVE_CTL_DMA_REG
;
if
(
of_id
&&
of_id
->
data
)
{
const
struct
sh_mobile_sdhi_of_data
*
of_data
=
of_id
->
data
;
mmc_data
->
flags
|=
of_data
->
tmio_flags
;
mmc_data
->
capabilities
|=
of_data
->
capabilities
;
mmc_data
->
capabilities2
|=
of_data
->
capabilities2
;
dma_priv
->
dma_rx_offset
=
of_data
->
dma_rx_offset
;
mmc_data
->
dma_rx_offset
=
of_data
->
dma_rx_offset
;
dma_priv
->
dma_buswidth
=
of_data
->
dma_buswidth
;
}
/* SD control register space size is 0x100, 0x200 for bus_shift=1 */
mmc_data
->
bus_shift
=
resource_size
(
res
)
>>
9
;
ret
=
tmio_mmc_host_probe
(
&
host
,
pdev
,
mmc_data
);
ret
=
tmio_mmc_host_probe
(
host
,
mmc_data
);
if
(
ret
<
0
)
goto
eprobe
;
/*
* FIXME:
* this Workaround can be more clever method
*/
ver
=
sd_ctrl_read16
(
host
,
CTL_VERSION
);
if
(
ver
==
0xCB0D
)
sd_ctrl_write16
(
host
,
EXT_ACC
,
1
);
goto
efree
;
/*
* Allow one or more specific (named) ISRs or
...
...
@@ -351,10 +369,9 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
eirq:
tmio_mmc_host_remove
(
host
);
efree:
tmio_mmc_host_free
(
host
);
eprobe:
eclkget:
if
(
p
&&
p
->
cleanup
)
p
->
cleanup
(
pdev
);
return
ret
;
}
...
...
@@ -362,13 +379,9 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
{
struct
mmc_host
*
mmc
=
platform_get_drvdata
(
pdev
);
struct
tmio_mmc_host
*
host
=
mmc_priv
(
mmc
);
struct
sh_mobile_sdhi_info
*
p
=
pdev
->
dev
.
platform_data
;
tmio_mmc_host_remove
(
host
);
if
(
p
&&
p
->
cleanup
)
p
->
cleanup
(
pdev
);
return
0
;
}
...
...
drivers/mmc/host/tmio_mmc.c
浏览文件 @
9cd0ef2b
...
...
@@ -88,14 +88,19 @@ static int tmio_mmc_probe(struct platform_device *pdev)
if
(
!
res
)
return
-
EINVAL
;
/* SD control register space size is 0x200, 0x400 for bus_shift=1 */
pdata
->
bus_shift
=
resource_size
(
res
)
>>
10
;
pdata
->
flags
|=
TMIO_MMC_HAVE_HIGH_REG
;
ret
=
tmio_mmc_host_probe
(
&
host
,
pdev
,
pdata
);
if
(
re
t
)
host
=
tmio_mmc_host_alloc
(
pdev
);
if
(
!
hos
t
)
goto
cell_disable
;
/* SD control register space size is 0x200, 0x400 for bus_shift=1 */
host
->
bus_shift
=
resource_size
(
res
)
>>
10
;
ret
=
tmio_mmc_host_probe
(
host
,
pdata
);
if
(
ret
)
goto
host_free
;
ret
=
request_irq
(
irq
,
tmio_mmc_irq
,
IRQF_TRIGGER_FALLING
,
dev_name
(
&
pdev
->
dev
),
host
);
if
(
ret
)
...
...
@@ -108,6 +113,8 @@ static int tmio_mmc_probe(struct platform_device *pdev)
host_remove:
tmio_mmc_host_remove
(
host
);
host_free:
tmio_mmc_host_free
(
host
);
cell_disable:
if
(
cell
->
disable
)
cell
->
disable
(
pdev
);
...
...
drivers/mmc/host/tmio_mmc.h
浏览文件 @
9cd0ef2b
...
...
@@ -16,6 +16,7 @@
#ifndef TMIO_MMC_H
#define TMIO_MMC_H
#include <linux/dmaengine.h>
#include <linux/highmem.h>
#include <linux/mmc/tmio.h>
#include <linux/mutex.h>
...
...
@@ -39,6 +40,17 @@
#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
struct
tmio_mmc_data
;
struct
tmio_mmc_host
;
struct
tmio_mmc_dma
{
void
*
chan_priv_tx
;
void
*
chan_priv_rx
;
int
slave_id_tx
;
int
slave_id_rx
;
enum
dma_slave_buswidth
dma_buswidth
;
bool
(
*
filter
)(
struct
dma_chan
*
chan
,
void
*
arg
);
void
(
*
enable
)(
struct
tmio_mmc_host
*
host
,
bool
enable
);
};
struct
tmio_mmc_host
{
void
__iomem
*
ctl
;
...
...
@@ -56,9 +68,11 @@ struct tmio_mmc_host {
struct
scatterlist
*
sg_orig
;
unsigned
int
sg_len
;
unsigned
int
sg_off
;
unsigned
long
bus_shift
;
struct
platform_device
*
pdev
;
struct
tmio_mmc_data
*
pdata
;
struct
tmio_mmc_dma
*
dma
;
/* DMA support */
bool
force_pio
;
...
...
@@ -83,10 +97,17 @@ struct tmio_mmc_host {
struct
mutex
ios_lock
;
/* protect set_ios() context */
bool
native_hotplug
;
bool
sdio_irq_enabled
;
int
(
*
write16_hook
)(
struct
tmio_mmc_host
*
host
,
int
addr
);
int
(
*
clk_enable
)(
struct
platform_device
*
pdev
,
unsigned
int
*
f
);
void
(
*
clk_disable
)(
struct
platform_device
*
pdev
);
int
(
*
multi_io_quirk
)(
struct
mmc_card
*
card
,
unsigned
int
direction
,
int
blk_size
);
};
int
tmio_mmc_host_probe
(
struct
tmio_mmc_host
**
host
,
struct
platform_device
*
pdev
,
struct
tmio_mmc_host
*
tmio_mmc_host_alloc
(
struct
platform_device
*
pdev
);
void
tmio_mmc_host_free
(
struct
tmio_mmc_host
*
host
);
int
tmio_mmc_host_probe
(
struct
tmio_mmc_host
*
host
,
struct
tmio_mmc_data
*
pdata
);
void
tmio_mmc_host_remove
(
struct
tmio_mmc_host
*
host
);
void
tmio_mmc_do_data_irq
(
struct
tmio_mmc_host
*
host
);
...
...
@@ -151,19 +172,19 @@ int tmio_mmc_host_runtime_resume(struct device *dev);
static
inline
u16
sd_ctrl_read16
(
struct
tmio_mmc_host
*
host
,
int
addr
)
{
return
readw
(
host
->
ctl
+
(
addr
<<
host
->
pdata
->
bus_shift
));
return
readw
(
host
->
ctl
+
(
addr
<<
host
->
bus_shift
));
}
static
inline
void
sd_ctrl_read16_rep
(
struct
tmio_mmc_host
*
host
,
int
addr
,
u16
*
buf
,
int
count
)
{
readsw
(
host
->
ctl
+
(
addr
<<
host
->
pdata
->
bus_shift
),
buf
,
count
);
readsw
(
host
->
ctl
+
(
addr
<<
host
->
bus_shift
),
buf
,
count
);
}
static
inline
u32
sd_ctrl_read32
(
struct
tmio_mmc_host
*
host
,
int
addr
)
{
return
readw
(
host
->
ctl
+
(
addr
<<
host
->
pdata
->
bus_shift
))
|
readw
(
host
->
ctl
+
((
addr
+
2
)
<<
host
->
pdata
->
bus_shift
))
<<
16
;
return
readw
(
host
->
ctl
+
(
addr
<<
host
->
bus_shift
))
|
readw
(
host
->
ctl
+
((
addr
+
2
)
<<
host
->
bus_shift
))
<<
16
;
}
static
inline
void
sd_ctrl_write16
(
struct
tmio_mmc_host
*
host
,
int
addr
,
u16
val
)
...
...
@@ -171,21 +192,21 @@ static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val
/* If there is a hook and it returns non-zero then there
* is an error and the write should be skipped
*/
if
(
host
->
pdata
->
write16_hook
&&
host
->
pdata
->
write16_hook
(
host
,
addr
))
if
(
host
->
write16_hook
&&
host
->
write16_hook
(
host
,
addr
))
return
;
writew
(
val
,
host
->
ctl
+
(
addr
<<
host
->
pdata
->
bus_shift
));
writew
(
val
,
host
->
ctl
+
(
addr
<<
host
->
bus_shift
));
}
static
inline
void
sd_ctrl_write16_rep
(
struct
tmio_mmc_host
*
host
,
int
addr
,
u16
*
buf
,
int
count
)
{
writesw
(
host
->
ctl
+
(
addr
<<
host
->
pdata
->
bus_shift
),
buf
,
count
);
writesw
(
host
->
ctl
+
(
addr
<<
host
->
bus_shift
),
buf
,
count
);
}
static
inline
void
sd_ctrl_write32
(
struct
tmio_mmc_host
*
host
,
int
addr
,
u32
val
)
{
writew
(
val
,
host
->
ctl
+
(
addr
<<
host
->
pdata
->
bus_shift
));
writew
(
val
>>
16
,
host
->
ctl
+
((
addr
+
2
)
<<
host
->
pdata
->
bus_shift
));
writew
(
val
,
host
->
ctl
+
(
addr
<<
host
->
bus_shift
));
writew
(
val
>>
16
,
host
->
ctl
+
((
addr
+
2
)
<<
host
->
bus_shift
));
}
...
...
drivers/mmc/host/tmio_mmc_dma.c
浏览文件 @
9cd0ef2b
...
...
@@ -28,8 +28,8 @@ void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
if
(
!
host
->
chan_tx
||
!
host
->
chan_rx
)
return
;
if
(
host
->
pdata
->
flags
&
TMIO_MMC_HAVE_CTL_DMA_REG
)
sd_ctrl_write16
(
host
,
CTL_DMA_ENABLE
,
enable
?
2
:
0
);
if
(
host
->
dma
->
enable
)
host
->
dma
->
enable
(
host
,
enable
);
}
void
tmio_mmc_abort_dma
(
struct
tmio_mmc_host
*
host
)
...
...
@@ -49,11 +49,10 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
struct
scatterlist
*
sg
=
host
->
sg_ptr
,
*
sg_tmp
;
struct
dma_async_tx_descriptor
*
desc
=
NULL
;
struct
dma_chan
*
chan
=
host
->
chan_rx
;
struct
tmio_mmc_data
*
pdata
=
host
->
pdata
;
dma_cookie_t
cookie
;
int
ret
,
i
;
bool
aligned
=
true
,
multiple
=
true
;
unsigned
int
align
=
(
1
<<
pdata
->
dm
a
->
alignment_shift
)
-
1
;
unsigned
int
align
=
(
1
<<
host
->
pdat
a
->
alignment_shift
)
-
1
;
for_each_sg
(
sg
,
sg_tmp
,
host
->
sg_len
,
i
)
{
if
(
sg_tmp
->
offset
&
align
)
...
...
@@ -126,11 +125,10 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
struct
scatterlist
*
sg
=
host
->
sg_ptr
,
*
sg_tmp
;
struct
dma_async_tx_descriptor
*
desc
=
NULL
;
struct
dma_chan
*
chan
=
host
->
chan_tx
;
struct
tmio_mmc_data
*
pdata
=
host
->
pdata
;
dma_cookie_t
cookie
;
int
ret
,
i
;
bool
aligned
=
true
,
multiple
=
true
;
unsigned
int
align
=
(
1
<<
pdata
->
dm
a
->
alignment_shift
)
-
1
;
unsigned
int
align
=
(
1
<<
host
->
pdat
a
->
alignment_shift
)
-
1
;
for_each_sg
(
sg
,
sg_tmp
,
host
->
sg_len
,
i
)
{
if
(
sg_tmp
->
offset
&
align
)
...
...
@@ -262,8 +260,8 @@ static void tmio_mmc_tasklet_fn(unsigned long arg)
void
tmio_mmc_request_dma
(
struct
tmio_mmc_host
*
host
,
struct
tmio_mmc_data
*
pdata
)
{
/* We can only either use DMA for both Tx and Rx or not use it at all */
if
(
!
pdata
->
dma
||
(
!
host
->
pdev
->
dev
.
of_node
&&
(
!
pdata
->
dma
->
chan_priv_tx
||
!
pdata
->
dma
->
chan_priv_rx
)))
if
(
!
host
->
dma
||
(
!
host
->
pdev
->
dev
.
of_node
&&
(
!
host
->
dma
->
chan_priv_tx
||
!
host
->
dma
->
chan_priv_rx
)))
return
;
if
(
!
host
->
chan_tx
&&
!
host
->
chan_rx
)
{
...
...
@@ -280,7 +278,7 @@ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdat
dma_cap_set
(
DMA_SLAVE
,
mask
);
host
->
chan_tx
=
dma_request_slave_channel_compat
(
mask
,
pdata
->
dma
->
filter
,
pdata
->
dma
->
chan_priv_tx
,
host
->
dma
->
filter
,
host
->
dma
->
chan_priv_tx
,
&
host
->
pdev
->
dev
,
"tx"
);
dev_dbg
(
&
host
->
pdev
->
dev
,
"%s: TX: got channel %p
\n
"
,
__func__
,
host
->
chan_tx
);
...
...
@@ -288,18 +286,20 @@ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdat
if
(
!
host
->
chan_tx
)
return
;
if
(
pdata
->
dma
->
chan_priv_tx
)
cfg
.
slave_id
=
pdata
->
dma
->
slave_id_tx
;
if
(
host
->
dma
->
chan_priv_tx
)
cfg
.
slave_id
=
host
->
dma
->
slave_id_tx
;
cfg
.
direction
=
DMA_MEM_TO_DEV
;
cfg
.
dst_addr
=
res
->
start
+
(
CTL_SD_DATA_PORT
<<
host
->
pdata
->
bus_shift
);
cfg
.
dst_addr_width
=
DMA_SLAVE_BUSWIDTH_2_BYTES
;
cfg
.
dst_addr
=
res
->
start
+
(
CTL_SD_DATA_PORT
<<
host
->
bus_shift
);
cfg
.
dst_addr_width
=
host
->
dma
->
dma_buswidth
;
if
(
!
cfg
.
dst_addr_width
)
cfg
.
dst_addr_width
=
DMA_SLAVE_BUSWIDTH_2_BYTES
;
cfg
.
src_addr
=
0
;
ret
=
dmaengine_slave_config
(
host
->
chan_tx
,
&
cfg
);
if
(
ret
<
0
)
goto
ecfgtx
;
host
->
chan_rx
=
dma_request_slave_channel_compat
(
mask
,
pdata
->
dma
->
filter
,
pdata
->
dma
->
chan_priv_rx
,
host
->
dma
->
filter
,
host
->
dma
->
chan_priv_rx
,
&
host
->
pdev
->
dev
,
"rx"
);
dev_dbg
(
&
host
->
pdev
->
dev
,
"%s: RX: got channel %p
\n
"
,
__func__
,
host
->
chan_rx
);
...
...
@@ -307,11 +307,13 @@ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdat
if
(
!
host
->
chan_rx
)
goto
ereqrx
;
if
(
pdata
->
dma
->
chan_priv_rx
)
cfg
.
slave_id
=
pdata
->
dma
->
slave_id_rx
;
if
(
host
->
dma
->
chan_priv_rx
)
cfg
.
slave_id
=
host
->
dma
->
slave_id_rx
;
cfg
.
direction
=
DMA_DEV_TO_MEM
;
cfg
.
src_addr
=
cfg
.
dst_addr
+
pdata
->
dma
->
dma_rx_offset
;
cfg
.
src_addr_width
=
DMA_SLAVE_BUSWIDTH_2_BYTES
;
cfg
.
src_addr
=
cfg
.
dst_addr
+
host
->
pdata
->
dma_rx_offset
;
cfg
.
src_addr_width
=
host
->
dma
->
dma_buswidth
;
if
(
!
cfg
.
src_addr_width
)
cfg
.
src_addr_width
=
DMA_SLAVE_BUSWIDTH_2_BYTES
;
cfg
.
dst_addr
=
0
;
ret
=
dmaengine_slave_config
(
host
->
chan_rx
,
&
cfg
);
if
(
ret
<
0
)
...
...
drivers/mmc/host/tmio_mmc_pio.c
浏览文件 @
9cd0ef2b
...
...
@@ -835,13 +835,12 @@ static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
static
int
tmio_mmc_clk_update
(
struct
tmio_mmc_host
*
host
)
{
struct
mmc_host
*
mmc
=
host
->
mmc
;
struct
tmio_mmc_data
*
pdata
=
host
->
pdata
;
int
ret
;
if
(
!
pdata
->
clk_enable
)
if
(
!
host
->
clk_enable
)
return
-
ENOTSUPP
;
ret
=
pdata
->
clk_enable
(
host
->
pdev
,
&
mmc
->
f_max
);
ret
=
host
->
clk_enable
(
host
->
pdev
,
&
mmc
->
f_max
);
if
(
!
ret
)
mmc
->
f_min
=
mmc
->
f_max
/
512
;
...
...
@@ -1005,10 +1004,9 @@ static int tmio_multi_io_quirk(struct mmc_card *card,
unsigned
int
direction
,
int
blk_size
)
{
struct
tmio_mmc_host
*
host
=
mmc_priv
(
card
->
host
);
struct
tmio_mmc_data
*
pdata
=
host
->
pdata
;
if
(
pdata
->
multi_io_quirk
)
return
pdata
->
multi_io_quirk
(
card
,
direction
,
blk_size
);
if
(
host
->
multi_io_quirk
)
return
host
->
multi_io_quirk
(
card
,
direction
,
blk_size
);
return
blk_size
;
}
...
...
@@ -1054,12 +1052,37 @@ static void tmio_mmc_of_parse(struct platform_device *pdev,
pdata
->
flags
|=
TMIO_MMC_WRPROTECT_DISABLE
;
}
int
tmio_mmc_host_probe
(
struct
tmio_mmc_host
**
host
,
struct
platform_device
*
pdev
,
struct
tmio_mmc_data
*
pdata
)
struct
tmio_mmc_host
*
tmio_mmc_host_alloc
(
struct
platform_device
*
pdev
)
{
struct
tmio_mmc_host
*
_
host
;
struct
tmio_mmc_host
*
host
;
struct
mmc_host
*
mmc
;
mmc
=
mmc_alloc_host
(
sizeof
(
struct
tmio_mmc_host
),
&
pdev
->
dev
);
if
(
!
mmc
)
return
NULL
;
host
=
mmc_priv
(
mmc
);
host
->
mmc
=
mmc
;
host
->
pdev
=
pdev
;
return
host
;
}
EXPORT_SYMBOL
(
tmio_mmc_host_alloc
);
void
tmio_mmc_host_free
(
struct
tmio_mmc_host
*
host
)
{
mmc_free_host
(
host
->
mmc
);
host
->
mmc
=
NULL
;
}
EXPORT_SYMBOL
(
tmio_mmc_host_free
);
int
tmio_mmc_host_probe
(
struct
tmio_mmc_host
*
_host
,
struct
tmio_mmc_data
*
pdata
)
{
struct
platform_device
*
pdev
=
_host
->
pdev
;
struct
mmc_host
*
mmc
=
_host
->
mmc
;
struct
resource
*
res_ctl
;
int
ret
;
u32
irq_mask
=
TMIO_MASK_CMD
;
...
...
@@ -1067,25 +1090,17 @@ int tmio_mmc_host_probe(struct tmio_mmc_host **host,
tmio_mmc_of_parse
(
pdev
,
pdata
);
if
(
!
(
pdata
->
flags
&
TMIO_MMC_HAS_IDLE_WAIT
))
pdata
->
write16_hook
=
NULL
;
_host
->
write16_hook
=
NULL
;
res_ctl
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
res_ctl
)
return
-
EINVAL
;
mmc
=
mmc_alloc_host
(
sizeof
(
struct
tmio_mmc_host
),
&
pdev
->
dev
);
if
(
!
mmc
)
return
-
ENOMEM
;
ret
=
mmc_of_parse
(
mmc
);
if
(
ret
<
0
)
goto
host_free
;
pdata
->
dev
=
&
pdev
->
dev
;
_host
=
mmc_priv
(
mmc
);
_host
->
pdata
=
pdata
;
_host
->
mmc
=
mmc
;
_host
->
pdev
=
pdev
;
platform_set_drvdata
(
pdev
,
mmc
);
_host
->
set_pwr
=
pdata
->
set_pwr
;
...
...
@@ -1192,12 +1207,9 @@ int tmio_mmc_host_probe(struct tmio_mmc_host **host,
mmc_gpiod_request_cd_irq
(
mmc
);
}
*
host
=
_host
;
return
0
;
host_free:
mmc_free_host
(
mmc
);
return
ret
;
}
...
...
@@ -1222,7 +1234,6 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
pm_runtime_disable
(
&
pdev
->
dev
);
iounmap
(
host
->
ctl
);
mmc_free_host
(
mmc
);
}
EXPORT_SYMBOL
(
tmio_mmc_host_remove
);
...
...
@@ -1237,8 +1248,8 @@ int tmio_mmc_host_runtime_suspend(struct device *dev)
if
(
host
->
clk_cache
)
tmio_mmc_clk_stop
(
host
);
if
(
host
->
pdata
->
clk_disable
)
host
->
pdata
->
clk_disable
(
host
->
pdev
);
if
(
host
->
clk_disable
)
host
->
clk_disable
(
host
->
pdev
);
return
0
;
}
...
...
include/linux/mfd/tmio.h
浏览文件 @
9cd0ef2b
...
...
@@ -95,11 +95,6 @@
*/
#define TMIO_MMC_SDIO_STATUS_QUIRK (1 << 8)
/*
* Some controllers have DMA enable/disable register
*/
#define TMIO_MMC_HAVE_CTL_DMA_REG (1 << 9)
/*
* Some controllers allows to set SDx actual clock
*/
...
...
@@ -112,18 +107,6 @@ void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state);
struct
dma_chan
;
struct
tmio_mmc_dma
{
void
*
chan_priv_tx
;
void
*
chan_priv_rx
;
int
slave_id_tx
;
int
slave_id_rx
;
int
alignment_shift
;
dma_addr_t
dma_rx_offset
;
bool
(
*
filter
)(
struct
dma_chan
*
chan
,
void
*
arg
);
};
struct
tmio_mmc_host
;
/*
* data for the MMC controller
*/
...
...
@@ -132,19 +115,12 @@ struct tmio_mmc_data {
unsigned
long
capabilities
;
unsigned
long
capabilities2
;
unsigned
long
flags
;
unsigned
long
bus_shift
;
u32
ocr_mask
;
/* available voltages */
struct
tmio_mmc_dma
*
dma
;
struct
device
*
dev
;
unsigned
int
cd_gpio
;
int
alignment_shift
;
dma_addr_t
dma_rx_offset
;
void
(
*
set_pwr
)(
struct
platform_device
*
host
,
int
state
);
void
(
*
set_clk_div
)(
struct
platform_device
*
host
,
int
state
);
int
(
*
write16_hook
)(
struct
tmio_mmc_host
*
host
,
int
addr
);
/* clock management callbacks */
int
(
*
clk_enable
)(
struct
platform_device
*
pdev
,
unsigned
int
*
f
);
void
(
*
clk_disable
)(
struct
platform_device
*
pdev
);
int
(
*
multi_io_quirk
)(
struct
mmc_card
*
card
,
unsigned
int
direction
,
int
blk_size
);
};
/*
...
...
include/linux/mmc/sh_mobile_sdhi.h
浏览文件 @
9cd0ef2b
...
...
@@ -3,20 +3,10 @@
#include <linux/types.h>
struct
platform_device
;
#define SH_MOBILE_SDHI_IRQ_CARD_DETECT "card_detect"
#define SH_MOBILE_SDHI_IRQ_SDCARD "sdcard"
#define SH_MOBILE_SDHI_IRQ_SDIO "sdio"
/**
* struct sh_mobile_sdhi_ops - SDHI driver callbacks
* @cd_wakeup: trigger a card-detection run
*/
struct
sh_mobile_sdhi_ops
{
void
(
*
cd_wakeup
)(
const
struct
platform_device
*
pdev
);
};
struct
sh_mobile_sdhi_info
{
int
dma_slave_tx
;
int
dma_slave_rx
;
...
...
@@ -25,11 +15,6 @@ struct sh_mobile_sdhi_info {
unsigned
long
tmio_caps2
;
u32
tmio_ocr_mask
;
/* available MMC voltages */
unsigned
int
cd_gpio
;
/* callbacks for board specific setup code */
int
(
*
init
)(
struct
platform_device
*
pdev
,
const
struct
sh_mobile_sdhi_ops
*
ops
);
void
(
*
cleanup
)(
struct
platform_device
*
pdev
);
};
#endif
/* LINUX_MMC_SH_MOBILE_SDHI_H */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录