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
bd6fe9e1
Commit
bd6fe9e1
authored
Sep 12, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/home/rmk/linux-2.6-mmc
parents
862aad56
210ce2a7
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
229 additions
and
235 deletions
+229
-235
drivers/mmc/wbsd.c
drivers/mmc/wbsd.c
+218
-223
drivers/mmc/wbsd.h
drivers/mmc/wbsd.h
+11
-12
No files found.
drivers/mmc/wbsd.c
View file @
bd6fe9e1
...
@@ -93,7 +93,7 @@ static int dma = 2;
...
@@ -93,7 +93,7 @@ static int dma = 2;
static
inline
void
wbsd_unlock_config
(
struct
wbsd_host
*
host
)
static
inline
void
wbsd_unlock_config
(
struct
wbsd_host
*
host
)
{
{
BUG_ON
(
host
->
config
==
0
);
BUG_ON
(
host
->
config
==
0
);
outb
(
host
->
unlock_code
,
host
->
config
);
outb
(
host
->
unlock_code
,
host
->
config
);
outb
(
host
->
unlock_code
,
host
->
config
);
outb
(
host
->
unlock_code
,
host
->
config
);
}
}
...
@@ -101,14 +101,14 @@ static inline void wbsd_unlock_config(struct wbsd_host* host)
...
@@ -101,14 +101,14 @@ static inline void wbsd_unlock_config(struct wbsd_host* host)
static
inline
void
wbsd_lock_config
(
struct
wbsd_host
*
host
)
static
inline
void
wbsd_lock_config
(
struct
wbsd_host
*
host
)
{
{
BUG_ON
(
host
->
config
==
0
);
BUG_ON
(
host
->
config
==
0
);
outb
(
LOCK_CODE
,
host
->
config
);
outb
(
LOCK_CODE
,
host
->
config
);
}
}
static
inline
void
wbsd_write_config
(
struct
wbsd_host
*
host
,
u8
reg
,
u8
value
)
static
inline
void
wbsd_write_config
(
struct
wbsd_host
*
host
,
u8
reg
,
u8
value
)
{
{
BUG_ON
(
host
->
config
==
0
);
BUG_ON
(
host
->
config
==
0
);
outb
(
reg
,
host
->
config
);
outb
(
reg
,
host
->
config
);
outb
(
value
,
host
->
config
+
1
);
outb
(
value
,
host
->
config
+
1
);
}
}
...
@@ -116,7 +116,7 @@ static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value)
...
@@ -116,7 +116,7 @@ static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value)
static
inline
u8
wbsd_read_config
(
struct
wbsd_host
*
host
,
u8
reg
)
static
inline
u8
wbsd_read_config
(
struct
wbsd_host
*
host
,
u8
reg
)
{
{
BUG_ON
(
host
->
config
==
0
);
BUG_ON
(
host
->
config
==
0
);
outb
(
reg
,
host
->
config
);
outb
(
reg
,
host
->
config
);
return
inb
(
host
->
config
+
1
);
return
inb
(
host
->
config
+
1
);
}
}
...
@@ -140,21 +140,21 @@ static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index)
...
@@ -140,21 +140,21 @@ static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index)
static
void
wbsd_init_device
(
struct
wbsd_host
*
host
)
static
void
wbsd_init_device
(
struct
wbsd_host
*
host
)
{
{
u8
setup
,
ier
;
u8
setup
,
ier
;
/*
/*
* Reset chip (SD/MMC part) and fifo.
* Reset chip (SD/MMC part) and fifo.
*/
*/
setup
=
wbsd_read_index
(
host
,
WBSD_IDX_SETUP
);
setup
=
wbsd_read_index
(
host
,
WBSD_IDX_SETUP
);
setup
|=
WBSD_FIFO_RESET
|
WBSD_SOFT_RESET
;
setup
|=
WBSD_FIFO_RESET
|
WBSD_SOFT_RESET
;
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
/*
/*
* Set DAT3 to input
* Set DAT3 to input
*/
*/
setup
&=
~
WBSD_DAT3_H
;
setup
&=
~
WBSD_DAT3_H
;
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
host
->
flags
&=
~
WBSD_FIGNORE_DETECT
;
host
->
flags
&=
~
WBSD_FIGNORE_DETECT
;
/*
/*
* Read back default clock.
* Read back default clock.
*/
*/
...
@@ -164,12 +164,12 @@ static void wbsd_init_device(struct wbsd_host* host)
...
@@ -164,12 +164,12 @@ static void wbsd_init_device(struct wbsd_host* host)
* Power down port.
* Power down port.
*/
*/
outb
(
WBSD_POWER_N
,
host
->
base
+
WBSD_CSR
);
outb
(
WBSD_POWER_N
,
host
->
base
+
WBSD_CSR
);
/*
/*
* Set maximum timeout.
* Set maximum timeout.
*/
*/
wbsd_write_index
(
host
,
WBSD_IDX_TAAC
,
0x7F
);
wbsd_write_index
(
host
,
WBSD_IDX_TAAC
,
0x7F
);
/*
/*
* Test for card presence
* Test for card presence
*/
*/
...
@@ -177,7 +177,7 @@ static void wbsd_init_device(struct wbsd_host* host)
...
@@ -177,7 +177,7 @@ static void wbsd_init_device(struct wbsd_host* host)
host
->
flags
|=
WBSD_FCARD_PRESENT
;
host
->
flags
|=
WBSD_FCARD_PRESENT
;
else
else
host
->
flags
&=
~
WBSD_FCARD_PRESENT
;
host
->
flags
&=
~
WBSD_FCARD_PRESENT
;
/*
/*
* Enable interesting interrupts.
* Enable interesting interrupts.
*/
*/
...
@@ -200,9 +200,9 @@ static void wbsd_init_device(struct wbsd_host* host)
...
@@ -200,9 +200,9 @@ static void wbsd_init_device(struct wbsd_host* host)
static
void
wbsd_reset
(
struct
wbsd_host
*
host
)
static
void
wbsd_reset
(
struct
wbsd_host
*
host
)
{
{
u8
setup
;
u8
setup
;
printk
(
KERN_ERR
DRIVER_NAME
": Resetting chip
\n
"
);
printk
(
KERN_ERR
DRIVER_NAME
": Resetting chip
\n
"
);
/*
/*
* Soft reset of chip (SD/MMC part).
* Soft reset of chip (SD/MMC part).
*/
*/
...
@@ -214,9 +214,9 @@ static void wbsd_reset(struct wbsd_host* host)
...
@@ -214,9 +214,9 @@ static void wbsd_reset(struct wbsd_host* host)
static
void
wbsd_request_end
(
struct
wbsd_host
*
host
,
struct
mmc_request
*
mrq
)
static
void
wbsd_request_end
(
struct
wbsd_host
*
host
,
struct
mmc_request
*
mrq
)
{
{
unsigned
long
dmaflags
;
unsigned
long
dmaflags
;
DBGF
(
"Ending request, cmd (%x)
\n
"
,
mrq
->
cmd
->
opcode
);
DBGF
(
"Ending request, cmd (%x)
\n
"
,
mrq
->
cmd
->
opcode
);
if
(
host
->
dma
>=
0
)
if
(
host
->
dma
>=
0
)
{
{
/*
/*
...
@@ -232,7 +232,7 @@ static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq)
...
@@ -232,7 +232,7 @@ static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq)
*/
*/
wbsd_write_index
(
host
,
WBSD_IDX_DMA
,
0
);
wbsd_write_index
(
host
,
WBSD_IDX_DMA
,
0
);
}
}
host
->
mrq
=
NULL
;
host
->
mrq
=
NULL
;
/*
/*
...
@@ -275,7 +275,7 @@ static inline int wbsd_next_sg(struct wbsd_host* host)
...
@@ -275,7 +275,7 @@ static inline int wbsd_next_sg(struct wbsd_host* host)
host
->
offset
=
0
;
host
->
offset
=
0
;
host
->
remain
=
host
->
cur_sg
->
length
;
host
->
remain
=
host
->
cur_sg
->
length
;
}
}
return
host
->
num_sg
;
return
host
->
num_sg
;
}
}
...
@@ -297,12 +297,12 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
...
@@ -297,12 +297,12 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
struct
scatterlist
*
sg
;
struct
scatterlist
*
sg
;
char
*
dmabuf
=
host
->
dma_buffer
;
char
*
dmabuf
=
host
->
dma_buffer
;
char
*
sgbuf
;
char
*
sgbuf
;
size
=
host
->
size
;
size
=
host
->
size
;
sg
=
data
->
sg
;
sg
=
data
->
sg
;
len
=
data
->
sg_len
;
len
=
data
->
sg_len
;
/*
/*
* Just loop through all entries. Size might not
* Just loop through all entries. Size might not
* be the entire list though so make sure that
* be the entire list though so make sure that
...
@@ -317,23 +317,23 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
...
@@ -317,23 +317,23 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
memcpy
(
dmabuf
,
sgbuf
,
sg
[
i
].
length
);
memcpy
(
dmabuf
,
sgbuf
,
sg
[
i
].
length
);
kunmap_atomic
(
sgbuf
,
KM_BIO_SRC_IRQ
);
kunmap_atomic
(
sgbuf
,
KM_BIO_SRC_IRQ
);
dmabuf
+=
sg
[
i
].
length
;
dmabuf
+=
sg
[
i
].
length
;
if
(
size
<
sg
[
i
].
length
)
if
(
size
<
sg
[
i
].
length
)
size
=
0
;
size
=
0
;
else
else
size
-=
sg
[
i
].
length
;
size
-=
sg
[
i
].
length
;
if
(
size
==
0
)
if
(
size
==
0
)
break
;
break
;
}
}
/*
/*
* Check that we didn't get a request to transfer
* Check that we didn't get a request to transfer
* more data than can fit into the SG list.
* more data than can fit into the SG list.
*/
*/
BUG_ON
(
size
!=
0
);
BUG_ON
(
size
!=
0
);
host
->
size
-=
size
;
host
->
size
-=
size
;
}
}
...
@@ -343,12 +343,12 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
...
@@ -343,12 +343,12 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
struct
scatterlist
*
sg
;
struct
scatterlist
*
sg
;
char
*
dmabuf
=
host
->
dma_buffer
;
char
*
dmabuf
=
host
->
dma_buffer
;
char
*
sgbuf
;
char
*
sgbuf
;
size
=
host
->
size
;
size
=
host
->
size
;
sg
=
data
->
sg
;
sg
=
data
->
sg
;
len
=
data
->
sg_len
;
len
=
data
->
sg_len
;
/*
/*
* Just loop through all entries. Size might not
* Just loop through all entries. Size might not
* be the entire list though so make sure that
* be the entire list though so make sure that
...
@@ -363,30 +363,30 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
...
@@ -363,30 +363,30 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
memcpy
(
sgbuf
,
dmabuf
,
sg
[
i
].
length
);
memcpy
(
sgbuf
,
dmabuf
,
sg
[
i
].
length
);
kunmap_atomic
(
sgbuf
,
KM_BIO_SRC_IRQ
);
kunmap_atomic
(
sgbuf
,
KM_BIO_SRC_IRQ
);
dmabuf
+=
sg
[
i
].
length
;
dmabuf
+=
sg
[
i
].
length
;
if
(
size
<
sg
[
i
].
length
)
if
(
size
<
sg
[
i
].
length
)
size
=
0
;
size
=
0
;
else
else
size
-=
sg
[
i
].
length
;
size
-=
sg
[
i
].
length
;
if
(
size
==
0
)
if
(
size
==
0
)
break
;
break
;
}
}
/*
/*
* Check that we didn't get a request to transfer
* Check that we didn't get a request to transfer
* more data than can fit into the SG list.
* more data than can fit into the SG list.
*/
*/
BUG_ON
(
size
!=
0
);
BUG_ON
(
size
!=
0
);
host
->
size
-=
size
;
host
->
size
-=
size
;
}
}
/*
/*
* Command handling
* Command handling
*/
*/
static
inline
void
wbsd_get_short_reply
(
struct
wbsd_host
*
host
,
static
inline
void
wbsd_get_short_reply
(
struct
wbsd_host
*
host
,
struct
mmc_command
*
cmd
)
struct
mmc_command
*
cmd
)
{
{
...
@@ -398,7 +398,7 @@ static inline void wbsd_get_short_reply(struct wbsd_host* host,
...
@@ -398,7 +398,7 @@ static inline void wbsd_get_short_reply(struct wbsd_host* host,
cmd
->
error
=
MMC_ERR_INVALID
;
cmd
->
error
=
MMC_ERR_INVALID
;
return
;
return
;
}
}
cmd
->
resp
[
0
]
=
cmd
->
resp
[
0
]
=
wbsd_read_index
(
host
,
WBSD_IDX_RESP12
)
<<
24
;
wbsd_read_index
(
host
,
WBSD_IDX_RESP12
)
<<
24
;
cmd
->
resp
[
0
]
|=
cmd
->
resp
[
0
]
|=
...
@@ -415,7 +415,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host,
...
@@ -415,7 +415,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host,
struct
mmc_command
*
cmd
)
struct
mmc_command
*
cmd
)
{
{
int
i
;
int
i
;
/*
/*
* Correct response type?
* Correct response type?
*/
*/
...
@@ -424,7 +424,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host,
...
@@ -424,7 +424,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host,
cmd
->
error
=
MMC_ERR_INVALID
;
cmd
->
error
=
MMC_ERR_INVALID
;
return
;
return
;
}
}
for
(
i
=
0
;
i
<
4
;
i
++
)
for
(
i
=
0
;
i
<
4
;
i
++
)
{
{
cmd
->
resp
[
i
]
=
cmd
->
resp
[
i
]
=
...
@@ -442,7 +442,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
...
@@ -442,7 +442,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
{
{
int
i
;
int
i
;
u8
status
,
isr
;
u8
status
,
isr
;
DBGF
(
"Sending cmd (%x)
\n
"
,
cmd
->
opcode
);
DBGF
(
"Sending cmd (%x)
\n
"
,
cmd
->
opcode
);
/*
/*
...
@@ -451,16 +451,16 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
...
@@ -451,16 +451,16 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
* transfer.
* transfer.
*/
*/
host
->
isr
=
0
;
host
->
isr
=
0
;
/*
/*
* Send the command (CRC calculated by host).
* Send the command (CRC calculated by host).
*/
*/
outb
(
cmd
->
opcode
,
host
->
base
+
WBSD_CMDR
);
outb
(
cmd
->
opcode
,
host
->
base
+
WBSD_CMDR
);
for
(
i
=
3
;
i
>=
0
;
i
--
)
for
(
i
=
3
;
i
>=
0
;
i
--
)
outb
((
cmd
->
arg
>>
(
i
*
8
))
&
0xff
,
host
->
base
+
WBSD_CMDR
);
outb
((
cmd
->
arg
>>
(
i
*
8
))
&
0xff
,
host
->
base
+
WBSD_CMDR
);
cmd
->
error
=
MMC_ERR_NONE
;
cmd
->
error
=
MMC_ERR_NONE
;
/*
/*
* Wait for the request to complete.
* Wait for the request to complete.
*/
*/
...
@@ -477,7 +477,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
...
@@ -477,7 +477,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
* Read back status.
* Read back status.
*/
*/
isr
=
host
->
isr
;
isr
=
host
->
isr
;
/* Card removed? */
/* Card removed? */
if
(
isr
&
WBSD_INT_CARD
)
if
(
isr
&
WBSD_INT_CARD
)
cmd
->
error
=
MMC_ERR_TIMEOUT
;
cmd
->
error
=
MMC_ERR_TIMEOUT
;
...
@@ -509,13 +509,13 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
...
@@ -509,13 +509,13 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
struct
mmc_data
*
data
=
host
->
mrq
->
cmd
->
data
;
struct
mmc_data
*
data
=
host
->
mrq
->
cmd
->
data
;
char
*
buffer
;
char
*
buffer
;
int
i
,
fsr
,
fifo
;
int
i
,
fsr
,
fifo
;
/*
/*
* Handle excessive data.
* Handle excessive data.
*/
*/
if
(
data
->
bytes_xfered
==
host
->
size
)
if
(
data
->
bytes_xfered
==
host
->
size
)
return
;
return
;
buffer
=
wbsd_kmap_sg
(
host
)
+
host
->
offset
;
buffer
=
wbsd_kmap_sg
(
host
)
+
host
->
offset
;
/*
/*
...
@@ -527,14 +527,14 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
...
@@ -527,14 +527,14 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
/*
/*
* The size field in the FSR is broken so we have to
* The size field in the FSR is broken so we have to
* do some guessing.
* do some guessing.
*/
*/
if
(
fsr
&
WBSD_FIFO_FULL
)
if
(
fsr
&
WBSD_FIFO_FULL
)
fifo
=
16
;
fifo
=
16
;
else
if
(
fsr
&
WBSD_FIFO_FUTHRE
)
else
if
(
fsr
&
WBSD_FIFO_FUTHRE
)
fifo
=
8
;
fifo
=
8
;
else
else
fifo
=
1
;
fifo
=
1
;
for
(
i
=
0
;
i
<
fifo
;
i
++
)
for
(
i
=
0
;
i
<
fifo
;
i
++
)
{
{
*
buffer
=
inb
(
host
->
base
+
WBSD_DFR
);
*
buffer
=
inb
(
host
->
base
+
WBSD_DFR
);
...
@@ -543,23 +543,23 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
...
@@ -543,23 +543,23 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
host
->
remain
--
;
host
->
remain
--
;
data
->
bytes_xfered
++
;
data
->
bytes_xfered
++
;
/*
/*
* Transfer done?
* Transfer done?
*/
*/
if
(
data
->
bytes_xfered
==
host
->
size
)
if
(
data
->
bytes_xfered
==
host
->
size
)
{
{
wbsd_kunmap_sg
(
host
);
wbsd_kunmap_sg
(
host
);
return
;
return
;
}
}
/*
/*
* End of scatter list entry?
* End of scatter list entry?
*/
*/
if
(
host
->
remain
==
0
)
if
(
host
->
remain
==
0
)
{
{
wbsd_kunmap_sg
(
host
);
wbsd_kunmap_sg
(
host
);
/*
/*
* Get next entry. Check if last.
* Get next entry. Check if last.
*/
*/
...
@@ -572,17 +572,17 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
...
@@ -572,17 +572,17 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
* into the scatter list.
* into the scatter list.
*/
*/
BUG_ON
(
1
);
BUG_ON
(
1
);
host
->
size
=
data
->
bytes_xfered
;
host
->
size
=
data
->
bytes_xfered
;
return
;
return
;
}
}
buffer
=
wbsd_kmap_sg
(
host
);
buffer
=
wbsd_kmap_sg
(
host
);
}
}
}
}
}
}
wbsd_kunmap_sg
(
host
);
wbsd_kunmap_sg
(
host
);
/*
/*
...
@@ -599,7 +599,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
...
@@ -599,7 +599,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
struct
mmc_data
*
data
=
host
->
mrq
->
cmd
->
data
;
struct
mmc_data
*
data
=
host
->
mrq
->
cmd
->
data
;
char
*
buffer
;
char
*
buffer
;
int
i
,
fsr
,
fifo
;
int
i
,
fsr
,
fifo
;
/*
/*
* Check that we aren't being called after the
* Check that we aren't being called after the
* entire buffer has been transfered.
* entire buffer has been transfered.
...
@@ -618,7 +618,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
...
@@ -618,7 +618,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
/*
/*
* The size field in the FSR is broken so we have to
* The size field in the FSR is broken so we have to
* do some guessing.
* do some guessing.
*/
*/
if
(
fsr
&
WBSD_FIFO_EMPTY
)
if
(
fsr
&
WBSD_FIFO_EMPTY
)
fifo
=
0
;
fifo
=
0
;
else
if
(
fsr
&
WBSD_FIFO_EMTHRE
)
else
if
(
fsr
&
WBSD_FIFO_EMTHRE
)
...
@@ -632,9 +632,9 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
...
@@ -632,9 +632,9 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
buffer
++
;
buffer
++
;
host
->
offset
++
;
host
->
offset
++
;
host
->
remain
--
;
host
->
remain
--
;
data
->
bytes_xfered
++
;
data
->
bytes_xfered
++
;
/*
/*
* Transfer done?
* Transfer done?
*/
*/
...
@@ -650,7 +650,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
...
@@ -650,7 +650,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
if
(
host
->
remain
==
0
)
if
(
host
->
remain
==
0
)
{
{
wbsd_kunmap_sg
(
host
);
wbsd_kunmap_sg
(
host
);
/*
/*
* Get next entry. Check if last.
* Get next entry. Check if last.
*/
*/
...
@@ -663,19 +663,19 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
...
@@ -663,19 +663,19 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
* into the scatter list.
* into the scatter list.
*/
*/
BUG_ON
(
1
);
BUG_ON
(
1
);
host
->
size
=
data
->
bytes_xfered
;
host
->
size
=
data
->
bytes_xfered
;
return
;
return
;
}
}
buffer
=
wbsd_kmap_sg
(
host
);
buffer
=
wbsd_kmap_sg
(
host
);
}
}
}
}
}
}
wbsd_kunmap_sg
(
host
);
wbsd_kunmap_sg
(
host
);
/*
/*
* The controller stops sending interrupts for
* The controller stops sending interrupts for
* 'FIFO empty' under certain conditions. So we
* 'FIFO empty' under certain conditions. So we
...
@@ -694,7 +694,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -694,7 +694,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
1
<<
data
->
blksz_bits
,
data
->
blocks
,
data
->
flags
);
1
<<
data
->
blksz_bits
,
data
->
blocks
,
data
->
flags
);
DBGF
(
"tsac %d ms nsac %d clk
\n
"
,
DBGF
(
"tsac %d ms nsac %d clk
\n
"
,
data
->
timeout_ns
/
1000000
,
data
->
timeout_clks
);
data
->
timeout_ns
/
1000000
,
data
->
timeout_clks
);
/*
/*
* Calculate size.
* Calculate size.
*/
*/
...
@@ -708,12 +708,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -708,12 +708,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
wbsd_write_index
(
host
,
WBSD_IDX_TAAC
,
127
);
wbsd_write_index
(
host
,
WBSD_IDX_TAAC
,
127
);
else
else
wbsd_write_index
(
host
,
WBSD_IDX_TAAC
,
data
->
timeout_ns
/
1000000
);
wbsd_write_index
(
host
,
WBSD_IDX_TAAC
,
data
->
timeout_ns
/
1000000
);
if
(
data
->
timeout_clks
>
255
)
if
(
data
->
timeout_clks
>
255
)
wbsd_write_index
(
host
,
WBSD_IDX_NSAC
,
255
);
wbsd_write_index
(
host
,
WBSD_IDX_NSAC
,
255
);
else
else
wbsd_write_index
(
host
,
WBSD_IDX_NSAC
,
data
->
timeout_clks
);
wbsd_write_index
(
host
,
WBSD_IDX_NSAC
,
data
->
timeout_clks
);
/*
/*
* Inform the chip of how large blocks will be
* Inform the chip of how large blocks will be
* sent. It needs this to determine when to
* sent. It needs this to determine when to
...
@@ -732,7 +732,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -732,7 +732,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
else
if
(
host
->
bus_width
==
MMC_BUS_WIDTH_4
)
else
if
(
host
->
bus_width
==
MMC_BUS_WIDTH_4
)
{
{
blksize
=
(
1
<<
data
->
blksz_bits
)
+
2
*
4
;
blksize
=
(
1
<<
data
->
blksz_bits
)
+
2
*
4
;
wbsd_write_index
(
host
,
WBSD_IDX_PBSMSB
,
((
blksize
>>
4
)
&
0xF0
)
wbsd_write_index
(
host
,
WBSD_IDX_PBSMSB
,
((
blksize
>>
4
)
&
0xF0
)
|
WBSD_DATA_WIDTH
);
|
WBSD_DATA_WIDTH
);
wbsd_write_index
(
host
,
WBSD_IDX_PBSLSB
,
blksize
&
0xFF
);
wbsd_write_index
(
host
,
WBSD_IDX_PBSLSB
,
blksize
&
0xFF
);
...
@@ -751,12 +751,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -751,12 +751,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
setup
=
wbsd_read_index
(
host
,
WBSD_IDX_SETUP
);
setup
=
wbsd_read_index
(
host
,
WBSD_IDX_SETUP
);
setup
|=
WBSD_FIFO_RESET
;
setup
|=
WBSD_FIFO_RESET
;
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
/*
/*
* DMA transfer?
* DMA transfer?
*/
*/
if
(
host
->
dma
>=
0
)
if
(
host
->
dma
>=
0
)
{
{
/*
/*
* The buffer for DMA is only 64 kB.
* The buffer for DMA is only 64 kB.
*/
*/
...
@@ -766,17 +766,17 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -766,17 +766,17 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
data
->
error
=
MMC_ERR_INVALID
;
data
->
error
=
MMC_ERR_INVALID
;
return
;
return
;
}
}
/*
/*
* Transfer data from the SG list to
* Transfer data from the SG list to
* the DMA buffer.
* the DMA buffer.
*/
*/
if
(
data
->
flags
&
MMC_DATA_WRITE
)
if
(
data
->
flags
&
MMC_DATA_WRITE
)
wbsd_sg_to_dma
(
host
,
data
);
wbsd_sg_to_dma
(
host
,
data
);
/*
/*
* Initialise the ISA DMA controller.
* Initialise the ISA DMA controller.
*/
*/
dmaflags
=
claim_dma_lock
();
dmaflags
=
claim_dma_lock
();
disable_dma
(
host
->
dma
);
disable_dma
(
host
->
dma
);
clear_dma_ff
(
host
->
dma
);
clear_dma_ff
(
host
->
dma
);
...
@@ -802,17 +802,17 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -802,17 +802,17 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
* output to a minimum.
* output to a minimum.
*/
*/
host
->
firsterr
=
1
;
host
->
firsterr
=
1
;
/*
/*
* Initialise the SG list.
* Initialise the SG list.
*/
*/
wbsd_init_sg
(
host
,
data
);
wbsd_init_sg
(
host
,
data
);
/*
/*
* Turn off DMA.
* Turn off DMA.
*/
*/
wbsd_write_index
(
host
,
WBSD_IDX_DMA
,
0
);
wbsd_write_index
(
host
,
WBSD_IDX_DMA
,
0
);
/*
/*
* Set up FIFO threshold levels (and fill
* Set up FIFO threshold levels (and fill
* buffer if doing a write).
* buffer if doing a write).
...
@@ -828,8 +828,8 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -828,8 +828,8 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
WBSD_FIFOEN_EMPTY
|
8
);
WBSD_FIFOEN_EMPTY
|
8
);
wbsd_fill_fifo
(
host
);
wbsd_fill_fifo
(
host
);
}
}
}
}
data
->
error
=
MMC_ERR_NONE
;
data
->
error
=
MMC_ERR_NONE
;
}
}
...
@@ -838,7 +838,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -838,7 +838,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
unsigned
long
dmaflags
;
unsigned
long
dmaflags
;
int
count
;
int
count
;
u8
status
;
u8
status
;
WARN_ON
(
host
->
mrq
==
NULL
);
WARN_ON
(
host
->
mrq
==
NULL
);
/*
/*
...
@@ -855,7 +855,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -855,7 +855,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
{
{
status
=
wbsd_read_index
(
host
,
WBSD_IDX_STATUS
);
status
=
wbsd_read_index
(
host
,
WBSD_IDX_STATUS
);
}
while
(
status
&
(
WBSD_BLOCK_READ
|
WBSD_BLOCK_WRITE
));
}
while
(
status
&
(
WBSD_BLOCK_READ
|
WBSD_BLOCK_WRITE
));
/*
/*
* DMA transfer?
* DMA transfer?
*/
*/
...
@@ -865,7 +865,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -865,7 +865,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
* Disable DMA on the host.
* Disable DMA on the host.
*/
*/
wbsd_write_index
(
host
,
WBSD_IDX_DMA
,
0
);
wbsd_write_index
(
host
,
WBSD_IDX_DMA
,
0
);
/*
/*
* Turn of ISA DMA controller.
* Turn of ISA DMA controller.
*/
*/
...
@@ -874,7 +874,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -874,7 +874,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
clear_dma_ff
(
host
->
dma
);
clear_dma_ff
(
host
->
dma
);
count
=
get_dma_residue
(
host
->
dma
);
count
=
get_dma_residue
(
host
->
dma
);
release_dma_lock
(
dmaflags
);
release_dma_lock
(
dmaflags
);
/*
/*
* Any leftover data?
* Any leftover data?
*/
*/
...
@@ -882,7 +882,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -882,7 +882,7 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
{
{
printk
(
KERN_ERR
DRIVER_NAME
": Incomplete DMA "
printk
(
KERN_ERR
DRIVER_NAME
": Incomplete DMA "
"transfer. %d bytes left.
\n
"
,
count
);
"transfer. %d bytes left.
\n
"
,
count
);
data
->
error
=
MMC_ERR_FAILED
;
data
->
error
=
MMC_ERR_FAILED
;
}
}
else
else
...
@@ -893,13 +893,13 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -893,13 +893,13 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
*/
*/
if
(
data
->
flags
&
MMC_DATA_READ
)
if
(
data
->
flags
&
MMC_DATA_READ
)
wbsd_dma_to_sg
(
host
,
data
);
wbsd_dma_to_sg
(
host
,
data
);
data
->
bytes_xfered
=
host
->
size
;
data
->
bytes_xfered
=
host
->
size
;
}
}
}
}
DBGF
(
"Ending data transfer (%d bytes)
\n
"
,
data
->
bytes_xfered
);
DBGF
(
"Ending data transfer (%d bytes)
\n
"
,
data
->
bytes_xfered
);
wbsd_request_end
(
host
,
host
->
mrq
);
wbsd_request_end
(
host
,
host
->
mrq
);
}
}
...
@@ -924,7 +924,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
...
@@ -924,7 +924,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
cmd
=
mrq
->
cmd
;
cmd
=
mrq
->
cmd
;
host
->
mrq
=
mrq
;
host
->
mrq
=
mrq
;
/*
/*
* If there is no card in the slot then
* If there is no card in the slot then
* timeout immediatly.
* timeout immediatly.
...
@@ -941,18 +941,18 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
...
@@ -941,18 +941,18 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
if
(
cmd
->
data
)
if
(
cmd
->
data
)
{
{
wbsd_prepare_data
(
host
,
cmd
->
data
);
wbsd_prepare_data
(
host
,
cmd
->
data
);
if
(
cmd
->
data
->
error
!=
MMC_ERR_NONE
)
if
(
cmd
->
data
->
error
!=
MMC_ERR_NONE
)
goto
done
;
goto
done
;
}
}
wbsd_send_command
(
host
,
cmd
);
wbsd_send_command
(
host
,
cmd
);
/*
/*
* If this is a data transfer the request
* If this is a data transfer the request
* will be finished after the data has
* will be finished after the data has
* transfered.
* transfered.
*/
*/
if
(
cmd
->
data
&&
(
cmd
->
error
==
MMC_ERR_NONE
))
if
(
cmd
->
data
&&
(
cmd
->
error
==
MMC_ERR_NONE
))
{
{
/*
/*
...
@@ -965,7 +965,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
...
@@ -965,7 +965,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
return
;
return
;
}
}
done:
done:
wbsd_request_end
(
host
,
mrq
);
wbsd_request_end
(
host
,
mrq
);
...
@@ -976,7 +976,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
...
@@ -976,7 +976,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
{
{
struct
wbsd_host
*
host
=
mmc_priv
(
mmc
);
struct
wbsd_host
*
host
=
mmc_priv
(
mmc
);
u8
clk
,
setup
,
pwr
;
u8
clk
,
setup
,
pwr
;
DBGF
(
"clock %uHz busmode %u powermode %u cs %u Vdd %u width %u
\n
"
,
DBGF
(
"clock %uHz busmode %u powermode %u cs %u Vdd %u width %u
\n
"
,
ios
->
clock
,
ios
->
bus_mode
,
ios
->
power_mode
,
ios
->
chip_select
,
ios
->
clock
,
ios
->
bus_mode
,
ios
->
power_mode
,
ios
->
chip_select
,
ios
->
vdd
,
ios
->
bus_width
);
ios
->
vdd
,
ios
->
bus_width
);
...
@@ -989,7 +989,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
...
@@ -989,7 +989,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
*/
*/
if
(
ios
->
power_mode
==
MMC_POWER_OFF
)
if
(
ios
->
power_mode
==
MMC_POWER_OFF
)
wbsd_init_device
(
host
);
wbsd_init_device
(
host
);
if
(
ios
->
clock
>=
24000000
)
if
(
ios
->
clock
>=
24000000
)
clk
=
WBSD_CLK_24M
;
clk
=
WBSD_CLK_24M
;
else
if
(
ios
->
clock
>=
16000000
)
else
if
(
ios
->
clock
>=
16000000
)
...
@@ -1042,7 +1042,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
...
@@ -1042,7 +1042,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
mod_timer
(
&
host
->
ignore_timer
,
jiffies
+
HZ
/
100
);
mod_timer
(
&
host
->
ignore_timer
,
jiffies
+
HZ
/
100
);
}
}
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
/*
/*
* Store bus width for later. Will be used when
* Store bus width for later. Will be used when
* setting up the data transfer.
* setting up the data transfer.
...
@@ -1128,7 +1128,7 @@ static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host)
...
@@ -1128,7 +1128,7 @@ static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host)
WARN_ON
(
!
host
->
mrq
->
cmd
->
data
);
WARN_ON
(
!
host
->
mrq
->
cmd
->
data
);
if
(
!
host
->
mrq
->
cmd
->
data
)
if
(
!
host
->
mrq
->
cmd
->
data
)
return
NULL
;
return
NULL
;
return
host
->
mrq
->
cmd
->
data
;
return
host
->
mrq
->
cmd
->
data
;
}
}
...
@@ -1136,72 +1136,67 @@ static void wbsd_tasklet_card(unsigned long param)
...
@@ -1136,72 +1136,67 @@ static void wbsd_tasklet_card(unsigned long param)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
u8
csr
;
u8
csr
;
int
delay
=
-
1
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
if
(
host
->
flags
&
WBSD_FIGNORE_DETECT
)
if
(
host
->
flags
&
WBSD_FIGNORE_DETECT
)
{
{
spin_unlock
(
&
host
->
lock
);
spin_unlock
(
&
host
->
lock
);
return
;
return
;
}
}
csr
=
inb
(
host
->
base
+
WBSD_CSR
);
csr
=
inb
(
host
->
base
+
WBSD_CSR
);
WARN_ON
(
csr
==
0xff
);
WARN_ON
(
csr
==
0xff
);
if
(
csr
&
WBSD_CARDPRESENT
)
if
(
csr
&
WBSD_CARDPRESENT
)
{
{
if
(
!
(
host
->
flags
&
WBSD_FCARD_PRESENT
))
if
(
!
(
host
->
flags
&
WBSD_FCARD_PRESENT
))
{
{
DBG
(
"Card inserted
\n
"
);
DBG
(
"Card inserted
\n
"
);
host
->
flags
|=
WBSD_FCARD_PRESENT
;
host
->
flags
|=
WBSD_FCARD_PRESENT
;
spin_unlock
(
&
host
->
lock
);
/*
delay
=
500
;
* Delay card detection to allow electrical connections
* to stabilise.
*/
mmc_detect_change
(
host
->
mmc
,
msecs_to_jiffies
(
500
));
}
}
else
spin_unlock
(
&
host
->
lock
);
}
}
else
if
(
host
->
flags
&
WBSD_FCARD_PRESENT
)
else
if
(
host
->
flags
&
WBSD_FCARD_PRESENT
)
{
{
DBG
(
"Card removed
\n
"
);
DBG
(
"Card removed
\n
"
);
host
->
flags
&=
~
WBSD_FCARD_PRESENT
;
host
->
flags
&=
~
WBSD_FCARD_PRESENT
;
if
(
host
->
mrq
)
if
(
host
->
mrq
)
{
{
printk
(
KERN_ERR
DRIVER_NAME
printk
(
KERN_ERR
DRIVER_NAME
": Card removed during transfer!
\n
"
);
": Card removed during transfer!
\n
"
);
wbsd_reset
(
host
);
wbsd_reset
(
host
);
host
->
mrq
->
cmd
->
error
=
MMC_ERR_FAILED
;
host
->
mrq
->
cmd
->
error
=
MMC_ERR_FAILED
;
tasklet_schedule
(
&
host
->
finish_tasklet
);
tasklet_schedule
(
&
host
->
finish_tasklet
);
}
}
/*
* Unlock first since we might get a call back.
*/
spin_unlock
(
&
host
->
lock
);
mmc_detect_change
(
host
->
mmc
,
0
)
;
delay
=
0
;
}
}
else
spin_unlock
(
&
host
->
lock
);
/*
* Unlock first since we might get a call back.
*/
spin_unlock
(
&
host
->
lock
);
if
(
delay
!=
-
1
)
mmc_detect_change
(
host
->
mmc
,
msecs_to_jiffies
(
delay
));
}
}
static
void
wbsd_tasklet_fifo
(
unsigned
long
param
)
static
void
wbsd_tasklet_fifo
(
unsigned
long
param
)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
mmc_data
*
data
;
struct
mmc_data
*
data
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
if
(
!
host
->
mrq
)
if
(
!
host
->
mrq
)
goto
end
;
goto
end
;
data
=
wbsd_get_data
(
host
);
data
=
wbsd_get_data
(
host
);
if
(
!
data
)
if
(
!
data
)
goto
end
;
goto
end
;
...
@@ -1220,7 +1215,7 @@ static void wbsd_tasklet_fifo(unsigned long param)
...
@@ -1220,7 +1215,7 @@ static void wbsd_tasklet_fifo(unsigned long param)
tasklet_schedule
(
&
host
->
finish_tasklet
);
tasklet_schedule
(
&
host
->
finish_tasklet
);
}
}
end:
end:
spin_unlock
(
&
host
->
lock
);
spin_unlock
(
&
host
->
lock
);
}
}
...
@@ -1228,23 +1223,23 @@ static void wbsd_tasklet_crc(unsigned long param)
...
@@ -1228,23 +1223,23 @@ static void wbsd_tasklet_crc(unsigned long param)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
mmc_data
*
data
;
struct
mmc_data
*
data
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
if
(
!
host
->
mrq
)
if
(
!
host
->
mrq
)
goto
end
;
goto
end
;
data
=
wbsd_get_data
(
host
);
data
=
wbsd_get_data
(
host
);
if
(
!
data
)
if
(
!
data
)
goto
end
;
goto
end
;
DBGF
(
"CRC error
\n
"
);
DBGF
(
"CRC error
\n
"
);
data
->
error
=
MMC_ERR_BADCRC
;
data
->
error
=
MMC_ERR_BADCRC
;
tasklet_schedule
(
&
host
->
finish_tasklet
);
tasklet_schedule
(
&
host
->
finish_tasklet
);
end:
end:
spin_unlock
(
&
host
->
lock
);
spin_unlock
(
&
host
->
lock
);
}
}
...
@@ -1252,23 +1247,23 @@ static void wbsd_tasklet_timeout(unsigned long param)
...
@@ -1252,23 +1247,23 @@ static void wbsd_tasklet_timeout(unsigned long param)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
mmc_data
*
data
;
struct
mmc_data
*
data
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
if
(
!
host
->
mrq
)
if
(
!
host
->
mrq
)
goto
end
;
goto
end
;
data
=
wbsd_get_data
(
host
);
data
=
wbsd_get_data
(
host
);
if
(
!
data
)
if
(
!
data
)
goto
end
;
goto
end
;
DBGF
(
"Timeout
\n
"
);
DBGF
(
"Timeout
\n
"
);
data
->
error
=
MMC_ERR_TIMEOUT
;
data
->
error
=
MMC_ERR_TIMEOUT
;
tasklet_schedule
(
&
host
->
finish_tasklet
);
tasklet_schedule
(
&
host
->
finish_tasklet
);
end:
end:
spin_unlock
(
&
host
->
lock
);
spin_unlock
(
&
host
->
lock
);
}
}
...
@@ -1276,20 +1271,20 @@ static void wbsd_tasklet_finish(unsigned long param)
...
@@ -1276,20 +1271,20 @@ static void wbsd_tasklet_finish(unsigned long param)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
mmc_data
*
data
;
struct
mmc_data
*
data
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
WARN_ON
(
!
host
->
mrq
);
WARN_ON
(
!
host
->
mrq
);
if
(
!
host
->
mrq
)
if
(
!
host
->
mrq
)
goto
end
;
goto
end
;
data
=
wbsd_get_data
(
host
);
data
=
wbsd_get_data
(
host
);
if
(
!
data
)
if
(
!
data
)
goto
end
;
goto
end
;
wbsd_finish_data
(
host
,
data
);
wbsd_finish_data
(
host
,
data
);
end:
end:
spin_unlock
(
&
host
->
lock
);
spin_unlock
(
&
host
->
lock
);
}
}
...
@@ -1297,7 +1292,7 @@ static void wbsd_tasklet_block(unsigned long param)
...
@@ -1297,7 +1292,7 @@ static void wbsd_tasklet_block(unsigned long param)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
mmc_data
*
data
;
struct
mmc_data
*
data
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
if
((
wbsd_read_index
(
host
,
WBSD_IDX_CRCSTATUS
)
&
WBSD_CRC_MASK
)
!=
if
((
wbsd_read_index
(
host
,
WBSD_IDX_CRCSTATUS
)
&
WBSD_CRC_MASK
)
!=
...
@@ -1306,15 +1301,15 @@ static void wbsd_tasklet_block(unsigned long param)
...
@@ -1306,15 +1301,15 @@ static void wbsd_tasklet_block(unsigned long param)
data
=
wbsd_get_data
(
host
);
data
=
wbsd_get_data
(
host
);
if
(
!
data
)
if
(
!
data
)
goto
end
;
goto
end
;
DBGF
(
"CRC error
\n
"
);
DBGF
(
"CRC error
\n
"
);
data
->
error
=
MMC_ERR_BADCRC
;
data
->
error
=
MMC_ERR_BADCRC
;
tasklet_schedule
(
&
host
->
finish_tasklet
);
tasklet_schedule
(
&
host
->
finish_tasklet
);
}
}
end:
end:
spin_unlock
(
&
host
->
lock
);
spin_unlock
(
&
host
->
lock
);
}
}
...
@@ -1326,7 +1321,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -1326,7 +1321,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
{
{
struct
wbsd_host
*
host
=
dev_id
;
struct
wbsd_host
*
host
=
dev_id
;
int
isr
;
int
isr
;
isr
=
inb
(
host
->
base
+
WBSD_ISR
);
isr
=
inb
(
host
->
base
+
WBSD_ISR
);
/*
/*
...
@@ -1334,7 +1329,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -1334,7 +1329,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
*/
*/
if
(
isr
==
0xff
||
isr
==
0x00
)
if
(
isr
==
0xff
||
isr
==
0x00
)
return
IRQ_NONE
;
return
IRQ_NONE
;
host
->
isr
|=
isr
;
host
->
isr
|=
isr
;
/*
/*
...
@@ -1352,7 +1347,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -1352,7 +1347,7 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
tasklet_hi_schedule
(
&
host
->
block_tasklet
);
tasklet_hi_schedule
(
&
host
->
block_tasklet
);
if
(
isr
&
WBSD_INT_TC
)
if
(
isr
&
WBSD_INT_TC
)
tasklet_schedule
(
&
host
->
finish_tasklet
);
tasklet_schedule
(
&
host
->
finish_tasklet
);
return
IRQ_HANDLED
;
return
IRQ_HANDLED
;
}
}
...
@@ -1370,14 +1365,14 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
...
@@ -1370,14 +1365,14 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
{
{
struct
mmc_host
*
mmc
;
struct
mmc_host
*
mmc
;
struct
wbsd_host
*
host
;
struct
wbsd_host
*
host
;
/*
/*
* Allocate MMC structure.
* Allocate MMC structure.
*/
*/
mmc
=
mmc_alloc_host
(
sizeof
(
struct
wbsd_host
),
dev
);
mmc
=
mmc_alloc_host
(
sizeof
(
struct
wbsd_host
),
dev
);
if
(
!
mmc
)
if
(
!
mmc
)
return
-
ENOMEM
;
return
-
ENOMEM
;
host
=
mmc_priv
(
mmc
);
host
=
mmc_priv
(
mmc
);
host
->
mmc
=
mmc
;
host
->
mmc
=
mmc
;
...
@@ -1391,37 +1386,37 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
...
@@ -1391,37 +1386,37 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
mmc
->
f_max
=
24000000
;
mmc
->
f_max
=
24000000
;
mmc
->
ocr_avail
=
MMC_VDD_32_33
|
MMC_VDD_33_34
;
mmc
->
ocr_avail
=
MMC_VDD_32_33
|
MMC_VDD_33_34
;
mmc
->
caps
=
MMC_CAP_4_BIT_DATA
;
mmc
->
caps
=
MMC_CAP_4_BIT_DATA
;
spin_lock_init
(
&
host
->
lock
);
spin_lock_init
(
&
host
->
lock
);
/*
/*
* Set up timers
* Set up timers
*/
*/
init_timer
(
&
host
->
ignore_timer
);
init_timer
(
&
host
->
ignore_timer
);
host
->
ignore_timer
.
data
=
(
unsigned
long
)
host
;
host
->
ignore_timer
.
data
=
(
unsigned
long
)
host
;
host
->
ignore_timer
.
function
=
wbsd_reset_ignore
;
host
->
ignore_timer
.
function
=
wbsd_reset_ignore
;
/*
/*
* Maximum number of segments. Worst case is one sector per segment
* Maximum number of segments. Worst case is one sector per segment
* so this will be 64kB/512.
* so this will be 64kB/512.
*/
*/
mmc
->
max_hw_segs
=
128
;
mmc
->
max_hw_segs
=
128
;
mmc
->
max_phys_segs
=
128
;
mmc
->
max_phys_segs
=
128
;
/*
/*
* Maximum number of sectors in one transfer. Also limited by 64kB
* Maximum number of sectors in one transfer. Also limited by 64kB
* buffer.
* buffer.
*/
*/
mmc
->
max_sectors
=
128
;
mmc
->
max_sectors
=
128
;
/*
/*
* Maximum segment size. Could be one segment with the maximum number
* Maximum segment size. Could be one segment with the maximum number
* of segments.
* of segments.
*/
*/
mmc
->
max_seg_size
=
mmc
->
max_sectors
*
512
;
mmc
->
max_seg_size
=
mmc
->
max_sectors
*
512
;
dev_set_drvdata
(
dev
,
mmc
);
dev_set_drvdata
(
dev
,
mmc
);
return
0
;
return
0
;
}
}
...
@@ -1429,18 +1424,18 @@ static void __devexit wbsd_free_mmc(struct device* dev)
...
@@ -1429,18 +1424,18 @@ static void __devexit wbsd_free_mmc(struct device* dev)
{
{
struct
mmc_host
*
mmc
;
struct
mmc_host
*
mmc
;
struct
wbsd_host
*
host
;
struct
wbsd_host
*
host
;
mmc
=
dev_get_drvdata
(
dev
);
mmc
=
dev_get_drvdata
(
dev
);
if
(
!
mmc
)
if
(
!
mmc
)
return
;
return
;
host
=
mmc_priv
(
mmc
);
host
=
mmc_priv
(
mmc
);
BUG_ON
(
host
==
NULL
);
BUG_ON
(
host
==
NULL
);
del_timer_sync
(
&
host
->
ignore_timer
);
del_timer_sync
(
&
host
->
ignore_timer
);
mmc_free_host
(
mmc
);
mmc_free_host
(
mmc
);
dev_set_drvdata
(
dev
,
NULL
);
dev_set_drvdata
(
dev
,
NULL
);
}
}
...
@@ -1452,7 +1447,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
...
@@ -1452,7 +1447,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
{
{
int
i
,
j
,
k
;
int
i
,
j
,
k
;
int
id
;
int
id
;
/*
/*
* Iterate through all ports, all codes to
* Iterate through all ports, all codes to
* find hardware that is in our known list.
* find hardware that is in our known list.
...
@@ -1461,32 +1456,32 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
...
@@ -1461,32 +1456,32 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
{
{
if
(
!
request_region
(
config_ports
[
i
],
2
,
DRIVER_NAME
))
if
(
!
request_region
(
config_ports
[
i
],
2
,
DRIVER_NAME
))
continue
;
continue
;
for
(
j
=
0
;
j
<
sizeof
(
unlock_codes
)
/
sizeof
(
int
);
j
++
)
for
(
j
=
0
;
j
<
sizeof
(
unlock_codes
)
/
sizeof
(
int
);
j
++
)
{
{
id
=
0xFFFF
;
id
=
0xFFFF
;
outb
(
unlock_codes
[
j
],
config_ports
[
i
]);
outb
(
unlock_codes
[
j
],
config_ports
[
i
]);
outb
(
unlock_codes
[
j
],
config_ports
[
i
]);
outb
(
unlock_codes
[
j
],
config_ports
[
i
]);
outb
(
WBSD_CONF_ID_HI
,
config_ports
[
i
]);
outb
(
WBSD_CONF_ID_HI
,
config_ports
[
i
]);
id
=
inb
(
config_ports
[
i
]
+
1
)
<<
8
;
id
=
inb
(
config_ports
[
i
]
+
1
)
<<
8
;
outb
(
WBSD_CONF_ID_LO
,
config_ports
[
i
]);
outb
(
WBSD_CONF_ID_LO
,
config_ports
[
i
]);
id
|=
inb
(
config_ports
[
i
]
+
1
);
id
|=
inb
(
config_ports
[
i
]
+
1
);
for
(
k
=
0
;
k
<
sizeof
(
valid_ids
)
/
sizeof
(
int
);
k
++
)
for
(
k
=
0
;
k
<
sizeof
(
valid_ids
)
/
sizeof
(
int
);
k
++
)
{
{
if
(
id
==
valid_ids
[
k
])
if
(
id
==
valid_ids
[
k
])
{
{
host
->
chip_id
=
id
;
host
->
chip_id
=
id
;
host
->
config
=
config_ports
[
i
];
host
->
config
=
config_ports
[
i
];
host
->
unlock_code
=
unlock_codes
[
i
];
host
->
unlock_code
=
unlock_codes
[
i
];
return
0
;
return
0
;
}
}
}
}
if
(
id
!=
0xFFFF
)
if
(
id
!=
0xFFFF
)
{
{
DBG
(
"Unknown hardware (id %x) found at %x
\n
"
,
DBG
(
"Unknown hardware (id %x) found at %x
\n
"
,
...
@@ -1495,10 +1490,10 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
...
@@ -1495,10 +1490,10 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
outb
(
LOCK_CODE
,
config_ports
[
i
]);
outb
(
LOCK_CODE
,
config_ports
[
i
]);
}
}
release_region
(
config_ports
[
i
],
2
);
release_region
(
config_ports
[
i
],
2
);
}
}
return
-
ENODEV
;
return
-
ENODEV
;
}
}
...
@@ -1510,12 +1505,12 @@ static int __devinit wbsd_request_region(struct wbsd_host* host, int base)
...
@@ -1510,12 +1505,12 @@ static int __devinit wbsd_request_region(struct wbsd_host* host, int base)
{
{
if
(
io
&
0x7
)
if
(
io
&
0x7
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
!
request_region
(
base
,
8
,
DRIVER_NAME
))
if
(
!
request_region
(
base
,
8
,
DRIVER_NAME
))
return
-
EIO
;
return
-
EIO
;
host
->
base
=
io
;
host
->
base
=
io
;
return
0
;
return
0
;
}
}
...
@@ -1523,12 +1518,12 @@ static void __devexit wbsd_release_regions(struct wbsd_host* host)
...
@@ -1523,12 +1518,12 @@ static void __devexit wbsd_release_regions(struct wbsd_host* host)
{
{
if
(
host
->
base
)
if
(
host
->
base
)
release_region
(
host
->
base
,
8
);
release_region
(
host
->
base
,
8
);
host
->
base
=
0
;
host
->
base
=
0
;
if
(
host
->
config
)
if
(
host
->
config
)
release_region
(
host
->
config
,
2
);
release_region
(
host
->
config
,
2
);
host
->
config
=
0
;
host
->
config
=
0
;
}
}
...
@@ -1540,10 +1535,10 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
...
@@ -1540,10 +1535,10 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
{
{
if
(
dma
<
0
)
if
(
dma
<
0
)
return
;
return
;
if
(
request_dma
(
dma
,
DRIVER_NAME
))
if
(
request_dma
(
dma
,
DRIVER_NAME
))
goto
err
;
goto
err
;
/*
/*
* We need to allocate a special buffer in
* We need to allocate a special buffer in
* order for ISA to be able to DMA to it.
* order for ISA to be able to DMA to it.
...
@@ -1558,7 +1553,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
...
@@ -1558,7 +1553,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
*/
*/
host
->
dma_addr
=
dma_map_single
(
host
->
mmc
->
dev
,
host
->
dma_buffer
,
host
->
dma_addr
=
dma_map_single
(
host
->
mmc
->
dev
,
host
->
dma_buffer
,
WBSD_DMA_SIZE
,
DMA_BIDIRECTIONAL
);
WBSD_DMA_SIZE
,
DMA_BIDIRECTIONAL
);
/*
/*
* ISA DMA must be aligned on a 64k basis.
* ISA DMA must be aligned on a 64k basis.
*/
*/
...
@@ -1571,19 +1566,19 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
...
@@ -1571,19 +1566,19 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
goto
kfree
;
goto
kfree
;
host
->
dma
=
dma
;
host
->
dma
=
dma
;
return
;
return
;
kfree:
kfree:
/*
/*
* If we've gotten here then there is some kind of alignment bug
* If we've gotten here then there is some kind of alignment bug
*/
*/
BUG_ON
(
1
);
BUG_ON
(
1
);
dma_unmap_single
(
host
->
mmc
->
dev
,
host
->
dma_addr
,
WBSD_DMA_SIZE
,
dma_unmap_single
(
host
->
mmc
->
dev
,
host
->
dma_addr
,
WBSD_DMA_SIZE
,
DMA_BIDIRECTIONAL
);
DMA_BIDIRECTIONAL
);
host
->
dma_addr
=
(
dma_addr_t
)
NULL
;
host
->
dma_addr
=
(
dma_addr_t
)
NULL
;
kfree
(
host
->
dma_buffer
);
kfree
(
host
->
dma_buffer
);
host
->
dma_buffer
=
NULL
;
host
->
dma_buffer
=
NULL
;
...
@@ -1604,7 +1599,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
...
@@ -1604,7 +1599,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
kfree
(
host
->
dma_buffer
);
kfree
(
host
->
dma_buffer
);
if
(
host
->
dma
>=
0
)
if
(
host
->
dma
>=
0
)
free_dma
(
host
->
dma
);
free_dma
(
host
->
dma
);
host
->
dma
=
-
1
;
host
->
dma
=
-
1
;
host
->
dma_buffer
=
NULL
;
host
->
dma_buffer
=
NULL
;
host
->
dma_addr
=
(
dma_addr_t
)
NULL
;
host
->
dma_addr
=
(
dma_addr_t
)
NULL
;
...
@@ -1617,7 +1612,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
...
@@ -1617,7 +1612,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
static
int
__devinit
wbsd_request_irq
(
struct
wbsd_host
*
host
,
int
irq
)
static
int
__devinit
wbsd_request_irq
(
struct
wbsd_host
*
host
,
int
irq
)
{
{
int
ret
;
int
ret
;
/*
/*
* Allocate interrupt.
* Allocate interrupt.
*/
*/
...
@@ -1625,7 +1620,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
...
@@ -1625,7 +1620,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
ret
=
request_irq
(
irq
,
wbsd_irq
,
SA_SHIRQ
,
DRIVER_NAME
,
host
);
ret
=
request_irq
(
irq
,
wbsd_irq
,
SA_SHIRQ
,
DRIVER_NAME
,
host
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
host
->
irq
=
irq
;
host
->
irq
=
irq
;
/*
/*
...
@@ -1637,7 +1632,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
...
@@ -1637,7 +1632,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
tasklet_init
(
&
host
->
timeout_tasklet
,
wbsd_tasklet_timeout
,
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
timeout_tasklet
,
wbsd_tasklet_timeout
,
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
finish_tasklet
,
wbsd_tasklet_finish
,
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
finish_tasklet
,
wbsd_tasklet_finish
,
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
block_tasklet
,
wbsd_tasklet_block
,
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
block_tasklet
,
wbsd_tasklet_block
,
(
unsigned
long
)
host
);
return
0
;
return
0
;
}
}
...
@@ -1647,9 +1642,9 @@ static void __devexit wbsd_release_irq(struct wbsd_host* host)
...
@@ -1647,9 +1642,9 @@ static void __devexit wbsd_release_irq(struct wbsd_host* host)
return
;
return
;
free_irq
(
host
->
irq
,
host
);
free_irq
(
host
->
irq
,
host
);
host
->
irq
=
0
;
host
->
irq
=
0
;
tasklet_kill
(
&
host
->
card_tasklet
);
tasklet_kill
(
&
host
->
card_tasklet
);
tasklet_kill
(
&
host
->
fifo_tasklet
);
tasklet_kill
(
&
host
->
fifo_tasklet
);
tasklet_kill
(
&
host
->
crc_tasklet
);
tasklet_kill
(
&
host
->
crc_tasklet
);
...
@@ -1666,7 +1661,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host,
...
@@ -1666,7 +1661,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host,
int
base
,
int
irq
,
int
dma
)
int
base
,
int
irq
,
int
dma
)
{
{
int
ret
;
int
ret
;
/*
/*
* Allocate I/O ports.
* Allocate I/O ports.
*/
*/
...
@@ -1685,7 +1680,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host,
...
@@ -1685,7 +1680,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host,
* Allocate DMA.
* Allocate DMA.
*/
*/
wbsd_request_dma
(
host
,
dma
);
wbsd_request_dma
(
host
,
dma
);
return
0
;
return
0
;
}
}
...
@@ -1708,7 +1703,7 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
...
@@ -1708,7 +1703,7 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
{
{
/*
/*
* Reset the chip.
* Reset the chip.
*/
*/
wbsd_write_config
(
host
,
WBSD_CONF_SWRST
,
1
);
wbsd_write_config
(
host
,
WBSD_CONF_SWRST
,
1
);
wbsd_write_config
(
host
,
WBSD_CONF_SWRST
,
0
);
wbsd_write_config
(
host
,
WBSD_CONF_SWRST
,
0
);
...
@@ -1716,23 +1711,23 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
...
@@ -1716,23 +1711,23 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
* Select SD/MMC function.
* Select SD/MMC function.
*/
*/
wbsd_write_config
(
host
,
WBSD_CONF_DEVICE
,
DEVICE_SD
);
wbsd_write_config
(
host
,
WBSD_CONF_DEVICE
,
DEVICE_SD
);
/*
/*
* Set up card detection.
* Set up card detection.
*/
*/
wbsd_write_config
(
host
,
WBSD_CONF_PINS
,
WBSD_PINS_DETECT_GP11
);
wbsd_write_config
(
host
,
WBSD_CONF_PINS
,
WBSD_PINS_DETECT_GP11
);
/*
/*
* Configure chip
* Configure chip
*/
*/
wbsd_write_config
(
host
,
WBSD_CONF_PORT_HI
,
host
->
base
>>
8
);
wbsd_write_config
(
host
,
WBSD_CONF_PORT_HI
,
host
->
base
>>
8
);
wbsd_write_config
(
host
,
WBSD_CONF_PORT_LO
,
host
->
base
&
0xff
);
wbsd_write_config
(
host
,
WBSD_CONF_PORT_LO
,
host
->
base
&
0xff
);
wbsd_write_config
(
host
,
WBSD_CONF_IRQ
,
host
->
irq
);
wbsd_write_config
(
host
,
WBSD_CONF_IRQ
,
host
->
irq
);
if
(
host
->
dma
>=
0
)
if
(
host
->
dma
>=
0
)
wbsd_write_config
(
host
,
WBSD_CONF_DRQ
,
host
->
dma
);
wbsd_write_config
(
host
,
WBSD_CONF_DRQ
,
host
->
dma
);
/*
/*
* Enable and power up chip.
* Enable and power up chip.
*/
*/
...
@@ -1743,26 +1738,26 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
...
@@ -1743,26 +1738,26 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
/*
/*
* Check that configured resources are correct.
* Check that configured resources are correct.
*/
*/
static
int
__devinit
wbsd_chip_validate
(
struct
wbsd_host
*
host
)
static
int
__devinit
wbsd_chip_validate
(
struct
wbsd_host
*
host
)
{
{
int
base
,
irq
,
dma
;
int
base
,
irq
,
dma
;
/*
/*
* Select SD/MMC function.
* Select SD/MMC function.
*/
*/
wbsd_write_config
(
host
,
WBSD_CONF_DEVICE
,
DEVICE_SD
);
wbsd_write_config
(
host
,
WBSD_CONF_DEVICE
,
DEVICE_SD
);
/*
/*
* Read configuration.
* Read configuration.
*/
*/
base
=
wbsd_read_config
(
host
,
WBSD_CONF_PORT_HI
)
<<
8
;
base
=
wbsd_read_config
(
host
,
WBSD_CONF_PORT_HI
)
<<
8
;
base
|=
wbsd_read_config
(
host
,
WBSD_CONF_PORT_LO
);
base
|=
wbsd_read_config
(
host
,
WBSD_CONF_PORT_LO
);
irq
=
wbsd_read_config
(
host
,
WBSD_CONF_IRQ
);
irq
=
wbsd_read_config
(
host
,
WBSD_CONF_IRQ
);
dma
=
wbsd_read_config
(
host
,
WBSD_CONF_DRQ
);
dma
=
wbsd_read_config
(
host
,
WBSD_CONF_DRQ
);
/*
/*
* Validate against given configuration.
* Validate against given configuration.
*/
*/
...
@@ -1772,7 +1767,7 @@ static int __devinit wbsd_chip_validate(struct wbsd_host* host)
...
@@ -1772,7 +1767,7 @@ static int __devinit wbsd_chip_validate(struct wbsd_host* host)
return
0
;
return
0
;
if
((
dma
!=
host
->
dma
)
&&
(
host
->
dma
!=
-
1
))
if
((
dma
!=
host
->
dma
)
&&
(
host
->
dma
!=
-
1
))
return
0
;
return
0
;
return
1
;
return
1
;
}
}
...
@@ -1788,14 +1783,14 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
...
@@ -1788,14 +1783,14 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
struct
wbsd_host
*
host
=
NULL
;
struct
wbsd_host
*
host
=
NULL
;
struct
mmc_host
*
mmc
=
NULL
;
struct
mmc_host
*
mmc
=
NULL
;
int
ret
;
int
ret
;
ret
=
wbsd_alloc_mmc
(
dev
);
ret
=
wbsd_alloc_mmc
(
dev
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
mmc
=
dev_get_drvdata
(
dev
);
mmc
=
dev_get_drvdata
(
dev
);
host
=
mmc_priv
(
mmc
);
host
=
mmc_priv
(
mmc
);
/*
/*
* Scan for hardware.
* Scan for hardware.
*/
*/
...
@@ -1814,7 +1809,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
...
@@ -1814,7 +1809,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
return
ret
;
return
ret
;
}
}
}
}
/*
/*
* Request resources.
* Request resources.
*/
*/
...
@@ -1825,7 +1820,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
...
@@ -1825,7 +1820,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
wbsd_free_mmc
(
dev
);
wbsd_free_mmc
(
dev
);
return
ret
;
return
ret
;
}
}
/*
/*
* See if chip needs to be configured.
* See if chip needs to be configured.
*/
*/
...
@@ -1842,7 +1837,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
...
@@ -1842,7 +1837,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
}
}
else
else
wbsd_chip_config
(
host
);
wbsd_chip_config
(
host
);
/*
/*
* Power Management stuff. No idea how this works.
* Power Management stuff. No idea how this works.
* Not tested.
* Not tested.
...
@@ -1860,7 +1855,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
...
@@ -1860,7 +1855,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
* Reset the chip into a known state.
* Reset the chip into a known state.
*/
*/
wbsd_init_device
(
host
);
wbsd_init_device
(
host
);
mmc_add_host
(
mmc
);
mmc_add_host
(
mmc
);
printk
(
KERN_INFO
"%s: W83L51xD"
,
mmc_hostname
(
mmc
));
printk
(
KERN_INFO
"%s: W83L51xD"
,
mmc_hostname
(
mmc
));
...
@@ -1882,12 +1877,12 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
...
@@ -1882,12 +1877,12 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
{
{
struct
mmc_host
*
mmc
=
dev_get_drvdata
(
dev
);
struct
mmc_host
*
mmc
=
dev_get_drvdata
(
dev
);
struct
wbsd_host
*
host
;
struct
wbsd_host
*
host
;
if
(
!
mmc
)
if
(
!
mmc
)
return
;
return
;
host
=
mmc_priv
(
mmc
);
host
=
mmc_priv
(
mmc
);
mmc_remove_host
(
mmc
);
mmc_remove_host
(
mmc
);
if
(
!
pnp
)
if
(
!
pnp
)
...
@@ -1900,9 +1895,9 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
...
@@ -1900,9 +1895,9 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
wbsd_write_config
(
host
,
WBSD_CONF_ENABLE
,
0
);
wbsd_write_config
(
host
,
WBSD_CONF_ENABLE
,
0
);
wbsd_lock_config
(
host
);
wbsd_lock_config
(
host
);
}
}
wbsd_release_resources
(
host
);
wbsd_release_resources
(
host
);
wbsd_free_mmc
(
dev
);
wbsd_free_mmc
(
dev
);
}
}
...
@@ -1932,7 +1927,7 @@ static int __devinit
...
@@ -1932,7 +1927,7 @@ static int __devinit
wbsd_pnp_probe
(
struct
pnp_dev
*
pnpdev
,
const
struct
pnp_device_id
*
dev_id
)
wbsd_pnp_probe
(
struct
pnp_dev
*
pnpdev
,
const
struct
pnp_device_id
*
dev_id
)
{
{
int
io
,
irq
,
dma
;
int
io
,
irq
,
dma
;
/*
/*
* Get resources from PnP layer.
* Get resources from PnP layer.
*/
*/
...
@@ -1942,9 +1937,9 @@ wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id)
...
@@ -1942,9 +1937,9 @@ wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id)
dma
=
pnp_dma
(
pnpdev
,
0
);
dma
=
pnp_dma
(
pnpdev
,
0
);
else
else
dma
=
-
1
;
dma
=
-
1
;
DBGF
(
"PnP resources: port %3x irq %d dma %d
\n
"
,
io
,
irq
,
dma
);
DBGF
(
"PnP resources: port %3x irq %d dma %d
\n
"
,
io
,
irq
,
dma
);
return
wbsd_init
(
&
pnpdev
->
dev
,
io
,
irq
,
dma
,
1
);
return
wbsd_init
(
&
pnpdev
->
dev
,
io
,
irq
,
dma
,
1
);
}
}
...
@@ -1985,7 +1980,7 @@ static struct device_driver wbsd_driver = {
...
@@ -1985,7 +1980,7 @@ static struct device_driver wbsd_driver = {
.
bus
=
&
platform_bus_type
,
.
bus
=
&
platform_bus_type
,
.
probe
=
wbsd_probe
,
.
probe
=
wbsd_probe
,
.
remove
=
wbsd_remove
,
.
remove
=
wbsd_remove
,
.
suspend
=
wbsd_suspend
,
.
suspend
=
wbsd_suspend
,
.
resume
=
wbsd_resume
,
.
resume
=
wbsd_resume
,
};
};
...
@@ -2008,7 +2003,7 @@ static struct pnp_driver wbsd_pnp_driver = {
...
@@ -2008,7 +2003,7 @@ static struct pnp_driver wbsd_pnp_driver = {
static
int
__init
wbsd_drv_init
(
void
)
static
int
__init
wbsd_drv_init
(
void
)
{
{
int
result
;
int
result
;
printk
(
KERN_INFO
DRIVER_NAME
printk
(
KERN_INFO
DRIVER_NAME
": Winbond W83L51xD SD/MMC card interface driver, "
": Winbond W83L51xD SD/MMC card interface driver, "
DRIVER_VERSION
"
\n
"
);
DRIVER_VERSION
"
\n
"
);
...
@@ -2023,8 +2018,8 @@ static int __init wbsd_drv_init(void)
...
@@ -2023,8 +2018,8 @@ static int __init wbsd_drv_init(void)
return
result
;
return
result
;
}
}
#endif
/* CONFIG_PNP */
#endif
/* CONFIG_PNP */
if
(
nopnp
)
if
(
nopnp
)
{
{
result
=
driver_register
(
&
wbsd_driver
);
result
=
driver_register
(
&
wbsd_driver
);
...
@@ -2046,13 +2041,13 @@ static void __exit wbsd_drv_exit(void)
...
@@ -2046,13 +2041,13 @@ static void __exit wbsd_drv_exit(void)
if
(
!
nopnp
)
if
(
!
nopnp
)
pnp_unregister_driver
(
&
wbsd_pnp_driver
);
pnp_unregister_driver
(
&
wbsd_pnp_driver
);
#endif
/* CONFIG_PNP */
#endif
/* CONFIG_PNP */
if
(
nopnp
)
if
(
nopnp
)
{
{
platform_device_unregister
(
wbsd_device
);
platform_device_unregister
(
wbsd_device
);
driver_unregister
(
&
wbsd_driver
);
driver_unregister
(
&
wbsd_driver
);
}
}
...
...
drivers/mmc/wbsd.h
View file @
bd6fe9e1
...
@@ -139,51 +139,50 @@
...
@@ -139,51 +139,50 @@
struct
wbsd_host
struct
wbsd_host
{
{
struct
mmc_host
*
mmc
;
/* MMC structure */
struct
mmc_host
*
mmc
;
/* MMC structure */
spinlock_t
lock
;
/* Mutex */
spinlock_t
lock
;
/* Mutex */
int
flags
;
/* Driver states */
int
flags
;
/* Driver states */
#define WBSD_FCARD_PRESENT (1<<0)
/* Card is present */
#define WBSD_FCARD_PRESENT (1<<0)
/* Card is present */
#define WBSD_FIGNORE_DETECT (1<<1)
/* Ignore card detection */
#define WBSD_FIGNORE_DETECT (1<<1)
/* Ignore card detection */
struct
mmc_request
*
mrq
;
/* Current request */
struct
mmc_request
*
mrq
;
/* Current request */
u8
isr
;
/* Accumulated ISR */
u8
isr
;
/* Accumulated ISR */
struct
scatterlist
*
cur_sg
;
/* Current SG entry */
struct
scatterlist
*
cur_sg
;
/* Current SG entry */
unsigned
int
num_sg
;
/* Number of entries left */
unsigned
int
num_sg
;
/* Number of entries left */
void
*
mapped_sg
;
/* vaddr of mapped sg */
void
*
mapped_sg
;
/* vaddr of mapped sg */
unsigned
int
offset
;
/* Offset into current entry */
unsigned
int
offset
;
/* Offset into current entry */
unsigned
int
remain
;
/* Data left in curren entry */
unsigned
int
remain
;
/* Data left in curren entry */
int
size
;
/* Total size of transfer */
int
size
;
/* Total size of transfer */
char
*
dma_buffer
;
/* ISA DMA buffer */
char
*
dma_buffer
;
/* ISA DMA buffer */
dma_addr_t
dma_addr
;
/* Physical address for same */
dma_addr_t
dma_addr
;
/* Physical address for same */
int
firsterr
;
/* See fifo functions */
int
firsterr
;
/* See fifo functions */
u8
clk
;
/* Current clock speed */
u8
clk
;
/* Current clock speed */
unsigned
char
bus_width
;
/* Current bus width */
unsigned
char
bus_width
;
/* Current bus width */
int
config
;
/* Config port */
int
config
;
/* Config port */
u8
unlock_code
;
/* Code to unlock config */
u8
unlock_code
;
/* Code to unlock config */
int
chip_id
;
/* ID of controller */
int
chip_id
;
/* ID of controller */
int
base
;
/* I/O port base */
int
base
;
/* I/O port base */
int
irq
;
/* Interrupt */
int
irq
;
/* Interrupt */
int
dma
;
/* DMA channel */
int
dma
;
/* DMA channel */
struct
tasklet_struct
card_tasklet
;
/* Tasklet structures */
struct
tasklet_struct
card_tasklet
;
/* Tasklet structures */
struct
tasklet_struct
fifo_tasklet
;
struct
tasklet_struct
fifo_tasklet
;
struct
tasklet_struct
crc_tasklet
;
struct
tasklet_struct
crc_tasklet
;
struct
tasklet_struct
timeout_tasklet
;
struct
tasklet_struct
timeout_tasklet
;
struct
tasklet_struct
finish_tasklet
;
struct
tasklet_struct
finish_tasklet
;
struct
tasklet_struct
block_tasklet
;
struct
tasklet_struct
block_tasklet
;
struct
timer_list
detect_timer
;
/* Card detection timer */
struct
timer_list
ignore_timer
;
/* Ignore detection timer */
struct
timer_list
ignore_timer
;
/* Ignore detection timer */
};
};
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