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
9cd0ef2b
Commit
9cd0ef2b
authored
Jan 20, 2015
by
Ulf Hansson
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'tmio' into next
parents
87a50745
de122cb1
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
166 additions
and
151 deletions
+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
No files found.
drivers/mmc/host/sh_mobile_sdhi.c
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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 */
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