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
0305c865
Commit
0305c865
authored
May 24, 2006
by
David Woodhouse
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.infradead.org/~gleixner/mtd-nand-2.6.git
parents
99988f7b
d470a97c
Changes
32
Show whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
666 additions
and
1515 deletions
+666
-1515
drivers/mtd/devices/doc2000.c
drivers/mtd/devices/doc2000.c
+0
-66
drivers/mtd/devices/doc2001.c
drivers/mtd/devices/doc2001.c
+0
-2
drivers/mtd/devices/doc2001plus.c
drivers/mtd/devices/doc2001plus.c
+0
-2
drivers/mtd/inftlcore.c
drivers/mtd/inftlcore.c
+32
-31
drivers/mtd/inftlmount.c
drivers/mtd/inftlmount.c
+6
-6
drivers/mtd/mtdconcat.c
drivers/mtd/mtdconcat.c
+2
-134
drivers/mtd/mtdpart.c
drivers/mtd/mtdpart.c
+6
-100
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Kconfig
+2
-2
drivers/mtd/nand/ams-delta.c
drivers/mtd/nand/ams-delta.c
+28
-29
drivers/mtd/nand/au1550nd.c
drivers/mtd/nand/au1550nd.c
+26
-30
drivers/mtd/nand/autcpu12.c
drivers/mtd/nand/autcpu12.c
+48
-29
drivers/mtd/nand/cs553x_nand.c
drivers/mtd/nand/cs553x_nand.c
+8
-25
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/diskonchip.c
+34
-52
drivers/mtd/nand/edb7312.c
drivers/mtd/nand/edb7312.c
+18
-24
drivers/mtd/nand/h1910.c
drivers/mtd/nand/h1910.c
+11
-29
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_base.c
+121
-359
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_bbt.c
+62
-42
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/nandsim.c
+13
-76
drivers/mtd/nand/ndfc.c
drivers/mtd/nand/ndfc.c
+9
-14
drivers/mtd/nand/ppchameleonevb.c
drivers/mtd/nand/ppchameleonevb.c
+58
-44
drivers/mtd/nand/rtc_from4.c
drivers/mtd/nand/rtc_from4.c
+10
-24
drivers/mtd/nand/s3c2410.c
drivers/mtd/nand/s3c2410.c
+20
-44
drivers/mtd/nand/sharpsl.c
drivers/mtd/nand/sharpsl.c
+18
-23
drivers/mtd/nand/spia.c
drivers/mtd/nand/spia.c
+17
-10
drivers/mtd/nand/toto.c
drivers/mtd/nand/toto.c
+33
-32
drivers/mtd/nand/ts7250.c
drivers/mtd/nand/ts7250.c
+21
-23
drivers/mtd/nftlcore.c
drivers/mtd/nftlcore.c
+8
-7
drivers/mtd/nftlmount.c
drivers/mtd/nftlmount.c
+8
-4
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/onenand_base.c
+17
-200
fs/jffs2/wbuf.c
fs/jffs2/wbuf.c
+8
-20
include/linux/mtd/mtd.h
include/linux/mtd/mtd.h
+1
-10
include/linux/mtd/nand.h
include/linux/mtd/nand.h
+21
-22
No files found.
drivers/mtd/devices/doc2000.c
View file @
0305c865
...
...
@@ -59,9 +59,6 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
size_t
*
retlen
,
u_char
*
buf
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
);
static
int
doc_write_ecc
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
);
static
int
doc_writev_ecc
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
);
static
int
doc_read_oob
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
static
int
doc_write_oob
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
size_t
len
,
...
...
@@ -587,9 +584,6 @@ void DoC2k_init(struct mtd_info *mtd)
mtd
->
unpoint
=
NULL
;
mtd
->
read
=
doc_read
;
mtd
->
write
=
doc_write
;
mtd
->
read_ecc
=
doc_read_ecc
;
mtd
->
write_ecc
=
doc_write_ecc
;
mtd
->
writev_ecc
=
doc_writev_ecc
;
mtd
->
read_oob
=
doc_read_oob
;
mtd
->
write_oob
=
doc_write_oob
;
mtd
->
sync
=
NULL
;
...
...
@@ -965,66 +959,6 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
return
0
;
}
static
int
doc_writev_ecc
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
{
static
char
static_buf
[
512
];
static
DEFINE_MUTEX
(
writev_buf_mutex
);
size_t
totretlen
=
0
;
size_t
thisvecofs
=
0
;
int
ret
=
0
;
mutex_lock
(
&
writev_buf_mutex
);
while
(
count
)
{
size_t
thislen
,
thisretlen
;
unsigned
char
*
buf
;
buf
=
vecs
->
iov_base
+
thisvecofs
;
thislen
=
vecs
->
iov_len
-
thisvecofs
;
if
(
thislen
>=
512
)
{
thislen
=
thislen
&
~
(
512
-
1
);
thisvecofs
+=
thislen
;
}
else
{
/* Not enough to fill a page. Copy into buf */
memcpy
(
static_buf
,
buf
,
thislen
);
buf
=
&
static_buf
[
thislen
];
while
(
count
&&
thislen
<
512
)
{
vecs
++
;
count
--
;
thisvecofs
=
min
((
512
-
thislen
),
vecs
->
iov_len
);
memcpy
(
buf
,
vecs
->
iov_base
,
thisvecofs
);
thislen
+=
thisvecofs
;
buf
+=
thisvecofs
;
}
buf
=
static_buf
;
}
if
(
count
&&
thisvecofs
==
vecs
->
iov_len
)
{
thisvecofs
=
0
;
vecs
++
;
count
--
;
}
ret
=
doc_write_ecc
(
mtd
,
to
,
thislen
,
&
thisretlen
,
buf
,
eccbuf
,
oobsel
);
totretlen
+=
thisretlen
;
if
(
ret
||
thisretlen
!=
thislen
)
break
;
to
+=
thislen
;
}
mutex_unlock
(
&
writev_buf_mutex
);
*
retlen
=
totretlen
;
return
ret
;
}
static
int
doc_read_oob
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
)
{
...
...
drivers/mtd/devices/doc2001.c
View file @
0305c865
...
...
@@ -369,8 +369,6 @@ void DoCMil_init(struct mtd_info *mtd)
mtd
->
unpoint
=
NULL
;
mtd
->
read
=
doc_read
;
mtd
->
write
=
doc_write
;
mtd
->
read_ecc
=
doc_read_ecc
;
mtd
->
write_ecc
=
doc_write_ecc
;
mtd
->
read_oob
=
doc_read_oob
;
mtd
->
write_oob
=
doc_write_oob
;
mtd
->
sync
=
NULL
;
...
...
drivers/mtd/devices/doc2001plus.c
View file @
0305c865
...
...
@@ -491,8 +491,6 @@ void DoCMilPlus_init(struct mtd_info *mtd)
mtd
->
unpoint
=
NULL
;
mtd
->
read
=
doc_read
;
mtd
->
write
=
doc_write
;
mtd
->
read_ecc
=
doc_read_ecc
;
mtd
->
write_ecc
=
doc_write_ecc
;
mtd
->
read_oob
=
doc_read_oob
;
mtd
->
write_oob
=
doc_write_oob
;
mtd
->
sync
=
NULL
;
...
...
drivers/mtd/inftlcore.c
View file @
0305c865
...
...
@@ -36,6 +36,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nftl.h>
#include <linux/mtd/inftl.h>
#include <linux/mtd/nand.h>
#include <asm/uaccess.h>
#include <asm/errno.h>
#include <asm/io.h>
...
...
@@ -79,8 +80,6 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
inftl
->
mbd
.
devnum
=
-
1
;
inftl
->
mbd
.
blksize
=
512
;
inftl
->
mbd
.
tr
=
tr
;
memcpy
(
&
inftl
->
oobinfo
,
&
mtd
->
oobinfo
,
sizeof
(
struct
nand_oobinfo
));
inftl
->
oobinfo
.
useecc
=
MTD_NANDECC_PLACEONLY
;
if
(
INFTL_mount
(
inftl
)
<
0
)
{
printk
(
KERN_WARNING
"INFTL: could not mount device
\n
"
);
...
...
@@ -302,9 +301,10 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
}
memset
(
&
oob
,
0xff
,
sizeof
(
struct
inftl_oob
));
oob
.
b
.
Status
=
oob
.
b
.
Status1
=
SECTOR_USED
;
MTD_WRITEECC
(
inftl
->
mbd
.
mtd
,
(
inftl
->
EraseSize
*
targetEUN
)
+
nand_write_raw
(
inftl
->
mbd
.
mtd
,
(
inftl
->
EraseSize
*
targetEUN
)
+
(
block
*
SECTORSIZE
),
SECTORSIZE
,
&
retlen
,
movebuf
,
(
char
*
)
&
oob
,
&
inftl
->
oobinfo
);
movebuf
,
(
char
*
)
&
oob
);
}
/*
...
...
@@ -784,9 +784,10 @@ static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
memset
(
&
oob
,
0xff
,
sizeof
(
struct
inftl_oob
));
oob
.
b
.
Status
=
oob
.
b
.
Status1
=
SECTOR_USED
;
MTD_WRITEECC
(
inftl
->
mbd
.
mtd
,
(
writeEUN
*
inftl
->
EraseSize
)
+
nand_write_raw
(
inftl
->
mbd
.
mtd
,
(
writeEUN
*
inftl
->
EraseSize
)
+
blockofs
,
SECTORSIZE
,
&
retlen
,
(
char
*
)
buffer
,
(
char
*
)
&
oob
,
&
inftl
->
oobinfo
);
(
char
*
)
&
oob
);
/*
* need to write SECTOR_USED flags since they are not written
* in mtd_writeecc
...
...
drivers/mtd/inftlmount.c
View file @
0305c865
...
...
@@ -350,21 +350,21 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
int
len
,
int
check_oob
)
{
u8
buf
[
SECTORSIZE
+
inftl
->
mbd
.
mtd
->
oobsize
];
struct
mtd_info
*
mtd
=
inftl
->
mbd
.
mtd
;
size_t
retlen
;
int
i
;
DEBUG
(
MTD_DEBUG_LEVEL3
,
"INFTL: check_free_sectors(inftl=%p,"
"address=0x%x,len=%d,check_oob=%d)
\n
"
,
inftl
,
address
,
len
,
check_oob
);
for
(
i
=
0
;
i
<
len
;
i
+=
SECTORSIZE
)
{
if
(
MTD_READECC
(
inftl
->
mbd
.
mtd
,
address
,
SECTORSIZE
,
&
retlen
,
buf
,
&
buf
[
SECTORSIZE
],
&
inftl
->
oobinfo
)
<
0
)
if
(
mtd
->
read
(
mtd
,
address
,
SECTORSIZE
,
&
retlen
,
buf
)
)
return
-
1
;
if
(
memcmpb
(
buf
,
0xff
,
SECTORSIZE
)
!=
0
)
return
-
1
;
if
(
check_oob
)
{
if
(
memcmpb
(
buf
+
SECTORSIZE
,
0xff
,
inftl
->
mbd
.
mtd
->
oobsize
)
!=
0
)
if
(
mtd
->
read_oob
(
mtd
,
address
,
mtd
->
oobsize
,
&
retlen
,
&
buf
[
SECTORSIZE
])
<
0
)
return
-
1
;
if
(
memcmpb
(
buf
+
SECTORSIZE
,
0xff
,
mtd
->
oobsize
)
!=
0
)
return
-
1
;
}
address
+=
SECTORSIZE
;
...
...
drivers/mtd/mtdconcat.c
View file @
0305c865
...
...
@@ -143,119 +143,8 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
}
static
int
concat_read_ecc
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
{
struct
mtd_concat
*
concat
=
CONCAT
(
mtd
);
int
err
=
-
EINVAL
;
int
i
;
*
retlen
=
0
;
for
(
i
=
0
;
i
<
concat
->
num_subdev
;
i
++
)
{
struct
mtd_info
*
subdev
=
concat
->
subdev
[
i
];
size_t
size
,
retsize
;
if
(
from
>=
subdev
->
size
)
{
/* Not destined for this subdev */
size
=
0
;
from
-=
subdev
->
size
;
continue
;
}
if
(
from
+
len
>
subdev
->
size
)
/* First part goes into this subdev */
size
=
subdev
->
size
-
from
;
else
/* Entire transaction goes into this subdev */
size
=
len
;
if
(
subdev
->
read_ecc
)
err
=
subdev
->
read_ecc
(
subdev
,
from
,
size
,
&
retsize
,
buf
,
eccbuf
,
oobsel
);
else
err
=
-
EINVAL
;
if
(
err
)
break
;
*
retlen
+=
retsize
;
len
-=
size
;
if
(
len
==
0
)
break
;
err
=
-
EINVAL
;
buf
+=
size
;
if
(
eccbuf
)
{
eccbuf
+=
subdev
->
oobsize
;
/* in nand.c at least, eccbufs are
tagged with 2 (int)eccstatus'; we
must account for these */
eccbuf
+=
2
*
(
sizeof
(
int
));
}
from
=
0
;
}
return
err
;
}
static
int
concat_write_ecc
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
{
struct
mtd_concat
*
concat
=
CONCAT
(
mtd
);
int
err
=
-
EINVAL
;
int
i
;
if
(
!
(
mtd
->
flags
&
MTD_WRITEABLE
))
return
-
EROFS
;
*
retlen
=
0
;
for
(
i
=
0
;
i
<
concat
->
num_subdev
;
i
++
)
{
struct
mtd_info
*
subdev
=
concat
->
subdev
[
i
];
size_t
size
,
retsize
;
if
(
to
>=
subdev
->
size
)
{
size
=
0
;
to
-=
subdev
->
size
;
continue
;
}
if
(
to
+
len
>
subdev
->
size
)
size
=
subdev
->
size
-
to
;
else
size
=
len
;
if
(
!
(
subdev
->
flags
&
MTD_WRITEABLE
))
err
=
-
EROFS
;
else
if
(
subdev
->
write_ecc
)
err
=
subdev
->
write_ecc
(
subdev
,
to
,
size
,
&
retsize
,
buf
,
eccbuf
,
oobsel
);
else
err
=
-
EINVAL
;
if
(
err
)
break
;
*
retlen
+=
retsize
;
len
-=
size
;
if
(
len
==
0
)
break
;
err
=
-
EINVAL
;
buf
+=
size
;
if
(
eccbuf
)
eccbuf
+=
subdev
->
oobsize
;
to
=
0
;
}
return
err
;
}
static
int
concat_writev_ecc
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
concat_writev
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
)
{
struct
mtd_concat
*
concat
=
CONCAT
(
mtd
);
struct
kvec
*
vecs_copy
;
...
...
@@ -315,10 +204,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
if
(
!
(
subdev
->
flags
&
MTD_WRITEABLE
))
err
=
-
EROFS
;
else
if
(
eccbuf
)
err
=
subdev
->
writev_ecc
(
subdev
,
&
vecs_copy
[
entry_low
],
entry_high
-
entry_low
+
1
,
to
,
&
retsize
,
eccbuf
,
oobsel
);
else
err
=
subdev
->
writev
(
subdev
,
&
vecs_copy
[
entry_low
],
entry_high
-
entry_low
+
1
,
to
,
&
retsize
);
...
...
@@ -333,8 +218,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
*
retlen
+=
retsize
;
total_len
-=
wsize
;
if
(
concat
->
mtd
.
type
==
MTD_NANDFLASH
&&
eccbuf
)
eccbuf
+=
mtd
->
oobavail
*
(
wsize
/
mtd
->
writesize
);
if
(
total_len
==
0
)
break
;
...
...
@@ -347,13 +230,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
return
err
;
}
static
int
concat_writev
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
)
{
return
concat_writev_ecc
(
mtd
,
vecs
,
count
,
to
,
retlen
,
NULL
,
NULL
);
}
static
int
concat_read_oob
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
)
...
...
@@ -837,14 +713,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat
->
mtd
.
oobsize
=
subdev
[
0
]
->
oobsize
;
concat
->
mtd
.
ecctype
=
subdev
[
0
]
->
ecctype
;
concat
->
mtd
.
eccsize
=
subdev
[
0
]
->
eccsize
;
if
(
subdev
[
0
]
->
read_ecc
)
concat
->
mtd
.
read_ecc
=
concat_read_ecc
;
if
(
subdev
[
0
]
->
write_ecc
)
concat
->
mtd
.
write_ecc
=
concat_write_ecc
;
if
(
subdev
[
0
]
->
writev
)
concat
->
mtd
.
writev
=
concat_writev
;
if
(
subdev
[
0
]
->
writev_ecc
)
concat
->
mtd
.
writev_ecc
=
concat_writev_ecc
;
if
(
subdev
[
0
]
->
read_oob
)
concat
->
mtd
.
read_oob
=
concat_read_oob
;
if
(
subdev
[
0
]
->
write_oob
)
...
...
@@ -885,8 +755,6 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat
->
mtd
.
oobsize
!=
subdev
[
i
]
->
oobsize
||
concat
->
mtd
.
ecctype
!=
subdev
[
i
]
->
ecctype
||
concat
->
mtd
.
eccsize
!=
subdev
[
i
]
->
eccsize
||
!
concat
->
mtd
.
read_ecc
!=
!
subdev
[
i
]
->
read_ecc
||
!
concat
->
mtd
.
write_ecc
!=
!
subdev
[
i
]
->
write_ecc
||
!
concat
->
mtd
.
read_oob
!=
!
subdev
[
i
]
->
read_oob
||
!
concat
->
mtd
.
write_oob
!=
!
subdev
[
i
]
->
write_oob
)
{
kfree
(
concat
);
...
...
drivers/mtd/mtdpart.c
View file @
0305c865
...
...
@@ -55,12 +55,8 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
len
=
0
;
else
if
(
from
+
len
>
mtd
->
size
)
len
=
mtd
->
size
-
from
;
if
(
part
->
master
->
read_ecc
==
NULL
)
return
part
->
master
->
read
(
part
->
master
,
from
+
part
->
offset
,
len
,
retlen
,
buf
);
else
return
part
->
master
->
read_ecc
(
part
->
master
,
from
+
part
->
offset
,
len
,
retlen
,
buf
,
NULL
,
&
mtd
->
oobinfo
);
}
static
int
part_point
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
...
...
@@ -74,6 +70,7 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
return
part
->
master
->
point
(
part
->
master
,
from
+
part
->
offset
,
len
,
retlen
,
buf
);
}
static
void
part_unpoint
(
struct
mtd_info
*
mtd
,
u_char
*
addr
,
loff_t
from
,
size_t
len
)
{
struct
mtd_part
*
part
=
PART
(
mtd
);
...
...
@@ -81,21 +78,6 @@ static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_
part
->
master
->
unpoint
(
part
->
master
,
addr
,
from
+
part
->
offset
,
len
);
}
static
int
part_read_ecc
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
{
struct
mtd_part
*
part
=
PART
(
mtd
);
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
if
(
from
>=
mtd
->
size
)
len
=
0
;
else
if
(
from
+
len
>
mtd
->
size
)
len
=
mtd
->
size
-
from
;
return
part
->
master
->
read_ecc
(
part
->
master
,
from
+
part
->
offset
,
len
,
retlen
,
buf
,
eccbuf
,
oobsel
);
}
static
int
part_read_oob
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
)
{
...
...
@@ -148,30 +130,8 @@ static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
len
=
0
;
else
if
(
to
+
len
>
mtd
->
size
)
len
=
mtd
->
size
-
to
;
if
(
part
->
master
->
write_ecc
==
NULL
)
return
part
->
master
->
write
(
part
->
master
,
to
+
part
->
offset
,
len
,
retlen
,
buf
);
else
return
part
->
master
->
write_ecc
(
part
->
master
,
to
+
part
->
offset
,
len
,
retlen
,
buf
,
NULL
,
&
mtd
->
oobinfo
);
}
static
int
part_write_ecc
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
{
struct
mtd_part
*
part
=
PART
(
mtd
);
if
(
!
(
mtd
->
flags
&
MTD_WRITEABLE
))
return
-
EROFS
;
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
if
(
to
>=
mtd
->
size
)
len
=
0
;
else
if
(
to
+
len
>
mtd
->
size
)
len
=
mtd
->
size
-
to
;
return
part
->
master
->
write_ecc
(
part
->
master
,
to
+
part
->
offset
,
len
,
retlen
,
buf
,
eccbuf
,
oobsel
);
}
static
int
part_write_oob
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
...
...
@@ -208,52 +168,8 @@ static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
struct
mtd_part
*
part
=
PART
(
mtd
);
if
(
!
(
mtd
->
flags
&
MTD_WRITEABLE
))
return
-
EROFS
;
if
(
part
->
master
->
writev_ecc
==
NULL
)
return
part
->
master
->
writev
(
part
->
master
,
vecs
,
count
,
to
+
part
->
offset
,
retlen
);
else
return
part
->
master
->
writev_ecc
(
part
->
master
,
vecs
,
count
,
to
+
part
->
offset
,
retlen
,
NULL
,
&
mtd
->
oobinfo
);
}
static
int
part_readv
(
struct
mtd_info
*
mtd
,
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
from
,
size_t
*
retlen
)
{
struct
mtd_part
*
part
=
PART
(
mtd
);
if
(
part
->
master
->
readv_ecc
==
NULL
)
return
part
->
master
->
readv
(
part
->
master
,
vecs
,
count
,
from
+
part
->
offset
,
retlen
);
else
return
part
->
master
->
readv_ecc
(
part
->
master
,
vecs
,
count
,
from
+
part
->
offset
,
retlen
,
NULL
,
&
mtd
->
oobinfo
);
}
static
int
part_writev_ecc
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
{
struct
mtd_part
*
part
=
PART
(
mtd
);
if
(
!
(
mtd
->
flags
&
MTD_WRITEABLE
))
return
-
EROFS
;
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
return
part
->
master
->
writev_ecc
(
part
->
master
,
vecs
,
count
,
to
+
part
->
offset
,
retlen
,
eccbuf
,
oobsel
);
}
static
int
part_readv_ecc
(
struct
mtd_info
*
mtd
,
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
from
,
size_t
*
retlen
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
{
struct
mtd_part
*
part
=
PART
(
mtd
);
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
return
part
->
master
->
readv_ecc
(
part
->
master
,
vecs
,
count
,
from
+
part
->
offset
,
retlen
,
eccbuf
,
oobsel
);
}
static
int
part_erase
(
struct
mtd_info
*
mtd
,
struct
erase_info
*
instr
)
...
...
@@ -416,10 +332,6 @@ int add_mtd_partitions(struct mtd_info *master,
slave
->
mtd
.
unpoint
=
part_unpoint
;
}
if
(
master
->
read_ecc
)
slave
->
mtd
.
read_ecc
=
part_read_ecc
;
if
(
master
->
write_ecc
)
slave
->
mtd
.
write_ecc
=
part_write_ecc
;
if
(
master
->
read_oob
)
slave
->
mtd
.
read_oob
=
part_read_oob
;
if
(
master
->
write_oob
)
...
...
@@ -444,12 +356,6 @@ int add_mtd_partitions(struct mtd_info *master,
}
if
(
master
->
writev
)
slave
->
mtd
.
writev
=
part_writev
;
if
(
master
->
readv
)
slave
->
mtd
.
readv
=
part_readv
;
if
(
master
->
writev_ecc
)
slave
->
mtd
.
writev_ecc
=
part_writev_ecc
;
if
(
master
->
readv_ecc
)
slave
->
mtd
.
readv_ecc
=
part_readv_ecc
;
if
(
master
->
lock
)
slave
->
mtd
.
lock
=
part_lock
;
if
(
master
->
unlock
)
...
...
drivers/mtd/nand/Kconfig
View file @
0305c865
...
...
@@ -65,7 +65,7 @@ config MTD_NAND_AMS_DELTA
config MTD_NAND_TOTO
tristate "NAND Flash device on TOTO board"
depends on ARCH_OMAP && MTD_NAND
depends on ARCH_OMAP && MTD_NAND
&& BROKEN
help
Support for NAND flash on Texas Instruments Toto platform.
...
...
@@ -96,7 +96,7 @@ config MTD_NAND_RTC_FROM4
config MTD_NAND_PPCHAMELEONEVB
tristate "NAND Flash device on PPChameleonEVB board"
depends on PPCHAMELEONEVB && MTD_NAND
depends on PPCHAMELEONEVB && MTD_NAND
&& BROKEN
help
This enables the NAND flash driver on the PPChameleon EVB Board.
...
...
drivers/mtd/nand/ams-delta.c
View file @
0305c865
...
...
@@ -34,13 +34,6 @@ static struct mtd_info *ams_delta_mtd = NULL;
#define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP)
#define T_NAND_CTL_CLRALE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_ALE, 0)
#define T_NAND_CTL_SETALE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_ALE, AMS_DELTA_LATCH2_NAND_ALE)
#define T_NAND_CTL_CLRCLE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE, 0)
#define T_NAND_CTL_SETCLE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE, AMS_DELTA_LATCH2_NAND_CLE)
#define T_NAND_CTL_SETNCE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NCE, 0)
#define T_NAND_CTL_CLRNCE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NCE, AMS_DELTA_LATCH2_NAND_NCE)
/*
* Define partitions for flash devices
*/
...
...
@@ -66,25 +59,6 @@ static struct mtd_partition partition_info[] = {
.
size
=
3
*
SZ_256K
},
};
/*
* hardware specific access to control-lines
*/
static
void
ams_delta_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
{
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
T_NAND_CTL_SETCLE
(
cmd
);
break
;
case
NAND_CTL_CLRCLE
:
T_NAND_CTL_CLRCLE
(
cmd
);
break
;
case
NAND_CTL_SETALE
:
T_NAND_CTL_SETALE
(
cmd
);
break
;
case
NAND_CTL_CLRALE
:
T_NAND_CTL_CLRALE
(
cmd
);
break
;
case
NAND_CTL_SETNCE
:
T_NAND_CTL_SETNCE
(
cmd
);
break
;
case
NAND_CTL_CLRNCE
:
T_NAND_CTL_CLRNCE
(
cmd
);
break
;
}
}
static
void
ams_delta_write_byte
(
struct
mtd_info
*
mtd
,
u_char
byte
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
...
...
@@ -141,6 +115,32 @@ static int ams_delta_verify_buf(struct mtd_info *mtd, const u_char *buf,
return
0
;
}
/*
* Command control function
*
* ctrl:
* NAND_NCE: bit 0 -> bit 2
* NAND_CLE: bit 1 -> bit 7
* NAND_ALE: bit 2 -> bit 6
*/
static
void
ams_delta_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
unsigned
long
bits
;
bits
=
(
~
ctrl
&
NAND_NCE
)
<<
2
;
bits
|=
(
ctrl
&
NAND_CLE
)
<<
7
;
bits
|=
(
ctrl
&
NAND_ALE
)
<<
6
;
ams_delta_latch2_write
(
0xC2
,
bits
);
}
if
(
cmd
!=
NAND_CMD_NONE
)
ams_delta_write_byte
(
mtd
,
cmd
);
}
static
int
ams_delta_nand_ready
(
struct
mtd_info
*
mtd
)
{
return
omap_get_gpio_datain
(
AMS_DELTA_GPIO_PIN_NAND_RB
);
...
...
@@ -179,11 +179,10 @@ static int __init ams_delta_init(void)
this
->
IO_ADDR_R
=
(
OMAP_MPUIO_BASE
+
OMAP_MPUIO_INPUT_LATCH
);
this
->
IO_ADDR_W
=
(
OMAP_MPUIO_BASE
+
OMAP_MPUIO_OUTPUT
);
this
->
read_byte
=
ams_delta_read_byte
;
this
->
write_byte
=
ams_delta_write_byte
;
this
->
write_buf
=
ams_delta_write_buf
;
this
->
read_buf
=
ams_delta_read_buf
;
this
->
verify_buf
=
ams_delta_verify_buf
;
this
->
hwcontro
l
=
ams_delta_hwcontrol
;
this
->
cmd_ctr
l
=
ams_delta_hwcontrol
;
if
(
!
omap_request_gpio
(
AMS_DELTA_GPIO_PIN_NAND_RB
))
{
this
->
dev_ready
=
ams_delta_nand_ready
;
}
else
{
...
...
drivers/mtd/nand/au1550nd.c
View file @
0305c865
...
...
@@ -40,6 +40,7 @@
static
struct
mtd_info
*
au1550_mtd
=
NULL
;
static
void
__iomem
*
p_nand
;
static
int
nand_width
=
1
;
/* default x8 */
static
void
(
*
au1550_write_byte
)(
struct
mtd_info
*
,
u_char
);
/*
* Define partitions for flash device
...
...
@@ -128,21 +129,6 @@ static u16 au_read_word(struct mtd_info *mtd)
return
ret
;
}
/**
* au_write_word - write one word to the chip
* @mtd: MTD device structure
* @word: data word to write
*
* write function for 16bit buswith without
* endianess conversion
*/
static
void
au_write_word
(
struct
mtd_info
*
mtd
,
u16
word
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
writew
(
word
,
this
->
IO_ADDR_W
);
au_sync
();
}
/**
* au_write_buf - write buffer to chip
* @mtd: MTD device structure
...
...
@@ -269,6 +255,18 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
return
0
;
}
/* Select the chip by setting nCE to low */
#define NAND_CTL_SETNCE 1
/* Deselect the chip by setting nCE to high */
#define NAND_CTL_CLRNCE 2
/* Select the command latch by setting CLE to high */
#define NAND_CTL_SETCLE 3
/* Deselect the command latch by setting CLE to low */
#define NAND_CTL_CLRCLE 4
/* Select the address latch by setting ALE to high */
#define NAND_CTL_SETALE 5
/* Deselect the address latch by setting ALE to low */
#define NAND_CTL_CLRALE 6
static
void
au1550_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
{
...
...
@@ -349,7 +347,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
ulong
flags
;
/* Begin command latch cycle */
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
au1550_
hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
/*
* Write out the command to the device.
*/
...
...
@@ -367,25 +365,25 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
column
-=
256
;
readcmd
=
NAND_CMD_READ1
;
}
this
->
write_byte
(
mtd
,
readcmd
);
au1550_
write_byte
(
mtd
,
readcmd
);
}
this
->
write_byte
(
mtd
,
command
);
au1550_
write_byte
(
mtd
,
command
);
/* Set ALE and clear CLE to start address cycle */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRCLE
);
au1550_
hwcontrol
(
mtd
,
NAND_CTL_CLRCLE
);
if
(
column
!=
-
1
||
page_addr
!=
-
1
)
{
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETALE
);
au1550_
hwcontrol
(
mtd
,
NAND_CTL_SETALE
);
/* Serially input address */
if
(
column
!=
-
1
)
{
/* Adjust columns for 16 bit buswidth */
if
(
this
->
options
&
NAND_BUSWIDTH_16
)
column
>>=
1
;
this
->
write_byte
(
mtd
,
column
);
au1550_
write_byte
(
mtd
,
column
);
}
if
(
page_addr
!=
-
1
)
{
this
->
write_byte
(
mtd
,
(
u8
)(
page_addr
&
0xff
));
au1550_
write_byte
(
mtd
,
(
u8
)(
page_addr
&
0xff
));
if
(
command
==
NAND_CMD_READ0
||
command
==
NAND_CMD_READ1
||
...
...
@@ -400,17 +398,17 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
*/
ce_override
=
1
;
local_irq_save
(
flags
);
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETNCE
);
au1550_
hwcontrol
(
mtd
,
NAND_CTL_SETNCE
);
}
this
->
write_byte
(
mtd
,
(
u8
)(
page_addr
>>
8
));
au1550_
write_byte
(
mtd
,
(
u8
)(
page_addr
>>
8
));
/* One more address cycle for devices > 32MiB */
if
(
this
->
chipsize
>
(
32
<<
20
))
this
->
write_byte
(
mtd
,
(
u8
)((
page_addr
>>
16
)
&
0x0f
));
au1550_
write_byte
(
mtd
,
(
u8
)((
page_addr
>>
16
)
&
0x0f
));
}
/* Latch in address */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRALE
);
au1550_
hwcontrol
(
mtd
,
NAND_CTL_CLRALE
);
}
/*
...
...
@@ -443,7 +441,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
udelay
(
1
);
/* Release -CE and re-enable interrupts. */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRNCE
);
au1550_
hwcontrol
(
mtd
,
NAND_CTL_CLRNCE
);
local_irq_restore
(
flags
);
return
;
}
...
...
@@ -571,7 +569,6 @@ static int __init au1xxx_nand_init(void)
nand_width
=
au_readl
(
MEM_STCFG3
)
&
(
1
<<
22
);
/* Set address of hardware control function */
this
->
hwcontrol
=
au1550_hwcontrol
;
this
->
dev_ready
=
au1550_device_ready
;
this
->
select_chip
=
au1550_select_chip
;
this
->
cmdfunc
=
au1550_command
;
...
...
@@ -586,8 +583,7 @@ static int __init au1xxx_nand_init(void)
this
->
options
|=
NAND_BUSWIDTH_16
;
this
->
read_byte
=
(
!
nand_width
)
?
au_read_byte16
:
au_read_byte
;
this
->
write_byte
=
(
!
nand_width
)
?
au_write_byte16
:
au_write_byte
;
this
->
write_word
=
au_write_word
;
au1550_write_byte
=
(
!
nand_width
)
?
au_write_byte16
:
au_write_byte
;
this
->
read_word
=
au_read_word
;
this
->
write_buf
=
(
!
nand_width
)
?
au_write_buf16
:
au_write_buf
;
this
->
read_buf
=
(
!
nand_width
)
?
au_read_buf16
:
au_read_buf
;
...
...
drivers/mtd/nand/autcpu12.c
View file @
0305c865
...
...
@@ -42,11 +42,6 @@
* MTD structure for AUTCPU12 board
*/
static
struct
mtd_info
*
autcpu12_mtd
=
NULL
;
static
int
autcpu12_io_base
=
CS89712_VIRT_BASE
;
static
int
autcpu12_fio_pbase
=
AUTCPU12_PHYS_SMC
;
static
int
autcpu12_fio_ctrl
=
AUTCPU12_SMC_SELECT_OFFSET
;
static
int
autcpu12_pedr
=
AUTCPU12_SMC_PORT_OFFSET
;
static
void
__iomem
*
autcpu12_fio_base
;
/*
...
...
@@ -94,31 +89,42 @@ static struct mtd_partition partition_info128k[] = {
#define NUM_PARTITIONS128K 2
/*
* hardware specific access to control-lines
*/
static
void
autcpu12_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
*
* ALE bit 4 autcpu12_pedr
* CLE bit 5 autcpu12_pedr
* NCE bit 0 fio_ctrl
*
*/
static
void
autcpu12_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
s
witch
(
cmd
)
{
s
truct
nand_chip
*
chip
=
mtd
->
priv
;
case
NAND_CTL_SETCLE
:
(
*
(
volatile
unsigned
char
*
)
(
autcpu12_io_base
+
autcpu12_pedr
))
|=
AUTCPU12_SMC_CLE
;
break
;
case
NAND_CTL_CLRCLE
:
(
*
(
volatile
unsigned
char
*
)
(
autcpu12_io_base
+
autcpu12_pedr
))
&=
~
AUTCPU12_SMC_CLE
;
break
;
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
void
__iomem
*
addr
unsigned
char
bits
;
case
NAND_CTL_SETALE
:
(
*
(
volatile
unsigned
char
*
)
(
autcpu12_io_base
+
autcpu12_pedr
))
|=
AUTCPU12_SMC_ALE
;
break
;
case
NAND_CTL_CLRALE
:
(
*
(
volatile
unsigned
char
*
)
(
autcpu12_io_base
+
autcpu12_pedr
))
&=
~
AUTCPU12_SMC_ALE
;
break
;
addr
=
CS89712_VIRT_BASE
+
AUTCPU12_SMC_PORT_OFFSET
;
bits
=
(
ctrl
&
NAND_CLE
)
<<
4
;
bits
|=
(
ctrl
&
NAND_ALE
)
<<
2
;
writeb
((
readb
(
addr
)
&
~
0x30
)
|
bits
,
addr
);
case
NAND_CTL_SETNCE
:
(
*
(
volatile
unsigned
char
*
)
(
autcpu12_fio_base
+
autcpu12_fio_ctrl
))
=
0x01
;
break
;
case
NAND_CTL_CLRNCE
:
(
*
(
volatile
unsigned
char
*
)
(
autcpu12_fio_base
+
autcpu12_fio_ctrl
))
=
0x00
;
break
;
addr
=
autcpu12_fio_base
+
AUTCPU12_SMC_SELECT_OFFSET
;
writeb
((
readb
(
addr
)
&
~
0x1
)
|
(
ctrl
&
NAND_NCE
),
addr
)
;
}
if
(
cmd
!=
NAND_CMD_NONE
)
writeb
(
cmd
,
chip
->
IO_ADDR_W
);
}
/*
* read device ready pin
*/
* read device ready pin
*/
int
autcpu12_device_ready
(
struct
mtd_info
*
mtd
)
{
void
__iomem
*
addr
=
CS89712_VIRT_BASE
+
AUTCPU12_SMC_PORT_OFFSET
;
return
((
*
(
volatile
unsigned
char
*
)(
autcpu12_io_base
+
autcpu12_pedr
))
&
AUTCPU12_SMC_RDY
)
?
1
:
0
;
return
readb
(
addr
)
&
AUTCPU12_SMC_RDY
;
}
/*
...
...
@@ -130,7 +136,8 @@ static int __init autcpu12_init(void)
int
err
=
0
;
/* Allocate memory for MTD device structure and private data */
autcpu12_mtd
=
kmalloc
(
sizeof
(
struct
mtd_info
)
+
sizeof
(
struct
nand_chip
),
GFP_KERNEL
);
autcpu12_mtd
=
kmalloc
(
sizeof
(
struct
mtd_info
)
+
sizeof
(
struct
nand_chip
),
GFP_KERNEL
);
if
(
!
autcpu12_mtd
)
{
printk
(
"Unable to allocate AUTCPU12 NAND MTD device structure.
\n
"
);
err
=
-
ENOMEM
;
...
...
@@ -138,7 +145,7 @@ static int __init autcpu12_init(void)
}
/* map physical adress */
autcpu12_fio_base
=
ioremap
(
autcpu12_fio_pbase
,
SZ_1K
);
autcpu12_fio_base
=
ioremap
(
AUTCPU12_PHYS_SMC
,
SZ_1K
);
if
(
!
autcpu12_fio_base
)
{
printk
(
"Ioremap autcpu12 SmartMedia Card failed
\n
"
);
err
=
-
EIO
;
...
...
@@ -159,7 +166,7 @@ static int __init autcpu12_init(void)
/* Set address of NAND IO lines */
this
->
IO_ADDR_R
=
autcpu12_fio_base
;
this
->
IO_ADDR_W
=
autcpu12_fio_base
;
this
->
hwcontro
l
=
autcpu12_hwcontrol
;
this
->
cmd_ctr
l
=
autcpu12_hwcontrol
;
this
->
dev_ready
=
autcpu12_device_ready
;
/* 20 us command delay time */
this
->
chip_delay
=
20
;
...
...
@@ -179,10 +186,22 @@ static int __init autcpu12_init(void)
/* Register the partitions */
switch
(
autcpu12_mtd
->
size
)
{
case
SZ_16M
:
add_mtd_partitions
(
autcpu12_mtd
,
partition_info16k
,
NUM_PARTITIONS16K
);
break
;
case
SZ_32M
:
add_mtd_partitions
(
autcpu12_mtd
,
partition_info32k
,
NUM_PARTITIONS32K
);
break
;
case
SZ_64M
:
add_mtd_partitions
(
autcpu12_mtd
,
partition_info64k
,
NUM_PARTITIONS64K
);
break
;
case
SZ_128M
:
add_mtd_partitions
(
autcpu12_mtd
,
partition_info128k
,
NUM_PARTITIONS128K
);
break
;
case
SZ_16M
:
add_mtd_partitions
(
autcpu12_mtd
,
partition_info16k
,
NUM_PARTITIONS16K
);
break
;
case
SZ_32M
:
add_mtd_partitions
(
autcpu12_mtd
,
partition_info32k
,
NUM_PARTITIONS32K
);
break
;
case
SZ_64M
:
add_mtd_partitions
(
autcpu12_mtd
,
partition_info64k
,
NUM_PARTITIONS64K
);
break
;
case
SZ_128M
:
add_mtd_partitions
(
autcpu12_mtd
,
partition_info128k
,
NUM_PARTITIONS128K
);
break
;
default:
printk
(
"Unsupported SmartMedia device
\n
"
);
err
=
-
ENXIO
;
...
...
@@ -191,7 +210,7 @@ static int __init autcpu12_init(void)
goto
out
;
out_ior:
iounmap
(
(
void
*
)
autcpu12_fio_base
);
iounmap
(
autcpu12_fio_base
);
out_mtd:
kfree
(
autcpu12_mtd
);
out:
...
...
@@ -209,7 +228,7 @@ static void __exit autcpu12_cleanup(void)
nand_release
(
autcpu12_mtd
);
/* unmap physical adress */
iounmap
(
(
void
*
)
autcpu12_fio_base
);
iounmap
(
autcpu12_fio_base
);
/* Free the MTD device structure */
kfree
(
autcpu12_mtd
);
...
...
drivers/mtd/nand/cs553x_nand.c
View file @
0305c865
...
...
@@ -131,33 +131,17 @@ static void cs553x_write_byte(struct mtd_info *mtd, u_char byte)
writeb
(
byte
,
this
->
IO_ADDR_W
+
0x801
);
}
static
void
cs553x_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
static
void
cs553x_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
void
__iomem
*
mmio_base
=
this
->
IO_ADDR_R
;
unsigned
char
ctl
;
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
ctl
=
CS_NAND_CTL_CLE
;
break
;
case
NAND_CTL_CLRCLE
:
case
NAND_CTL_CLRALE
:
case
NAND_CTL_SETNCE
:
ctl
=
0
;
break
;
case
NAND_CTL_SETALE
:
ctl
=
CS_NAND_CTL_ALE
;
break
;
default:
case
NAND_CTL_CLRNCE
:
ctl
=
CS_NAND_CTL_CE
;
break
;
}
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
unsigned
char
ctl
=
(
ctrl
&
~
NAND_CTRL_CHANGE
)
^
0x01
;
writeb
(
ctl
,
mmio_base
+
MM_NAND_CTL
);
}
if
(
cmd
!=
NAND_CMD_NONE
)
cs553x_write_byte
(
mtd
,
cmd
);
}
static
int
cs553x_device_ready
(
struct
mtd_info
*
mtd
)
...
...
@@ -233,10 +217,9 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
goto
out_mtd
;
}
this
->
hwcontro
l
=
cs553x_hwcontrol
;
this
->
cmd_ctr
l
=
cs553x_hwcontrol
;
this
->
dev_ready
=
cs553x_device_ready
;
this
->
read_byte
=
cs553x_read_byte
;
this
->
write_byte
=
cs553x_write_byte
;
this
->
read_buf
=
cs553x_read_buf
;
this
->
write_buf
=
cs553x_write_buf
;
...
...
drivers/mtd/nand/diskonchip.c
View file @
0305c865
...
...
@@ -95,7 +95,8 @@ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
static
void
doc200x_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
);
static
void
doc200x_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
bitmask
);
static
void
doc200x_select_chip
(
struct
mtd_info
*
mtd
,
int
chip
);
static
int
debug
=
0
;
...
...
@@ -402,12 +403,10 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
uint16_t
ret
;
doc200x_select_chip
(
mtd
,
nr
);
doc200x_hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
this
->
write_byte
(
mtd
,
NAND_CMD_READID
);
doc200x_hwcontrol
(
mtd
,
NAND_CTL_CLRCLE
);
doc200x_hwcontrol
(
mtd
,
NAND_CTL_SETALE
);
this
->
write_byte
(
mtd
,
0
);
doc200x_hwcontrol
(
mtd
,
NAND_CTL_CLRALE
);
doc200x_hwcontrol
(
mtd
,
NAND_CMD_READID
,
NAND_CTRL_CLE
|
NAND_CTRL_CHANGE
);
doc200x_hwcontrol
(
mtd
,
0
,
NAND_CTRL_ALE
|
NAND_CTRL_CHANGE
);
doc200x_hwcontrol
(
mtd
,
NAND_CMD_NONE
,
NAND_NCE
|
NAND_CTRL_CHANGE
);
/* We cant' use dev_ready here, but at least we wait for the
* command to complete
...
...
@@ -425,12 +424,11 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
}
ident
;
void
__iomem
*
docptr
=
doc
->
virtadr
;
doc200x_hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
doc2000_write_byte
(
mtd
,
NAND_CMD_READID
);
doc200x_hwcontrol
(
mtd
,
NAND_CTL_CLRCLE
);
doc200x_hwcontrol
(
mtd
,
NAND_CTL_SETALE
);
doc2000_write_byte
(
mtd
,
0
);
doc200x_hwcontrol
(
mtd
,
NAND_CTL_CLRALE
);
doc200x_hwcontrol
(
mtd
,
NAND_CMD_READID
,
NAND_CTRL_CLE
|
NAND_CTRL_CHANGE
);
doc200x_hwcontrol
(
mtd
,
0
,
NAND_CTRL_ALE
|
NAND_CTRL_CHANGE
);
doc200x_hwcontrol
(
mtd
,
NAND_CMD_NONE
,
NAND_NCE
|
NAND_CTRL_CHANGE
);
udelay
(
50
);
...
...
@@ -690,54 +688,41 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip)
chip
-=
(
floor
*
doc
->
chips_per_floor
);
/* 11.4.4 -- deassert CE before changing chip */
doc200x_hwcontrol
(
mtd
,
NAND_C
TL_CLRNC
E
);
doc200x_hwcontrol
(
mtd
,
NAND_C
MD_NONE
,
0
|
NAND_CTRL_CHANG
E
);
WriteDOC
(
floor
,
docptr
,
FloorSelect
);
WriteDOC
(
chip
,
docptr
,
CDSNDeviceSelect
);
doc200x_hwcontrol
(
mtd
,
NAND_C
TL_SETNC
E
);
doc200x_hwcontrol
(
mtd
,
NAND_C
MD_NONE
,
NAND_NCE
|
NAND_CTRL_CHANG
E
);
doc
->
curchip
=
chip
;
doc
->
curfloor
=
floor
;
}
static
void
doc200x_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
#define CDSN_CTRL_MSK (CDSN_CTRL_CE | CDSN_CTRL_CLE | CDSN_CTRL_ALE)
static
void
doc200x_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
struct
doc_priv
*
doc
=
this
->
priv
;
void
__iomem
*
docptr
=
doc
->
virtadr
;
switch
(
cmd
)
{
case
NAND_CTL_SETNCE
:
doc
->
CDSNControl
|=
CDSN_CTRL_CE
;
break
;
case
NAND_CTL_CLRNCE
:
doc
->
CDSNControl
&=
~
CDSN_CTRL_CE
;
break
;
case
NAND_CTL_SETCLE
:
doc
->
CDSNControl
|=
CDSN_CTRL_CLE
;
break
;
case
NAND_CTL_CLRCLE
:
doc
->
CDSNControl
&=
~
CDSN_CTRL_CLE
;
break
;
case
NAND_CTL_SETALE
:
doc
->
CDSNControl
|=
CDSN_CTRL_ALE
;
break
;
case
NAND_CTL_CLRALE
:
doc
->
CDSNControl
&=
~
CDSN_CTRL_ALE
;
break
;
case
NAND_CTL_SETWP
:
doc
->
CDSNControl
|=
CDSN_CTRL_WP
;
break
;
case
NAND_CTL_CLRWP
:
doc
->
CDSNControl
&=
~
CDSN_CTRL_WP
;
break
;
}
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
doc
->
CDSNControl
&=
~
CDSN_CTRL_MSK
;
doc
->
CDSNControl
|=
ctrl
&
CDSN_CTRL_MSK
;
if
(
debug
)
printk
(
"hwcontrol(%d): %02x
\n
"
,
cmd
,
doc
->
CDSNControl
);
WriteDOC
(
doc
->
CDSNControl
,
docptr
,
CDSNControl
);
/* 11.4.3 -- 4 NOPs after CSDNControl write */
DoC_Delay
(
doc
,
4
);
}
if
(
cmd
!=
NAND_CMD_NONE
)
{
if
(
DoC_is_2000
(
doc
))
doc2000_write_byte
(
mtd
,
cmd
);
else
doc2001_write_byte
(
mtd
,
cmd
);
}
}
static
void
doc2001plus_command
(
struct
mtd_info
*
mtd
,
unsigned
command
,
int
column
,
int
page_addr
)
...
...
@@ -1454,7 +1439,6 @@ static inline int __init doc2000_init(struct mtd_info *mtd)
struct
nand_chip
*
this
=
mtd
->
priv
;
struct
doc_priv
*
doc
=
this
->
priv
;
this
->
write_byte
=
doc2000_write_byte
;
this
->
read_byte
=
doc2000_read_byte
;
this
->
write_buf
=
doc2000_writebuf
;
this
->
read_buf
=
doc2000_readbuf
;
...
...
@@ -1472,7 +1456,6 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
struct
nand_chip
*
this
=
mtd
->
priv
;
struct
doc_priv
*
doc
=
this
->
priv
;
this
->
write_byte
=
doc2001_write_byte
;
this
->
read_byte
=
doc2001_read_byte
;
this
->
write_buf
=
doc2001_writebuf
;
this
->
read_buf
=
doc2001_readbuf
;
...
...
@@ -1504,16 +1487,15 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)
struct
nand_chip
*
this
=
mtd
->
priv
;
struct
doc_priv
*
doc
=
this
->
priv
;
this
->
write_byte
=
NULL
;
this
->
read_byte
=
doc2001plus_read_byte
;
this
->
write_buf
=
doc2001plus_writebuf
;
this
->
read_buf
=
doc2001plus_readbuf
;
this
->
verify_buf
=
doc2001plus_verifybuf
;
this
->
scan_bbt
=
inftl_scan_bbt
;
this
->
hwcontro
l
=
NULL
;
this
->
cmd_ctr
l
=
NULL
;
this
->
select_chip
=
doc2001plus_select_chip
;
this
->
cmdfunc
=
doc2001plus_command
;
this
->
e
nable_hwecc
=
doc2001plus_enable_hwecc
;
this
->
e
cc
.
hwctl
=
doc2001plus_enable_hwecc
;
doc
->
chips_per_floor
=
1
;
mtd
->
name
=
"DiskOnChip Millennium Plus"
;
...
...
@@ -1670,7 +1652,7 @@ static int __init doc_probe(unsigned long physadr)
nand
->
priv
=
doc
;
nand
->
select_chip
=
doc200x_select_chip
;
nand
->
hwcontro
l
=
doc200x_hwcontrol
;
nand
->
cmd_ctr
l
=
doc200x_hwcontrol
;
nand
->
dev_ready
=
doc200x_dev_ready
;
nand
->
waitfunc
=
doc200x_wait
;
nand
->
block_bad
=
doc200x_block_bad
;
...
...
drivers/mtd/nand/edb7312.c
View file @
0305c865
...
...
@@ -73,32 +73,26 @@ static struct mtd_partition partition_info[] = {
/*
* hardware specific access to control-lines
*
* NAND_NCE: bit 0 -> bit 7
* NAND_CLE: bit 1 -> bit 4
* NAND_ALE: bit 2 -> bit 5
*/
static
void
ep7312_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
static
void
ep7312_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
clps_writeb
(
clps_readb
(
ep7312_pxdr
)
|
0x10
,
ep7312_pxdr
);
break
;
case
NAND_CTL_CLRCLE
:
clps_writeb
(
clps_readb
(
ep7312_pxdr
)
&
~
0x10
,
ep7312_pxdr
);
break
;
case
NAND_CTL_SETALE
:
clps_writeb
(
clps_readb
(
ep7312_pxdr
)
|
0x20
,
ep7312_pxdr
);
break
;
case
NAND_CTL_CLRALE
:
clps_writeb
(
clps_readb
(
ep7312_pxdr
)
&
~
0x20
,
ep7312_pxdr
);
break
;
case
NAND_CTL_SETNCE
:
clps_writeb
((
clps_readb
(
ep7312_pxdr
)
|
0x80
)
&
~
0x40
,
ep7312_pxdr
);
break
;
case
NAND_CTL_CLRNCE
:
clps_writeb
((
clps_readb
(
ep7312_pxdr
)
|
0x80
)
|
0x40
,
ep7312_pxdr
);
break
;
struct
nand_chip
*
chip
=
mtd
->
priv
;
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
unsigned
char
bits
;
bits
=
(
ctrl
&
(
NAND_CLE
|
NAND_ALE
))
<<
3
;
bits
=
(
ctrl
&
NAND_NCE
)
<<
7
;
clps_writeb
((
clps_readb
(
ep7312_pxdr
)
&
0xB0
)
|
0x10
,
ep7312_pxdr
);
}
if
(
cmd
!=
NAND_CMD_NONE
)
writeb
(
cmd
,
chip
->
IO_ADDR_W
);
}
/*
...
...
@@ -159,7 +153,7 @@ static int __init ep7312_init(void)
/* insert callbacks */
this
->
IO_ADDR_R
=
ep7312_fio_base
;
this
->
IO_ADDR_W
=
ep7312_fio_base
;
this
->
hwcontro
l
=
ep7312_hwcontrol
;
this
->
cmd_ctr
l
=
ep7312_hwcontrol
;
this
->
dev_ready
=
ep7312_device_ready
;
/* 15 us command delay time */
this
->
chip_delay
=
15
;
...
...
drivers/mtd/nand/h1910.c
View file @
0305c865
...
...
@@ -56,36 +56,18 @@ static struct mtd_partition partition_info[] = {
/*
* hardware specific access to control-lines
*
* NAND_NCE: bit 0 - don't care
* NAND_CLE: bit 1 - address bit 2
* NAND_ALE: bit 2 - address bit 3
*/
static
void
h1910_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
static
void
h1910_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
struct
nand_chip
*
this
=
(
struct
nand_chip
*
)(
mtd
->
priv
);
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
this
->
IO_ADDR_R
|=
(
1
<<
2
);
this
->
IO_ADDR_W
|=
(
1
<<
2
);
break
;
case
NAND_CTL_CLRCLE
:
this
->
IO_ADDR_R
&=
~
(
1
<<
2
);
this
->
IO_ADDR_W
&=
~
(
1
<<
2
);
break
;
case
NAND_CTL_SETALE
:
this
->
IO_ADDR_R
|=
(
1
<<
3
);
this
->
IO_ADDR_W
|=
(
1
<<
3
);
break
;
case
NAND_CTL_CLRALE
:
this
->
IO_ADDR_R
&=
~
(
1
<<
3
);
this
->
IO_ADDR_W
&=
~
(
1
<<
3
);
break
;
case
NAND_CTL_SETNCE
:
break
;
case
NAND_CTL_CLRNCE
:
break
;
}
struct
nand_chip
*
chip
=
mtd
->
priv
;
if
(
cmd
!=
NAND_CMD_NONE
)
writeb
(
cmd
,
chip
->
IO_ADDR_W
|
((
ctrl
&
0x6
)
<<
1
));
}
/*
...
...
@@ -145,7 +127,7 @@ static int __init h1910_init(void)
/* insert callbacks */
this
->
IO_ADDR_R
=
nandaddr
;
this
->
IO_ADDR_W
=
nandaddr
;
this
->
hwcontro
l
=
h1910_hwcontrol
;
this
->
cmd_ctr
l
=
h1910_hwcontrol
;
this
->
dev_ready
=
NULL
;
/* unknown whether that was correct or not so we will just do it like this */
/* 15 us command delay time */
this
->
chip_delay
=
50
;
...
...
drivers/mtd/nand/nand_base.c
View file @
0305c865
...
...
@@ -139,23 +139,12 @@ static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
static
int
nand_read
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
uint8_t
*
buf
);
static
int
nand_read_ecc
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
uint8_t
*
buf
,
uint8_t
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
);
static
int
nand_read_oob
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
uint8_t
*
buf
);
static
int
nand_write
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
uint8_t
*
buf
);
static
int
nand_write_ecc
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
uint8_t
*
buf
,
uint8_t
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
);
static
int
nand_write_oob
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
uint8_t
*
buf
);
static
int
nand_writev
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
);
static
int
nand_writev_ecc
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
,
uint8_t
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
);
static
int
nand_erase
(
struct
mtd_info
*
mtd
,
struct
erase_info
*
instr
);
static
void
nand_sync
(
struct
mtd_info
*
mtd
);
...
...
@@ -175,6 +164,12 @@ static int nand_verify_pages(struct mtd_info *mtd, struct nand_chip *this,
static
int
nand_get_device
(
struct
nand_chip
*
this
,
struct
mtd_info
*
mtd
,
int
new_state
);
/*
* For devices which display every fart in the system on a seperate LED. Is
* compiled away when LED support is disabled.
*/
DEFINE_LED_TRIGGER
(
nand_led_trigger
);
/**
* nand_release_device - [GENERIC] release chip
* @mtd: MTD device structure
...
...
@@ -208,19 +203,6 @@ static uint8_t nand_read_byte(struct mtd_info *mtd)
return
readb
(
this
->
IO_ADDR_R
);
}
/**
* nand_write_byte - [DEFAULT] write one byte to the chip
* @mtd: MTD device structure
* @byte: pointer to data byte to write
*
* Default write function for 8it buswith
*/
static
void
nand_write_byte
(
struct
mtd_info
*
mtd
,
uint8_t
byte
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
writeb
(
byte
,
this
->
IO_ADDR_W
);
}
/**
* nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
* @mtd: MTD device structure
...
...
@@ -234,20 +216,6 @@ static uint8_t nand_read_byte16(struct mtd_info *mtd)
return
(
uint8_t
)
cpu_to_le16
(
readw
(
this
->
IO_ADDR_R
));
}
/**
* nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip
* @mtd: MTD device structure
* @byte: pointer to data byte to write
*
* Default write function for 16bit buswith with
* endianess conversion
*/
static
void
nand_write_byte16
(
struct
mtd_info
*
mtd
,
uint8_t
byte
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
writew
(
le16_to_cpu
((
u16
)
byte
),
this
->
IO_ADDR_W
);
}
/**
* nand_read_word - [DEFAULT] read one word from the chip
* @mtd: MTD device structure
...
...
@@ -261,20 +229,6 @@ static u16 nand_read_word(struct mtd_info *mtd)
return
readw
(
this
->
IO_ADDR_R
);
}
/**
* nand_write_word - [DEFAULT] write one word to the chip
* @mtd: MTD device structure
* @word: data word to write
*
* Default write function for 16bit buswith without
* endianess conversion
*/
static
void
nand_write_word
(
struct
mtd_info
*
mtd
,
u16
word
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
writew
(
word
,
this
->
IO_ADDR_W
);
}
/**
* nand_select_chip - [DEFAULT] control CE line
* @mtd: MTD device structure
...
...
@@ -287,10 +241,10 @@ static void nand_select_chip(struct mtd_info *mtd, int chip)
struct
nand_chip
*
this
=
mtd
->
priv
;
switch
(
chip
)
{
case
-
1
:
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRNC
E
);
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_NONE
,
0
|
NAND_CTRL_CHANG
E
);
break
;
case
0
:
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETNC
E
);
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_NONE
,
NAND_NCE
|
NAND_CTRL_CHANG
E
);
break
;
default:
...
...
@@ -528,8 +482,6 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
return
nand_isbad_bbt
(
mtd
,
ofs
,
allowbbt
);
}
DEFINE_LED_TRIGGER
(
nand_led_trigger
);
/*
* Wait for the ready pin, after a command
* The timeout is catched later.
...
...
@@ -559,13 +511,12 @@ static void nand_wait_ready(struct mtd_info *mtd)
* Send command to NAND device. This function is used for small page
* devices (256/512 Bytes per page)
*/
static
void
nand_command
(
struct
mtd_info
*
mtd
,
unsigned
command
,
int
column
,
int
page_addr
)
static
void
nand_command
(
struct
mtd_info
*
mtd
,
unsigned
int
command
,
int
column
,
int
page_addr
)
{
register
struct
nand_chip
*
this
=
mtd
->
priv
;
int
ctrl
=
NAND_CTRL_CLE
|
NAND_CTRL_CHANGE
;
/* Begin command latch cycle */
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
/*
* Write out the command to the device.
*/
...
...
@@ -583,33 +534,32 @@ static void nand_command(struct mtd_info *mtd, unsigned command, int column,
column
-=
256
;
readcmd
=
NAND_CMD_READ1
;
}
this
->
write_byte
(
mtd
,
readcmd
);
this
->
cmd_ctrl
(
mtd
,
readcmd
,
ctrl
);
ctrl
&=
~
NAND_CTRL_CHANGE
;
}
this
->
write_byte
(
mtd
,
command
);
/* Set ALE and clear CLE to start address cycle */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRCLE
);
if
(
column
!=
-
1
||
page_addr
!=
-
1
)
{
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETALE
);
this
->
cmd_ctrl
(
mtd
,
command
,
ctrl
);
/*
* Address cycle, when necessary
*/
ctrl
=
NAND_CTRL_ALE
|
NAND_CTRL_CHANGE
;
/* Serially input address */
if
(
column
!=
-
1
)
{
/* Adjust columns for 16 bit buswidth */
if
(
this
->
options
&
NAND_BUSWIDTH_16
)
column
>>=
1
;
this
->
write_byte
(
mtd
,
column
);
this
->
cmd_ctrl
(
mtd
,
column
,
ctrl
);
ctrl
&=
~
NAND_CTRL_CHANGE
;
}
if
(
page_addr
!=
-
1
)
{
this
->
write_byte
(
mtd
,
(
uint8_t
)(
page_addr
&
0xff
));
this
->
write_byte
(
mtd
,
(
uint8_t
)((
page_addr
>>
8
)
&
0xff
));
this
->
cmd_ctrl
(
mtd
,
page_addr
,
ctrl
);
ctrl
&=
~
NAND_CTRL_CHANGE
;
this
->
cmd_ctrl
(
mtd
,
page_addr
>>
8
,
ctrl
);
/* One more address cycle for devices > 32MiB */
if
(
this
->
chipsize
>
(
32
<<
20
))
this
->
write_byte
(
mtd
,
(
uint8_t
)((
page_addr
>>
16
)
&
0x0f
));
}
/* Latch in address */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRALE
);
this
->
cmd_ctrl
(
mtd
,
page_addr
>>
16
,
ctrl
);
}
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_NONE
,
NAND_NCE
|
NAND_CTRL_CHANGE
);
/*
* program and erase have their own busy handlers
...
...
@@ -622,15 +572,16 @@ static void nand_command(struct mtd_info *mtd, unsigned command, int column,
case
NAND_CMD_ERASE2
:
case
NAND_CMD_SEQIN
:
case
NAND_CMD_STATUS
:
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_NONE
,
NAND_NCE
);
return
;
case
NAND_CMD_RESET
:
if
(
this
->
dev_ready
)
break
;
udelay
(
this
->
chip_delay
);
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
this
->
write_byte
(
mtd
,
NAND_CMD_STATUS
);
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRCL
E
);
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_STATUS
,
NAND_CTRL_CLE
|
NAND_CTRL_CHANGE
);
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_NONE
,
NAND_NC
E
);
while
(
!
(
this
->
read_byte
(
mtd
)
&
NAND_STATUS_READY
))
;
return
;
...
...
@@ -659,12 +610,13 @@ static void nand_command(struct mtd_info *mtd, unsigned command, int column,
* @column: the column address for this command, -1 if none
* @page_addr: the page address for this command, -1 if none
*
* Send command to NAND device. This is the version for the new large page
devices
*
We dont have the separate regions as we have in the small page devices.
* We must emulate NAND_CMD_READOOB to keep the code compatible.
* Send command to NAND device. This is the version for the new large page
*
devices We dont have the separate regions as we have in the small page
*
devices.
We must emulate NAND_CMD_READOOB to keep the code compatible.
*
*/
static
void
nand_command_lp
(
struct
mtd_info
*
mtd
,
unsigned
command
,
int
column
,
int
page_addr
)
static
void
nand_command_lp
(
struct
mtd_info
*
mtd
,
unsigned
int
command
,
int
column
,
int
page_addr
)
{
register
struct
nand_chip
*
this
=
mtd
->
priv
;
...
...
@@ -674,34 +626,33 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned command, int column,
command
=
NAND_CMD_READ0
;
}
/* Begin command latch cycle */
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
/* Write out the command to the device. */
this
->
write_byte
(
mtd
,
(
command
&
0xff
));
/* End command latch cycle */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRCLE
);
/* Command latch cycle */
this
->
cmd_ctrl
(
mtd
,
command
&
0xff
,
NAND_NCE
|
NAND_CLE
|
NAND_CTRL_CHANGE
);
if
(
column
!=
-
1
||
page_addr
!=
-
1
)
{
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETALE
)
;
int
ctrl
=
NAND_CTRL_CHANGE
|
NAND_NCE
|
NAND_ALE
;
/* Serially input address */
if
(
column
!=
-
1
)
{
/* Adjust columns for 16 bit buswidth */
if
(
this
->
options
&
NAND_BUSWIDTH_16
)
column
>>=
1
;
this
->
write_byte
(
mtd
,
column
&
0xff
);
this
->
write_byte
(
mtd
,
column
>>
8
);
this
->
cmd_ctrl
(
mtd
,
column
,
ctrl
);
ctrl
&=
~
NAND_CTRL_CHANGE
;
this
->
cmd_ctrl
(
mtd
,
column
>>
8
,
ctrl
);
}
if
(
page_addr
!=
-
1
)
{
this
->
write_byte
(
mtd
,
(
uint8_t
)(
page_addr
&
0xff
));
this
->
write_byte
(
mtd
,
(
uint8_t
)((
page_addr
>>
8
)
&
0xff
));
this
->
cmd_ctrl
(
mtd
,
page_addr
,
ctrl
);
this
->
cmd_ctrl
(
mtd
,
page_addr
>>
8
,
NAND_NCE
|
NAND_ALE
);
/* One more address cycle for devices > 128MiB */
if
(
this
->
chipsize
>
(
128
<<
20
))
this
->
write_byte
(
mtd
,
(
uint8_t
)((
page_addr
>>
16
)
&
0xff
));
this
->
cmd_ctrl
(
mtd
,
page_addr
>>
16
,
NAND_NCE
|
NAND_ALE
);
}
/* Latch in address */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRALE
);
}
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_NONE
,
NAND_NCE
|
NAND_CTRL_CHANGE
);
/*
* program and erase have their own busy handlers
...
...
@@ -733,20 +684,14 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned command, int column,
if
(
this
->
dev_ready
)
break
;
udelay
(
this
->
chip_delay
);
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
this
->
write_byte
(
mtd
,
NAND_CMD_STATUS
);
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRCLE
);
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_STATUS
,
NAND_NCE
|
NAND_CLE
);
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_NONE
,
NAND_NCE
);
while
(
!
(
this
->
read_byte
(
mtd
)
&
NAND_STATUS_READY
))
;
return
;
case
NAND_CMD_READ0
:
/* Begin command latch cycle */
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
/* Write out the start read command */
this
->
write_byte
(
mtd
,
NAND_CMD_READSTART
);
/* End command latch cycle */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRCLE
);
/* Fall through into ready check */
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_READSTART
,
NAND_NCE
|
NAND_CLE
);
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_NONE
,
NAND_NCE
);
/* This applies to read commands */
default:
...
...
@@ -1084,27 +1029,6 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retl
return
nand_do_read_ecc
(
mtd
,
from
,
len
,
retlen
,
buf
,
NULL
,
&
mtd
->
oobinfo
,
0xff
);
}
/**
* nand_read_ecc - [MTD Interface] MTD compability function for nand_do_read_ecc
* @mtd: MTD device structure
* @from: offset to read from
* @len: number of bytes to read
* @retlen: pointer to variable to store the number of read bytes
* @buf: the databuffer to put data
* @oob_buf: filesystem supplied oob data buffer
* @oobsel: oob selection structure
*
* This function simply calls nand_do_read_ecc with flags = 0xff
*/
static
int
nand_read_ecc
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
uint8_t
*
buf
,
uint8_t
*
oob_buf
,
struct
nand_oobinfo
*
oobsel
)
{
/* use userspace supplied oobinfo, if zero */
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
return
nand_do_read_ecc
(
mtd
,
from
,
len
,
retlen
,
buf
,
oob_buf
,
oobsel
,
0xff
);
}
/**
* nand_do_read_ecc - [MTD Interface] Read data with ECC
* @mtd: MTD device structure
...
...
@@ -1528,6 +1452,56 @@ int nand_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, s
return
0
;
}
/**
* nand_write_raw - [GENERIC] Write raw data including oob
* @mtd: MTD device structure
* @buf: source buffer
* @to: offset to write to
* @len: number of bytes to write
* @buf: source buffer
* @oob: oob buffer
*
* Write raw data including oob
*/
int
nand_write_raw
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
uint8_t
*
buf
,
uint8_t
*
oob
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
int
page
=
(
int
)(
to
>>
this
->
page_shift
);
int
chip
=
(
int
)(
to
>>
this
->
chip_shift
);
int
ret
;
*
retlen
=
0
;
/* Do not allow writes past end of device */
if
((
to
+
len
)
>
mtd
->
size
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_read_raw: Attempt write "
"beyond end of device
\n
"
);
return
-
EINVAL
;
}
/* Grab the lock and see if the device is available */
nand_get_device
(
this
,
mtd
,
FL_WRITING
);
this
->
select_chip
(
mtd
,
chip
);
this
->
data_poi
=
buf
;
while
(
len
!=
*
retlen
)
{
ret
=
nand_write_page
(
mtd
,
this
,
page
,
oob
,
&
mtd
->
oobinfo
,
0
);
if
(
ret
)
return
ret
;
page
++
;
*
retlen
+=
mtd
->
writesize
;
this
->
data_poi
+=
mtd
->
writesize
;
oob
+=
mtd
->
oobsize
;
}
/* Deselect and wake up anyone waiting on the device */
nand_release_device
(
mtd
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
nand_write_raw
);
/**
* nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
* @mtd: MTD device structure
...
...
@@ -1590,57 +1564,39 @@ static uint8_t *nand_prepare_oobbuf(struct mtd_info *mtd, uint8_t *fsbuf, struct
#define NOTALIGNED(x) (x & (mtd->writesize-1)) != 0
/**
* nand_write - [MTD Interface] compability function for nand_write_ecc
* @mtd: MTD device structure
* @to: offset to write to
* @len: number of bytes to write
* @retlen: pointer to variable to store the number of written bytes
* @buf: the data to write
*
* This function simply calls nand_write_ecc with oob buffer and oobsel = NULL
*
*/
static
int
nand_write
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
uint8_t
*
buf
)
{
return
(
nand_write_ecc
(
mtd
,
to
,
len
,
retlen
,
buf
,
NULL
,
NULL
));
}
/**
* nand_write_ecc - [MTD Interface] NAND write with ECC
* nand_write - [MTD Interface] NAND write with ECC
* @mtd: MTD device structure
* @to: offset to write to
* @len: number of bytes to write
* @retlen: pointer to variable to store the number of written bytes
* @buf: the data to write
* @eccbuf: filesystem supplied oob data buffer
* @oobsel: oob selection structure
*
* NAND write with ECC
*/
static
int
nand_write_ecc
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
uint8_t
*
buf
,
uint8_t
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
static
int
nand_write
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
uint8_t
*
buf
)
{
int
startpage
,
page
,
ret
=
-
EIO
,
oob
=
0
,
written
=
0
,
chipnr
;
int
autoplace
=
0
,
numpages
,
totalpages
;
struct
nand_chip
*
this
=
mtd
->
priv
;
uint8_t
*
oobbuf
,
*
bufstart
;
uint8_t
*
oobbuf
,
*
bufstart
,
*
eccbuf
=
NULL
;
int
ppblock
=
(
1
<<
(
this
->
phys_erase_shift
-
this
->
page_shift
));
struct
nand_oobinfo
*
oobsel
=
&
mtd
->
oobinfo
;
DEBUG
(
MTD_DEBUG_LEVEL3
,
"nand_write
_ecc
: to = 0x%08x, len = %i
\n
"
,
(
unsigned
int
)
to
,
(
int
)
len
);
DEBUG
(
MTD_DEBUG_LEVEL3
,
"nand_write: to = 0x%08x, len = %i
\n
"
,
(
unsigned
int
)
to
,
(
int
)
len
);
/* Initialize retlen, in case of early exit */
*
retlen
=
0
;
/* Do not allow write past end of device */
if
((
to
+
len
)
>
mtd
->
size
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write
_ecc
: Attempt to write past end of page
\n
"
);
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write: Attempt to write past end of page
\n
"
);
return
-
EINVAL
;
}
/* reject writes, which are not page aligned */
if
(
NOTALIGNED
(
to
)
||
NOTALIGNED
(
len
))
{
printk
(
KERN_NOTICE
"nand_write
_ecc
: Attempt to write not page aligned data
\n
"
);
printk
(
KERN_NOTICE
"nand_write: Attempt to write not page aligned data
\n
"
);
return
-
EINVAL
;
}
...
...
@@ -1656,10 +1612,6 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
if
(
nand_check_wp
(
mtd
))
goto
out
;
/* if oobsel is NULL, use chip defaults */
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
/* Autoplace of oob data ? Use the default placement scheme */
if
(
oobsel
->
useecc
==
MTD_NANDECC_AUTOPLACE
)
{
oobsel
=
this
->
autooob
;
...
...
@@ -1694,7 +1646,7 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
*/
ret
=
nand_write_page
(
mtd
,
this
,
page
,
&
oobbuf
[
oob
],
oobsel
,
(
--
numpages
>
0
));
if
(
ret
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write
_ecc
: write_page failed %d
\n
"
,
ret
);
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write: write_page failed %d
\n
"
,
ret
);
goto
out
;
}
/* Next oob page */
...
...
@@ -1717,7 +1669,7 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
ret
=
nand_verify_pages
(
mtd
,
this
,
startpage
,
page
-
startpage
,
oobbuf
,
oobsel
,
chipnr
,
(
eccbuf
!=
NULL
));
if
(
ret
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write
_ecc
: verify_pages failed %d
\n
"
,
ret
);
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write: verify_pages failed %d
\n
"
,
ret
);
goto
out
;
}
*
retlen
=
written
;
...
...
@@ -1746,7 +1698,7 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
if
(
!
ret
)
*
retlen
=
written
;
else
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write
_ecc
: verify_pages failed %d
\n
"
,
ret
);
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write: verify_pages failed %d
\n
"
,
ret
);
out:
/* Deselect and wake up anyone waiting on the device */
...
...
@@ -1856,187 +1808,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, size_t *r
return
ret
;
}
/**
* nand_writev - [MTD Interface] compabilty function for nand_writev_ecc
* @mtd: MTD device structure
* @vecs: the iovectors to write
* @count: number of vectors
* @to: offset to write to
* @retlen: pointer to variable to store the number of written bytes
*
* NAND write with kvec. This just calls the ecc function
*/
static
int
nand_writev
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
)
{
return
(
nand_writev_ecc
(
mtd
,
vecs
,
count
,
to
,
retlen
,
NULL
,
NULL
));
}
/**
* nand_writev_ecc - [MTD Interface] write with iovec with ecc
* @mtd: MTD device structure
* @vecs: the iovectors to write
* @count: number of vectors
* @to: offset to write to
* @retlen: pointer to variable to store the number of written bytes
* @eccbuf: filesystem supplied oob data buffer
* @oobsel: oob selection structure
*
* NAND write with iovec with ecc
*/
static
int
nand_writev_ecc
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
,
uint8_t
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
{
int
i
,
page
,
len
,
total_len
,
ret
=
-
EIO
,
written
=
0
,
chipnr
;
int
oob
,
numpages
,
autoplace
=
0
,
startpage
;
struct
nand_chip
*
this
=
mtd
->
priv
;
int
ppblock
=
(
1
<<
(
this
->
phys_erase_shift
-
this
->
page_shift
));
uint8_t
*
oobbuf
,
*
bufstart
;
/* Preset written len for early exit */
*
retlen
=
0
;
/* Calculate total length of data */
total_len
=
0
;
for
(
i
=
0
;
i
<
count
;
i
++
)
total_len
+=
(
int
)
vecs
[
i
].
iov_len
;
DEBUG
(
MTD_DEBUG_LEVEL3
,
"nand_writev: to = 0x%08x, len = %i, count = %ld
\n
"
,
(
unsigned
int
)
to
,
(
unsigned
int
)
total_len
,
count
);
/* Do not allow write past end of page */
if
((
to
+
total_len
)
>
mtd
->
size
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_writev: Attempted write past end of device
\n
"
);
return
-
EINVAL
;
}
/* reject writes, which are not page aligned */
if
(
NOTALIGNED
(
to
)
||
NOTALIGNED
(
total_len
))
{
printk
(
KERN_NOTICE
"nand_write_ecc: Attempt to write not page aligned data
\n
"
);
return
-
EINVAL
;
}
/* Grab the lock and see if the device is available */
nand_get_device
(
this
,
mtd
,
FL_WRITING
);
/* Get the current chip-nr */
chipnr
=
(
int
)(
to
>>
this
->
chip_shift
);
/* Select the NAND device */
this
->
select_chip
(
mtd
,
chipnr
);
/* Check, if it is write protected */
if
(
nand_check_wp
(
mtd
))
goto
out
;
/* if oobsel is NULL, use chip defaults */
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
/* Autoplace of oob data ? Use the default placement scheme */
if
(
oobsel
->
useecc
==
MTD_NANDECC_AUTOPLACE
)
{
oobsel
=
this
->
autooob
;
autoplace
=
1
;
}
if
(
oobsel
->
useecc
==
MTD_NANDECC_AUTOPL_USR
)
autoplace
=
1
;
/* Setup start page */
page
=
(
int
)(
to
>>
this
->
page_shift
);
/* Invalidate the page cache, if we write to the cached page */
if
(
page
<=
this
->
pagebuf
&&
this
->
pagebuf
<
((
to
+
total_len
)
>>
this
->
page_shift
))
this
->
pagebuf
=
-
1
;
startpage
=
page
&
this
->
pagemask
;
/* Loop until all kvec' data has been written */
len
=
0
;
while
(
count
)
{
/* If the given tuple is >= pagesize then
* write it out from the iov
*/
if
((
vecs
->
iov_len
-
len
)
>=
mtd
->
writesize
)
{
/* Calc number of pages we can write
* out of this iov in one go */
numpages
=
(
vecs
->
iov_len
-
len
)
>>
this
->
page_shift
;
/* Do not cross block boundaries */
numpages
=
min
(
ppblock
-
(
startpage
&
(
ppblock
-
1
)),
numpages
);
oobbuf
=
nand_prepare_oobbuf
(
mtd
,
NULL
,
oobsel
,
autoplace
,
numpages
);
bufstart
=
(
uint8_t
*
)
vecs
->
iov_base
;
bufstart
+=
len
;
this
->
data_poi
=
bufstart
;
oob
=
0
;
for
(
i
=
1
;
i
<=
numpages
;
i
++
)
{
/* Write one page. If this is the last page to write
* then use the real pageprogram command, else select
* cached programming if supported by the chip.
*/
ret
=
nand_write_page
(
mtd
,
this
,
page
&
this
->
pagemask
,
&
oobbuf
[
oob
],
oobsel
,
i
!=
numpages
);
if
(
ret
)
goto
out
;
this
->
data_poi
+=
mtd
->
writesize
;
len
+=
mtd
->
writesize
;
oob
+=
mtd
->
oobsize
;
page
++
;
}
/* Check, if we have to switch to the next tuple */
if
(
len
>=
(
int
)
vecs
->
iov_len
)
{
vecs
++
;
len
=
0
;
count
--
;
}
}
else
{
/* We must use the internal buffer, read data out of each
* tuple until we have a full page to write
*/
int
cnt
=
0
;
while
(
cnt
<
mtd
->
writesize
)
{
if
(
vecs
->
iov_base
!=
NULL
&&
vecs
->
iov_len
)
this
->
data_buf
[
cnt
++
]
=
((
uint8_t
*
)
vecs
->
iov_base
)[
len
++
];
/* Check, if we have to switch to the next tuple */
if
(
len
>=
(
int
)
vecs
->
iov_len
)
{
vecs
++
;
len
=
0
;
count
--
;
}
}
this
->
pagebuf
=
page
;
this
->
data_poi
=
this
->
data_buf
;
bufstart
=
this
->
data_poi
;
numpages
=
1
;
oobbuf
=
nand_prepare_oobbuf
(
mtd
,
NULL
,
oobsel
,
autoplace
,
numpages
);
ret
=
nand_write_page
(
mtd
,
this
,
page
&
this
->
pagemask
,
oobbuf
,
oobsel
,
0
);
if
(
ret
)
goto
out
;
page
++
;
}
this
->
data_poi
=
bufstart
;
ret
=
nand_verify_pages
(
mtd
,
this
,
startpage
,
numpages
,
oobbuf
,
oobsel
,
chipnr
,
0
);
if
(
ret
)
goto
out
;
written
+=
mtd
->
writesize
*
numpages
;
/* All done ? */
if
(
!
count
)
break
;
startpage
=
page
&
this
->
pagemask
;
/* Check, if we cross a chip boundary */
if
(
!
startpage
)
{
chipnr
++
;
this
->
select_chip
(
mtd
,
-
1
);
this
->
select_chip
(
mtd
,
chipnr
);
}
}
ret
=
0
;
out:
/* Deselect and wake up anyone waiting on the device */
nand_release_device
(
mtd
);
*
retlen
=
written
;
return
ret
;
}
/**
* single_erease_cmd - [GENERIC] NAND standard block erase command function
* @mtd: MTD device structure
...
...
@@ -2392,12 +2163,8 @@ static void nand_set_defaults(struct nand_chip *this, int busw)
if
(
!
this
->
select_chip
)
this
->
select_chip
=
nand_select_chip
;
if
(
!
this
->
write_byte
)
this
->
write_byte
=
busw
?
nand_write_byte16
:
nand_write_byte
;
if
(
!
this
->
read_byte
)
this
->
read_byte
=
busw
?
nand_read_byte16
:
nand_read_byte
;
if
(
!
this
->
write_word
)
this
->
write_word
=
nand_write_word
;
if
(
!
this
->
read_word
)
this
->
read_word
=
nand_read_word
;
if
(
!
this
->
block_bad
)
...
...
@@ -2713,13 +2480,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
mtd
->
unpoint
=
NULL
;
mtd
->
read
=
nand_read
;
mtd
->
write
=
nand_write
;
mtd
->
read_ecc
=
nand_read_ecc
;
mtd
->
write_ecc
=
nand_write_ecc
;
mtd
->
read_oob
=
nand_read_oob
;
mtd
->
write_oob
=
nand_write_oob
;
mtd
->
readv
=
NULL
;
mtd
->
writev
=
nand_writev
;
mtd
->
writev_ecc
=
nand_writev_ecc
;
mtd
->
sync
=
nand_sync
;
mtd
->
lock
=
NULL
;
mtd
->
unlock
=
NULL
;
...
...
drivers/mtd/nand/nand_bbt.c
View file @
0305c865
...
...
@@ -156,7 +156,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
while
(
totlen
)
{
len
=
min
(
totlen
,
(
size_t
)
(
1
<<
this
->
bbt_erase_shift
));
res
=
mtd
->
read
_ecc
(
mtd
,
from
,
len
,
&
retlen
,
buf
,
NULL
,
this
->
autooob
);
res
=
mtd
->
read
(
mtd
,
from
,
len
,
&
retlen
,
buf
);
if
(
res
<
0
)
{
if
(
retlen
!=
len
)
{
printk
(
KERN_INFO
"nand_bbt: Error reading bad block table
\n
"
);
...
...
@@ -471,17 +471,17 @@ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt
*
*/
static
int
write_bbt
(
struct
mtd_info
*
mtd
,
uint8_t
*
buf
,
struct
nand_bbt_descr
*
td
,
struct
nand_bbt_descr
*
md
,
int
chipsel
)
struct
nand_bbt_descr
*
td
,
struct
nand_bbt_descr
*
md
,
int
chipsel
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
struct
nand_oobinfo
oobinfo
;
struct
erase_info
einfo
;
int
i
,
j
,
res
,
chip
=
0
;
int
bits
,
startblock
,
dir
,
page
,
offs
,
numblocks
,
sft
,
sftmsk
;
int
nrchips
,
bbtoffs
,
pageoffs
;
int
nrchips
,
bbtoffs
,
pageoffs
,
ooboffs
;
uint8_t
msk
[
4
];
uint8_t
rcode
=
td
->
reserved_block_code
;
size_t
retlen
,
len
=
0
;
size_t
retlen
,
len
=
0
,
ooblen
;
loff_t
to
;
if
(
!
rcode
)
...
...
@@ -526,12 +526,14 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
for
(
i
=
0
;
i
<
td
->
maxblocks
;
i
++
)
{
int
block
=
startblock
+
dir
*
i
;
/* Check, if the block is bad */
switch
((
this
->
bbt
[
block
>>
2
]
>>
(
2
*
(
block
&
0x03
)))
&
0x03
)
{
switch
((
this
->
bbt
[
block
>>
2
]
>>
(
2
*
(
block
&
0x03
)))
&
0x03
)
{
case
0x01
:
case
0x03
:
continue
;
}
page
=
block
<<
(
this
->
bbt_erase_shift
-
this
->
page_shift
);
page
=
block
<<
(
this
->
bbt_erase_shift
-
this
->
page_shift
);
/* Check, if the block is used by the mirror table */
if
(
!
md
||
md
->
pages
[
chip
]
!=
page
)
goto
write
;
...
...
@@ -542,11 +544,20 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
/* Set up shift count and masks for the flash table */
bits
=
td
->
options
&
NAND_BBT_NRBITS_MSK
;
msk
[
2
]
=
~
rcode
;
switch
(
bits
)
{
case
1
:
sft
=
3
;
sftmsk
=
0x07
;
msk
[
0
]
=
0x00
;
msk
[
1
]
=
0x01
;
msk
[
2
]
=
~
rcode
;
msk
[
3
]
=
0x01
;
break
;
case
2
:
sft
=
2
;
sftmsk
=
0x06
;
msk
[
0
]
=
0x00
;
msk
[
1
]
=
0x01
;
msk
[
2
]
=
~
rcode
;
msk
[
3
]
=
0x03
;
break
;
case
4
:
sft
=
1
;
sftmsk
=
0x04
;
msk
[
0
]
=
0x00
;
msk
[
1
]
=
0x0C
;
msk
[
2
]
=
~
rcode
;
msk
[
3
]
=
0x0f
;
break
;
case
8
:
sft
=
0
;
sftmsk
=
0x00
;
msk
[
0
]
=
0x00
;
msk
[
1
]
=
0x0F
;
msk
[
2
]
=
~
rcode
;
msk
[
3
]
=
0xff
;
break
;
case
1
:
sft
=
3
;
sftmsk
=
0x07
;
msk
[
0
]
=
0x00
;
msk
[
1
]
=
0x01
;
msk
[
3
]
=
0x01
;
break
;
case
2
:
sft
=
2
;
sftmsk
=
0x06
;
msk
[
0
]
=
0x00
;
msk
[
1
]
=
0x01
;
msk
[
3
]
=
0x03
;
break
;
case
4
:
sft
=
1
;
sftmsk
=
0x04
;
msk
[
0
]
=
0x00
;
msk
[
1
]
=
0x0C
;
msk
[
3
]
=
0x0f
;
break
;
case
8
:
sft
=
0
;
sftmsk
=
0x00
;
msk
[
0
]
=
0x00
;
msk
[
1
]
=
0x0F
;
msk
[
3
]
=
0xff
;
break
;
default:
return
-
EINVAL
;
}
...
...
@@ -554,49 +565,55 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
to
=
((
loff_t
)
page
)
<<
this
->
page_shift
;
memcpy
(
&
oobinfo
,
this
->
autooob
,
sizeof
(
oobinfo
));
oobinfo
.
useecc
=
MTD_NANDECC_PLACEONLY
;
/* Must we save the block contents ? */
if
(
td
->
options
&
NAND_BBT_SAVECONTENT
)
{
/* Make it block aligned */
to
&=
~
((
loff_t
)
((
1
<<
this
->
bbt_erase_shift
)
-
1
));
len
=
1
<<
this
->
bbt_erase_shift
;
res
=
mtd
->
read
_ecc
(
mtd
,
to
,
len
,
&
retlen
,
buf
,
&
buf
[
len
],
&
oobinfo
);
res
=
mtd
->
read
(
mtd
,
to
,
len
,
&
retlen
,
buf
);
if
(
res
<
0
)
{
if
(
retlen
!=
len
)
{
printk
(
KERN_INFO
"nand_bbt: Error reading block for writing the bad block table
\n
"
);
printk
(
KERN_INFO
"nand_bbt: Error "
"reading block for writing "
"the bad block table
\n
"
);
return
res
;
}
printk
(
KERN_WARNING
"nand_bbt: ECC error while reading block for writing bad block table
\n
"
);
printk
(
KERN_WARNING
"nand_bbt: ECC error "
"while reading block for writing "
"bad block table
\n
"
);
}
/* Read oob data */
ooblen
=
(
len
>>
this
->
page_shift
)
*
mtd
->
oobsize
;
res
=
mtd
->
read_oob
(
mtd
,
to
+
mtd
->
writesize
,
ooblen
,
&
retlen
,
&
buf
[
len
]);
if
(
res
<
0
||
retlen
!=
ooblen
)
goto
outerr
;
/* Calc the byte offset in the buffer */
pageoffs
=
page
-
(
int
)(
to
>>
this
->
page_shift
);
offs
=
pageoffs
<<
this
->
page_shift
;
/* Preset the bbt area with 0xff */
memset
(
&
buf
[
offs
],
0xff
,
(
size_t
)
(
numblocks
>>
sft
));
/* Preset the bbt's oob area with 0xff */
memset
(
&
buf
[
len
+
pageoffs
*
mtd
->
oobsize
],
0xff
,
((
len
>>
this
->
page_shift
)
-
pageoffs
)
*
mtd
->
oobsize
);
if
(
td
->
options
&
NAND_BBT_VERSION
)
{
buf
[
len
+
(
pageoffs
*
mtd
->
oobsize
)
+
td
->
veroffs
]
=
td
->
version
[
chip
];
}
ooboffs
=
len
+
(
pageoffs
*
mtd
->
oobsize
);
}
else
{
/* Calc length */
len
=
(
size_t
)
(
numblocks
>>
sft
);
/* Make it page aligned ! */
len
=
(
len
+
(
mtd
->
writesize
-
1
))
&
~
(
mtd
->
writesize
-
1
);
len
=
(
len
+
(
mtd
->
writesize
-
1
))
&
~
(
mtd
->
writesize
-
1
);
/* Preset the buffer with 0xff */
memset
(
buf
,
0xff
,
len
+
(
len
>>
this
->
page_shift
)
*
mtd
->
oobsize
);
memset
(
buf
,
0xff
,
len
+
(
len
>>
this
->
page_shift
)
*
mtd
->
oobsize
);
offs
=
0
;
ooboffs
=
len
;
/* Pattern is located in oob area of first page */
memcpy
(
&
buf
[
len
+
td
->
offs
],
td
->
pattern
,
td
->
len
);
if
(
td
->
options
&
NAND_BBT_VERSION
)
{
buf
[
len
+
td
->
veroffs
]
=
td
->
version
[
chip
];
}
memcpy
(
&
buf
[
ooboffs
+
td
->
offs
],
td
->
pattern
,
td
->
len
);
}
if
(
td
->
options
&
NAND_BBT_VERSION
)
buf
[
ooboffs
+
td
->
veroffs
]
=
td
->
version
[
chip
];
/* walk through the memory table */
for
(
i
=
0
;
i
<
numblocks
;)
{
uint8_t
dat
;
...
...
@@ -604,7 +621,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
for
(
j
=
0
;
j
<
4
;
j
++
,
i
++
)
{
int
sftcnt
=
(
i
<<
(
3
-
sft
))
&
sftmsk
;
/* Do not store the reserved bbt blocks ! */
buf
[
offs
+
(
i
>>
sft
)]
&=
~
(
msk
[
dat
&
0x03
]
<<
sftcnt
);
buf
[
offs
+
(
i
>>
sft
)]
&=
~
(
msk
[
dat
&
0x03
]
<<
sftcnt
);
dat
>>=
2
;
}
}
...
...
@@ -614,23 +632,25 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
einfo
.
addr
=
(
unsigned
long
)
to
;
einfo
.
len
=
1
<<
this
->
bbt_erase_shift
;
res
=
nand_erase_nand
(
mtd
,
&
einfo
,
1
);
if
(
res
<
0
)
{
printk
(
KERN_WARNING
"nand_bbt: Error during block erase: %d
\n
"
,
res
);
return
res
;
}
if
(
res
<
0
)
goto
outerr
;
res
=
mtd
->
write_ecc
(
mtd
,
to
,
len
,
&
retlen
,
buf
,
&
buf
[
len
],
&
oobinfo
);
if
(
res
<
0
)
{
printk
(
KERN_WARNING
"nand_bbt: Error while writing bad block table %d
\n
"
,
res
);
return
res
;
}
printk
(
KERN_DEBUG
"Bad block table written to 0x%08x, version 0x%02X
\n
"
,
(
unsigned
int
)
to
,
td
->
version
[
chip
]);
res
=
nand_write_raw
(
mtd
,
to
,
len
,
&
retlen
,
buf
,
&
buf
[
len
]);
if
(
res
<
0
)
goto
outerr
;
printk
(
KERN_DEBUG
"Bad block table written to 0x%08x, version "
"0x%02X
\n
"
,
(
unsigned
int
)
to
,
td
->
version
[
chip
]);
/* Mark it as used */
td
->
pages
[
chip
]
=
page
;
}
return
0
;
outerr:
printk
(
KERN_WARNING
"nand_bbt: Error while writing bad block table %d
\n
"
,
res
);
return
res
;
}
/**
...
...
drivers/mtd/nand/nandsim.c
View file @
0305c865
...
...
@@ -1071,68 +1071,6 @@ switch_state(struct nandsim *ns)
}
}
static
void
ns_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
{
struct
nandsim
*
ns
=
(
struct
nandsim
*
)((
struct
nand_chip
*
)
mtd
->
priv
)
->
priv
;
switch
(
cmd
)
{
/* set CLE line high */
case
NAND_CTL_SETCLE
:
NS_DBG
(
"ns_hwcontrol: start command latch cycles
\n
"
);
ns
->
lines
.
cle
=
1
;
break
;
/* set CLE line low */
case
NAND_CTL_CLRCLE
:
NS_DBG
(
"ns_hwcontrol: stop command latch cycles
\n
"
);
ns
->
lines
.
cle
=
0
;
break
;
/* set ALE line high */
case
NAND_CTL_SETALE
:
NS_DBG
(
"ns_hwcontrol: start address latch cycles
\n
"
);
ns
->
lines
.
ale
=
1
;
break
;
/* set ALE line low */
case
NAND_CTL_CLRALE
:
NS_DBG
(
"ns_hwcontrol: stop address latch cycles
\n
"
);
ns
->
lines
.
ale
=
0
;
break
;
/* set WP line high */
case
NAND_CTL_SETWP
:
NS_DBG
(
"ns_hwcontrol: enable write protection
\n
"
);
ns
->
lines
.
wp
=
1
;
break
;
/* set WP line low */
case
NAND_CTL_CLRWP
:
NS_DBG
(
"ns_hwcontrol: disable write protection
\n
"
);
ns
->
lines
.
wp
=
0
;
break
;
/* set CE line low */
case
NAND_CTL_SETNCE
:
NS_DBG
(
"ns_hwcontrol: enable chip
\n
"
);
ns
->
lines
.
ce
=
1
;
break
;
/* set CE line high */
case
NAND_CTL_CLRNCE
:
NS_DBG
(
"ns_hwcontrol: disable chip
\n
"
);
ns
->
lines
.
ce
=
0
;
break
;
default:
NS_ERR
(
"hwcontrol: unknown command
\n
"
);
}
return
;
}
static
u_char
ns_nand_read_byte
(
struct
mtd_info
*
mtd
)
{
...
...
@@ -1359,6 +1297,18 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
return
;
}
static
void
ns_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
bitmask
)
{
struct
nandsim
*
ns
=
((
struct
nand_chip
*
)
mtd
->
priv
)
->
priv
;
ns
->
lines
.
cle
=
bitmask
&
NAND_CLE
?
1
:
0
;
ns
->
lines
.
ale
=
bitmask
&
NAND_ALE
?
1
:
0
;
ns
->
lines
.
ce
=
bitmask
&
NAND_NCE
?
1
:
0
;
if
(
cmd
!=
NAND_CMD_NONE
)
ns_nand_write_byte
(
mtd
,
cmd
);
}
static
int
ns_device_ready
(
struct
mtd_info
*
mtd
)
{
...
...
@@ -1376,17 +1326,6 @@ ns_nand_read_word(struct mtd_info *mtd)
return
chip
->
read_byte
(
mtd
)
|
(
chip
->
read_byte
(
mtd
)
<<
8
);
}
static
void
ns_nand_write_word
(
struct
mtd_info
*
mtd
,
uint16_t
word
)
{
struct
nand_chip
*
chip
=
(
struct
nand_chip
*
)
mtd
->
priv
;
NS_DBG
(
"write_word
\n
"
);
chip
->
write_byte
(
mtd
,
word
&
0xFF
);
chip
->
write_byte
(
mtd
,
word
>>
8
);
}
static
void
ns_nand_write_buf
(
struct
mtd_info
*
mtd
,
const
u_char
*
buf
,
int
len
)
{
...
...
@@ -1514,14 +1453,12 @@ static int __init ns_init_module(void)
/*
* Register simulator's callbacks.
*/
chip
->
hwcontrol
=
ns_hwcontrol
;
chip
->
cmd_ctrl
=
ns_hwcontrol
;
chip
->
read_byte
=
ns_nand_read_byte
;
chip
->
dev_ready
=
ns_device_ready
;
chip
->
write_byte
=
ns_nand_write_byte
;
chip
->
write_buf
=
ns_nand_write_buf
;
chip
->
read_buf
=
ns_nand_read_buf
;
chip
->
verify_buf
=
ns_nand_verify_buf
;
chip
->
write_word
=
ns_nand_write_word
;
chip
->
read_word
=
ns_nand_read_word
;
chip
->
ecc
.
mode
=
NAND_ECC_SOFT
;
chip
->
options
|=
NAND_SKIP_BBTSCAN
;
...
...
drivers/mtd/nand/ndfc.c
View file @
0305c865
...
...
@@ -60,22 +60,17 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip)
writel
(
ccr
,
ndfc
->
ndfcbase
+
NDFC_CCR
);
}
static
void
ndfc_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
static
void
ndfc_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
struct
ndfc_controller
*
ndfc
=
&
ndfc_ctrl
;
struct
nand_chip
*
chip
=
mtd
->
priv
;
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
chip
->
IO_ADDR_W
=
ndfc
->
ndfcbase
+
NDFC_CMD
;
break
;
case
NAND_CTL_SETALE
:
chip
->
IO_ADDR_W
=
ndfc
->
ndfcbase
+
NDFC_ALE
;
break
;
default:
chip
->
IO_ADDR_W
=
ndfc
->
ndfcbase
+
NDFC_DATA
;
break
;
}
if
(
cmd
==
NAND_CMD_NONE
)
return
;
if
(
ctrl
&
NAND_CLE
)
writel
(
cmd
&
0xFF
,
chip
->
IO_ADDR_W
+
NDFC_CMD
);
else
writel
(
cmd
&
0xFF
,
chip
->
IO_ADDR_W
+
NDFC_ALE
);
}
static
int
ndfc_ready
(
struct
mtd_info
*
mtd
)
...
...
@@ -158,7 +153,7 @@ static void ndfc_chip_init(struct ndfc_nand_mtd *mtd)
chip
->
IO_ADDR_R
=
ndfc
->
ndfcbase
+
NDFC_DATA
;
chip
->
IO_ADDR_W
=
ndfc
->
ndfcbase
+
NDFC_DATA
;
chip
->
hwcontro
l
=
ndfc_hwcontrol
;
chip
->
cmd_ctr
l
=
ndfc_hwcontrol
;
chip
->
dev_ready
=
ndfc_ready
;
chip
->
select_chip
=
ndfc_select_chip
;
chip
->
chip_delay
=
50
;
...
...
drivers/mtd/nand/ppchameleonevb.c
View file @
0305c865
...
...
@@ -108,10 +108,14 @@ extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partitio
/*
* hardware specific access to control-lines
*/
static
void
ppchameleon_hwcontrol
(
struct
mtd_info
*
mtdinfo
,
int
cmd
)
static
void
ppchameleon_hwcontrol
(
struct
mtd_info
*
mtdinfo
,
int
cmd
,
unsigned
int
ctrl
)
{
s
witch
(
cmd
)
{
s
truct
nand_chip
*
chip
=
mtd
->
priv
;
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
#error Missing headerfiles. No way to fix this. -tglx
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
MACRO_NAND_CTL_SETCLE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
...
...
@@ -131,12 +135,19 @@ static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd)
MACRO_NAND_DISABLE_CE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
}
}
if
(
cmd
!=
NAND_CMD_NONE
)
writeb
(
cmd
,
chip
->
IO_ADDR_W
);
}
static
void
ppchameleonevb_hwcontrol
(
struct
mtd_info
*
mtdinfo
,
int
cmd
)
static
void
ppchameleonevb_hwcontrol
(
struct
mtd_info
*
mtdinfo
,
int
cmd
,
unsigned
int
ctrl
)
{
s
witch
(
cmd
)
{
s
truct
nand_chip
*
chip
=
mtd
->
priv
;
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
#error Missing headerfiles. No way to fix this. -tglx
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
MACRO_NAND_CTL_SETCLE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
...
...
@@ -156,6 +167,9 @@ static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd)
MACRO_NAND_DISABLE_CE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
}
}
if
(
cmd
!=
NAND_CMD_NONE
)
writeb
(
cmd
,
chip
->
IO_ADDR_W
);
}
#ifdef USE_READY_BUSY_PIN
...
...
@@ -251,7 +265,7 @@ static int __init ppchameleonevb_init(void)
/* insert callbacks */
this
->
IO_ADDR_R
=
ppchameleon_fio_base
;
this
->
IO_ADDR_W
=
ppchameleon_fio_base
;
this
->
hwcontro
l
=
ppchameleon_hwcontrol
;
this
->
cmd_ctr
l
=
ppchameleon_hwcontrol
;
#ifdef USE_READY_BUSY_PIN
this
->
dev_ready
=
ppchameleon_device_ready
;
#endif
...
...
@@ -351,7 +365,7 @@ static int __init ppchameleonevb_init(void)
/* insert callbacks */
this
->
IO_ADDR_R
=
ppchameleonevb_fio_base
;
this
->
IO_ADDR_W
=
ppchameleonevb_fio_base
;
this
->
hwcontro
l
=
ppchameleonevb_hwcontrol
;
this
->
cmd_ctr
l
=
ppchameleonevb_hwcontrol
;
#ifdef USE_READY_BUSY_PIN
this
->
dev_ready
=
ppchameleonevb_device_ready
;
#endif
...
...
drivers/mtd/nand/rtc_from4.c
View file @
0305c865
...
...
@@ -208,32 +208,18 @@ static uint8_t revbits[256] = {
* Address lines (A24-A22), so no action is required here.
*
*/
static
void
rtc_from4_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
static
void
rtc_from4_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
struct
nand_chip
*
this
=
(
struct
nand_chip
*
)
(
mtd
->
priv
);
struct
nand_chip
*
chip
=
(
mtd
->
priv
);
switch
(
cmd
)
{
if
(
cmd
==
NAND_CMD_NONE
)
return
;
case
NAND_CTL_SETCLE
:
this
->
IO_ADDR_W
=
(
void
__iomem
*
)((
unsigned
long
)
this
->
IO_ADDR_W
|
RTC_FROM4_CLE
);
break
;
case
NAND_CTL_CLRCLE
:
this
->
IO_ADDR_W
=
(
void
__iomem
*
)((
unsigned
long
)
this
->
IO_ADDR_W
&
~
RTC_FROM4_CLE
);
break
;
case
NAND_CTL_SETALE
:
this
->
IO_ADDR_W
=
(
void
__iomem
*
)((
unsigned
long
)
this
->
IO_ADDR_W
|
RTC_FROM4_ALE
);
break
;
case
NAND_CTL_CLRALE
:
this
->
IO_ADDR_W
=
(
void
__iomem
*
)((
unsigned
long
)
this
->
IO_ADDR_W
&
~
RTC_FROM4_ALE
);
break
;
case
NAND_CTL_SETNCE
:
break
;
case
NAND_CTL_CLRNCE
:
break
;
}
if
(
ctrl
&
NAND_CLE
)
writeb
(
cmd
,
chip
->
IO_ADDR_W
|
RTC_FROM4_CLE
);
else
writeb
(
cmd
,
chip
->
IO_ADDR_W
|
RTC_FROM4_ALE
);
}
/*
...
...
@@ -559,7 +545,7 @@ static int __init rtc_from4_init(void)
this
->
IO_ADDR_R
=
rtc_from4_fio_base
;
this
->
IO_ADDR_W
=
rtc_from4_fio_base
;
/* Set address of hardware control function */
this
->
hwcontro
l
=
rtc_from4_hwcontrol
;
this
->
cmd_ctr
l
=
rtc_from4_hwcontrol
;
/* Set address of chip select function */
this
->
select_chip
=
rtc_from4_nand_select_chip
;
/* command delay time (in us) */
...
...
drivers/mtd/nand/s3c2410.c
View file @
0305c865
...
...
@@ -256,60 +256,36 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
*
*/
static
void
s3c2410_nand_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
static
void
s3c2410_nand_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigend
int
ctrl
)
{
struct
s3c2410_nand_info
*
info
=
s3c2410_nand_mtd_toinfo
(
mtd
);
struct
nand_chip
*
chip
=
mtd
->
priv
;
switch
(
cmd
)
{
case
NAND_CTL_SETNCE
:
case
NAND_CTL_CLRNCE
:
printk
(
KERN_ERR
"%s: called for NCE
\n
"
,
__FUNCTION__
);
break
;
case
NAND_CTL_SETCLE
:
chip
->
IO_ADDR_W
=
info
->
regs
+
S3C2410_NFCMD
;
break
;
case
NAND_CTL_SETALE
:
chip
->
IO_ADDR_W
=
info
->
regs
+
S3C2410_NFADDR
;
break
;
if
(
cmd
==
NAND_CMD_NONE
)
return
;
/* NAND_CTL_CLRCLE: */
/* NAND_CTL_CLRALE: */
default:
chip
->
IO_ADDR_W
=
info
->
regs
+
S3C2410_NFDATA
;
break
;
}
if
(
cmd
&
NAND_CLE
)
writeb
(
cmd
,
info
->
regs
+
S3C2410_NFCMD
);
else
writeb
(
cmd
,
info
->
regs
+
S3C2410_NFADDR
);
}
/* command and control functions */
static
void
s3c2440_nand_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
static
void
s3c2410_nand_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigend
int
ctrl
)
{
struct
s3c2410_nand_info
*
info
=
s3c2410_nand_mtd_toinfo
(
mtd
);
struct
nand_chip
*
chip
=
mtd
->
priv
;
switch
(
cmd
)
{
case
NAND_CTL_SETNCE
:
case
NAND_CTL_CLRNCE
:
printk
(
KERN_ERR
"%s: called for NCE
\n
"
,
__FUNCTION__
);
break
;
case
NAND_CTL_SETCLE
:
chip
->
IO_ADDR_W
=
info
->
regs
+
S3C2440_NFCMD
;
break
;
case
NAND_CTL_SETALE
:
chip
->
IO_ADDR_W
=
info
->
regs
+
S3C2440_NFADDR
;
break
;
if
(
cmd
==
NAND_CMD_NONE
)
return
;
/* NAND_CTL_CLRCLE: */
/* NAND_CTL_CLRALE: */
default:
chip
->
IO_ADDR_W
=
info
->
regs
+
S3C2440_NFDATA
;
break
;
}
if
(
cmd
&
NAND_CLE
)
writeb
(
cmd
,
info
->
regs
+
S3C2440_NFCMD
);
else
writeb
(
cmd
,
info
->
regs
+
S3C2440_NFADDR
);
}
/* s3c2410_nand_devready()
...
...
@@ -498,7 +474,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
chip
->
IO_ADDR_R
=
info
->
regs
+
S3C2410_NFDATA
;
chip
->
IO_ADDR_W
=
info
->
regs
+
S3C2410_NFDATA
;
chip
->
hwcontrol
=
s3c2410_nand_hwcontrol
;
chip
->
cmd_ctrl
=
s3c2410_nand_hwcontrol
;
chip
->
dev_ready
=
s3c2410_nand_devready
;
chip
->
write_buf
=
s3c2410_nand_write_buf
;
chip
->
read_buf
=
s3c2410_nand_read_buf
;
...
...
@@ -511,7 +487,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
if
(
info
->
is_s3c2440
)
{
chip
->
IO_ADDR_R
=
info
->
regs
+
S3C2440_NFDATA
;
chip
->
IO_ADDR_W
=
info
->
regs
+
S3C2440_NFDATA
;
chip
->
hwcontrol
=
s3c2440_nand_hwcontrol
;
chip
->
cmd_ctrl
=
s3c2440_nand_hwcontrol
;
}
nmtd
->
info
=
info
;
...
...
drivers/mtd/nand/sharpsl.c
View file @
0305c865
...
...
@@ -77,31 +77,26 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = {
/*
* hardware specific access to control-lines
* ctrl:
* NAND_CNE: bit 0 -> bit 0 & 4
* NAND_CLE: bit 1 -> bit 1
* NAND_ALE: bit 2 -> bit 2
*
*/
static
void
sharpsl_nand_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
static
void
sharpsl_nand_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
writeb
(
readb
(
FLASHCTL
)
|
FLCLE
,
FLASHCTL
);
break
;
case
NAND_CTL_CLRCLE
:
writeb
(
readb
(
FLASHCTL
)
&
~
FLCLE
,
FLASHCTL
);
break
;
case
NAND_CTL_SETALE
:
writeb
(
readb
(
FLASHCTL
)
|
FLALE
,
FLASHCTL
);
break
;
case
NAND_CTL_CLRALE
:
writeb
(
readb
(
FLASHCTL
)
&
~
FLALE
,
FLASHCTL
);
break
;
case
NAND_CTL_SETNCE
:
writeb
(
readb
(
FLASHCTL
)
&
~
(
FLCE0
|
FLCE1
),
FLASHCTL
);
break
;
case
NAND_CTL_CLRNCE
:
writeb
(
readb
(
FLASHCTL
)
|
(
FLCE0
|
FLCE1
),
FLASHCTL
);
break
;
struct
nand_chip
*
chip
=
mtd
->
priv
;
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
unsigned
char
bits
=
ctrl
&
0x07
;
bits
|=
(
ctrl
&
0x01
)
<<
4
;
writeb
((
readb
(
FLASHCTL
)
&
0x17
)
|
bits
,
FLASHCTL
);
}
if
(
cmd
!=
NAND_CMD_NONE
)
writeb
(
cmd
,
chip
->
IO_ADDR_W
);
}
static
uint8_t
scan_ff_pattern
[]
=
{
0xff
,
0xff
};
...
...
@@ -196,7 +191,7 @@ static int __init sharpsl_nand_init(void)
this
->
IO_ADDR_R
=
FLASHIO
;
this
->
IO_ADDR_W
=
FLASHIO
;
/* Set address of hardware control function */
this
->
hwcontro
l
=
sharpsl_nand_hwcontrol
;
this
->
cmd_ctr
l
=
sharpsl_nand_hwcontrol
;
this
->
dev_ready
=
sharpsl_nand_dev_ready
;
/* 15 us command delay time */
this
->
chip_delay
=
15
;
...
...
drivers/mtd/nand/spia.c
View file @
0305c865
...
...
@@ -82,20 +82,27 @@ static const struct mtd_partition partition_info[] = {
/*
* hardware specific access to control-lines
*/
*
* ctrl:
* NAND_CNE: bit 0 -> bit 2
* NAND_CLE: bit 1 -> bit 0
* NAND_ALE: bit 2 -> bit 1
*/
static
void
spia_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
{
s
witch
(
cmd
)
{
s
truct
nand_chip
*
chip
=
mtd
->
priv
;
case
NAND_CTL_SETCLE
:
(
*
(
volatile
unsigned
char
*
)
(
spia_io_base
+
spia_pedr
))
|=
0x01
;
break
;
case
NAND_CTL_CLRCLE
:
(
*
(
volatile
unsigned
char
*
)
(
spia_io_base
+
spia_pedr
))
&=
~
0x01
;
break
;
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
void
__iomem
*
addr
=
spia_io_base
+
spia_pedr
;
unsigned
char
bits
;
case
NAND_CTL_SETALE
:
(
*
(
volatile
unsigned
char
*
)
(
spia_io_base
+
spia_pedr
))
|=
0x02
;
break
;
case
NAND_CTL_CLRALE
:
(
*
(
volatile
unsigned
char
*
)
(
spia_io_base
+
spia_pedr
))
&=
~
0x02
;
break
;
case
NAND_CTL_SETNCE
:
(
*
(
volatile
unsigned
char
*
)
(
spia_io_base
+
spia_pedr
))
&=
~
0x04
;
break
;
case
NAND_CTL_CLRNCE
:
(
*
(
volatile
unsigned
char
*
)
(
spia_io_base
+
spia_pedr
))
|=
0x04
;
break
;
bits
=
(
ctrl
&
NAND_CNE
)
<<
2
;
bits
|=
(
ctrl
&
NAND_CLE
|
NAND_ALE
)
>>
1
;
writeb
((
readb
(
addr
)
&
~
0x7
)
|
bits
,
addr
);
}
if
(
cmd
!=
NAND_CMD_NONE
)
writeb
(
cmd
,
chip
->
IO_ADDR_W
);
}
/*
...
...
@@ -133,7 +140,7 @@ static int __init spia_init(void)
this
->
IO_ADDR_R
=
(
void
__iomem
*
)
spia_fio_base
;
this
->
IO_ADDR_W
=
(
void
__iomem
*
)
spia_fio_base
;
/* Set address of hardware control function */
this
->
hwcontro
l
=
spia_hwcontrol
;
this
->
cmd_ctr
l
=
spia_hwcontrol
;
/* 15 us command delay time */
this
->
chip_delay
=
15
;
...
...
drivers/mtd/nand/toto.c
View file @
0305c865
...
...
@@ -32,6 +32,8 @@
#include <asm/arch-omap1510/hardware.h>
#include <asm/arch/gpio.h>
#define CONFIG_NAND_WORKAROUND 1
/*
* MTD structure for TOTO board
*/
...
...
@@ -39,25 +41,6 @@ static struct mtd_info *toto_mtd = NULL;
static
unsigned
long
toto_io_base
=
OMAP_FLASH_1_BASE
;
#define CONFIG_NAND_WORKAROUND 1
#define NAND_NCE 0x4000
#define NAND_CLE 0x1000
#define NAND_ALE 0x0002
#define NAND_MASK (NAND_CLE | NAND_ALE | NAND_NCE)
#define T_NAND_CTL_CLRALE(iob) gpiosetout(NAND_ALE, 0)
#define T_NAND_CTL_SETALE(iob) gpiosetout(NAND_ALE, NAND_ALE)
#ifdef CONFIG_NAND_WORKAROUND
/* "some" dev boards busted, blue wired to rts2 :( */
#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0); rts2setout(2, 2)
#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE); rts2setout(2, 0)
#else
#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0)
#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE)
#endif
#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
/*
* Define partitions for flash devices
*/
...
...
@@ -91,25 +74,43 @@ static struct mtd_partition partition_info32M[] = {
#define NUM_PARTITIONS32M 3
#define NUM_PARTITIONS64M 4
/*
* hardware specific access to control-lines
*/
static
void
toto_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
*
* ctrl:
* NAND_NCE: bit 0 -> bit 14 (0x4000)
* NAND_CLE: bit 1 -> bit 12 (0x1000)
* NAND_ALE: bit 2 -> bit 1 (0x0002)
*/
static
void
toto_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
struct
nand_chip
*
chip
=
mtd
->
priv
;
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
unsigned
long
bits
;
udelay
(
1
);
/* hopefully enough time for tc make proceding write to clear */
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
T_NAND_CTL_SETCLE
(
cmd
);
break
;
case
NAND_CTL_CLRCLE
:
T_NAND_CTL_CLRCLE
(
cmd
);
break
;
/* hopefully enough time for tc make proceding write to clear */
udelay
(
1
);
case
NAND_CTL_SETALE
:
T_NAND_CTL_SETALE
(
cmd
);
break
;
case
NAND_CTL_CLRALE
:
T_NAND_CTL_CLRALE
(
cmd
);
break
;
bits
=
(
~
ctrl
&
NAND_NCE
)
<<
14
;
bits
|=
(
ctrl
&
NAND_CLE
)
<<
12
;
bits
|=
(
ctrl
&
NAND_ALE
)
>>
1
;
case
NAND_CTL_SETNCE
:
T_NAND_CTL_SETNCE
(
cmd
);
break
;
case
NAND_CTL_CLRNCE
:
T_NAND_CTL_CLRNCE
(
cmd
);
break
;
#warning Wild guess as gpiosetout() is nowhere defined in the kernel source - tglx
gpiosetout
(
0x5002
,
bits
);
#ifdef CONFIG_NAND_WORKAROUND
/* "some" dev boards busted, blue wired to rts2 :( */
rts2setout
(
2
,
(
ctrl
&
NAND_CLE
)
<<
1
);
#endif
/* allow time to ensure gpio state to over take memory write */
udelay
(
1
);
}
udelay
(
1
);
/* allow time to ensure gpio state to over take memory write */
if
(
cmd
!=
NAND_CMD_NONE
)
writeb
(
cmd
,
chip
->
IO_ADDR_W
);
}
/*
...
...
@@ -142,7 +143,7 @@ static int __init toto_init(void)
/* Set address of NAND IO lines */
this
->
IO_ADDR_R
=
toto_io_base
;
this
->
IO_ADDR_W
=
toto_io_base
;
this
->
hwcontro
l
=
toto_hwcontrol
;
this
->
cmd_ctr
l
=
toto_hwcontrol
;
this
->
dev_ready
=
NULL
;
/* 25 us command delay time */
this
->
chip_delay
=
30
;
...
...
drivers/mtd/nand/ts7250.c
View file @
0305c865
...
...
@@ -83,31 +83,29 @@ static struct mtd_partition partition_info128[] = {
/*
* hardware specific access to control-lines
*
* ctrl:
* NAND_NCE: bit 0 -> bit 2
* NAND_CLE: bit 1 -> bit 1
* NAND_ALE: bit 2 -> bit 0
*/
static
void
ts7250_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
static
void
ts7250_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
unsigned
long
ctrl
=
TS72XX_NAND_CONTROL_VIRT_BASE
;
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
__raw_writeb
(
__raw_readb
(
ctrl
)
|
0x2
,
ctrl
);
break
;
case
NAND_CTL_CLRCLE
:
__raw_writeb
(
__raw_readb
(
ctrl
)
&
~
0x2
,
ctrl
);
break
;
case
NAND_CTL_SETALE
:
__raw_writeb
(
__raw_readb
(
ctrl
)
|
0x1
,
ctrl
);
break
;
case
NAND_CTL_CLRALE
:
__raw_writeb
(
__raw_readb
(
ctrl
)
&
~
0x1
,
ctrl
);
break
;
case
NAND_CTL_SETNCE
:
__raw_writeb
(
__raw_readb
(
ctrl
)
|
0x4
,
ctrl
);
break
;
case
NAND_CTL_CLRNCE
:
__raw_writeb
(
__raw_readb
(
ctrl
)
&
~
0x4
,
ctrl
);
break
;
struct
nand_chip
*
chip
=
mtd
->
priv
;
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
unsigned
long
addr
=
TS72XX_NAND_CONTROL_VIRT_BASE
;
unsigned
char
bits
;
bits
=
(
ctrl
&
NAND_CNE
)
<<
2
;
bits
|=
ctrl
&
NAND_CLE
;
bits
|=
(
ctrl
&
NAND_ALE
)
>>
2
;
__raw_writeb
((
__raw_readb
(
addr
)
&
~
0x7
)
|
bits
,
addr
);
}
if
(
cmd
!=
NAND_CMD_NONE
)
writeb
(
cmd
,
chip
->
IO_ADDR_W
);
}
/*
...
...
@@ -152,7 +150,7 @@ static int __init ts7250_init(void)
/* insert callbacks */
this
->
IO_ADDR_R
=
(
void
*
)
TS72XX_NAND_DATA_VIRT_BASE
;
this
->
IO_ADDR_W
=
(
void
*
)
TS72XX_NAND_DATA_VIRT_BASE
;
this
->
hwcontro
l
=
ts7250_hwcontrol
;
this
->
cmd_ctr
l
=
ts7250_hwcontrol
;
this
->
dev_ready
=
ts7250_device_ready
;
this
->
chip_delay
=
15
;
this
->
ecc
.
mode
=
NAND_ECC_SOFT
;
...
...
drivers/mtd/nftlcore.c
View file @
0305c865
...
...
@@ -70,8 +70,6 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
nftl
->
mbd
.
devnum
=
-
1
;
nftl
->
mbd
.
blksize
=
512
;
nftl
->
mbd
.
tr
=
tr
;
memcpy
(
&
nftl
->
oobinfo
,
&
mtd
->
oobinfo
,
sizeof
(
struct
nand_oobinfo
));
nftl
->
oobinfo
.
useecc
=
MTD_NANDECC_PLACEONLY
;
if
(
NFTL_mount
(
nftl
)
<
0
)
{
printk
(
KERN_WARNING
"NFTL: could not mount device
\n
"
);
...
...
@@ -369,8 +367,11 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
}
memset
(
&
oob
,
0xff
,
sizeof
(
struct
nftl_oob
));
oob
.
b
.
Status
=
oob
.
b
.
Status1
=
SECTOR_USED
;
MTD_WRITEECC
(
nftl
->
mbd
.
mtd
,
(
nftl
->
EraseSize
*
targetEUN
)
+
(
block
*
512
),
512
,
&
retlen
,
movebuf
,
(
char
*
)
&
oob
,
&
nftl
->
oobinfo
);
nand_write_raw
(
nftl
->
mbd
.
mtd
,
(
nftl
->
EraseSize
*
targetEUN
)
+
(
block
*
512
),
512
,
&
retlen
,
movebuf
,
(
char
*
)
&
oob
);
}
/* add the header so that it is now a valid chain */
...
...
@@ -639,10 +640,10 @@ static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
memset
(
&
oob
,
0xff
,
sizeof
(
struct
nftl_oob
));
oob
.
b
.
Status
=
oob
.
b
.
Status1
=
SECTOR_USED
;
MTD_WRITEECC
(
nftl
->
mbd
.
mtd
,
(
writeEUN
*
nftl
->
EraseSize
)
+
blockofs
,
512
,
&
retlen
,
(
char
*
)
buffer
,
(
char
*
)
&
oob
,
&
nftl
->
oobinfo
);
/* need to write SECTOR_USED flags since they are not written in mtd_writeecc */
nand_write_raw
(
nftl
->
mbd
.
mtd
,
(
writeEUN
*
nftl
->
EraseSize
)
+
blockofs
,
512
,
&
retlen
,
(
char
*
)
buffer
,
(
char
*
)
&
oob
);
return
0
;
}
#endif
/* CONFIG_NFTL_RW */
...
...
drivers/mtd/nftlmount.c
View file @
0305c865
...
...
@@ -268,18 +268,22 @@ static int memcmpb(void *a, int c, int n)
static
int
check_free_sectors
(
struct
NFTLrecord
*
nftl
,
unsigned
int
address
,
int
len
,
int
check_oob
)
{
int
i
;
size_t
retlen
;
u8
buf
[
SECTORSIZE
+
nftl
->
mbd
.
mtd
->
oobsize
];
struct
mtd_info
*
mtd
=
nftl
->
mbd
.
mtd
;
size_t
retlen
;
int
i
;
for
(
i
=
0
;
i
<
len
;
i
+=
SECTORSIZE
)
{
if
(
MTD_READECC
(
nftl
->
mbd
.
mtd
,
address
,
SECTORSIZE
,
&
retlen
,
buf
,
&
buf
[
SECTORSIZE
],
&
nftl
->
oobinfo
)
<
0
)
if
(
mtd
->
read
(
mtd
,
address
,
SECTORSIZE
,
&
retlen
,
buf
)
)
return
-
1
;
if
(
memcmpb
(
buf
,
0xff
,
SECTORSIZE
)
!=
0
)
return
-
1
;
if
(
check_oob
)
{
if
(
memcmpb
(
buf
+
SECTORSIZE
,
0xff
,
nftl
->
mbd
.
mtd
->
oobsize
)
!=
0
)
if
(
mtd
->
read_oob
(
mtd
,
address
,
mtd
->
oobsize
,
&
retlen
,
&
buf
[
SECTORSIZE
])
<
0
)
return
-
1
;
if
(
memcmpb
(
buf
+
SECTORSIZE
,
0xff
,
mtd
->
oobsize
)
!=
0
)
return
-
1
;
}
address
+=
SECTORSIZE
;
...
...
drivers/mtd/onenand/onenand_base.c
View file @
0305c865
...
...
@@ -597,31 +597,28 @@ static void onenand_release_device(struct mtd_info *mtd)
}
/**
* onenand_read
_ecc - [MTD Interface] Read data with ECC
* onenand_read
- [MTD Interface] Read data from flash
* @param mtd MTD device structure
* @param from offset to read from
* @param len number of bytes to read
* @param retlen pointer to variable to store the number of read bytes
* @param buf the databuffer to put data
* @param oob_buf filesystem supplied oob data buffer
* @param oobsel oob selection structure
*
* OneNAND read with ECC
*/
static
int
onenand_read_ecc
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
,
u_char
*
oob_buf
,
struct
nand_oobinfo
*
oobsel
)
* Read with ecc
*/
static
int
onenand_read
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
)
{
struct
onenand_chip
*
this
=
mtd
->
priv
;
int
read
=
0
,
column
;
int
thislen
;
int
ret
=
0
;
DEBUG
(
MTD_DEBUG_LEVEL3
,
"onenand_read
_ecc
: from = 0x%08x, len = %i
\n
"
,
(
unsigned
int
)
from
,
(
int
)
len
);
DEBUG
(
MTD_DEBUG_LEVEL3
,
"onenand_read: from = 0x%08x, len = %i
\n
"
,
(
unsigned
int
)
from
,
(
int
)
len
);
/* Do not allow reads past end of device */
if
((
from
+
len
)
>
mtd
->
size
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_read
_ecc
: Attempt read beyond end of device
\n
"
);
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_read: Attempt read beyond end of device
\n
"
);
*
retlen
=
0
;
return
-
EINVAL
;
}
...
...
@@ -654,7 +651,7 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
break
;
if
(
ret
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_read
_ecc
: read failed = %d
\n
"
,
ret
);
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_read: read failed = %d
\n
"
,
ret
);
goto
out
;
}
...
...
@@ -675,22 +672,6 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
return
ret
;
}
/**
* onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
* @param mtd MTD device structure
* @param from offset to read from
* @param len number of bytes to read
* @param retlen pointer to variable to store the number of read bytes
* @param buf the databuffer to put data
*
* This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
*/
static
int
onenand_read
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
)
{
return
onenand_read_ecc
(
mtd
,
from
,
len
,
retlen
,
buf
,
NULL
,
NULL
);
}
/**
* onenand_read_oob - [MTD Interface] OneNAND read out-of-band
* @param mtd MTD device structure
...
...
@@ -834,39 +815,36 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
#define NOTALIGNED(x) ((x & (mtd->writesize - 1)) != 0)
/**
* onenand_write
_ecc - [MTD Interface] OneNAND write with ECC
* onenand_write
- [MTD Interface] write buffer to FLASH
* @param mtd MTD device structure
* @param to offset to write to
* @param len number of bytes to write
* @param retlen pointer to variable to store the number of written bytes
* @param buf the data to write
* @param eccbuf filesystem supplied oob data buffer
* @param oobsel oob selection structure
*
*
OneNAND w
rite with ECC
*
W
rite with ECC
*/
static
int
onenand_write_ecc
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
static
int
onenand_write
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
)
{
struct
onenand_chip
*
this
=
mtd
->
priv
;
int
written
=
0
;
int
ret
=
0
;
DEBUG
(
MTD_DEBUG_LEVEL3
,
"onenand_write
_ecc
: to = 0x%08x, len = %i
\n
"
,
(
unsigned
int
)
to
,
(
int
)
len
);
DEBUG
(
MTD_DEBUG_LEVEL3
,
"onenand_write: to = 0x%08x, len = %i
\n
"
,
(
unsigned
int
)
to
,
(
int
)
len
);
/* Initialize retlen, in case of early exit */
*
retlen
=
0
;
/* Do not allow writes past end of device */
if
(
unlikely
((
to
+
len
)
>
mtd
->
size
))
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_write
_ecc
: Attempt write to past end of device
\n
"
);
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_write: Attempt write to past end of device
\n
"
);
return
-
EINVAL
;
}
/* Reject writes, which are not page aligned */
if
(
unlikely
(
NOTALIGNED
(
to
))
||
unlikely
(
NOTALIGNED
(
len
)))
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_write
_ecc
: Attempt to write not page aligned data
\n
"
);
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_write: Attempt to write not page aligned data
\n
"
);
return
-
EINVAL
;
}
...
...
@@ -888,7 +866,7 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
ret
=
this
->
wait
(
mtd
,
FL_WRITING
);
if
(
ret
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_write
_ecc
: write filaed %d
\n
"
,
ret
);
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_write: write filaed %d
\n
"
,
ret
);
goto
out
;
}
...
...
@@ -897,7 +875,7 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
/* Only check verify write turn on */
ret
=
onenand_verify_page
(
mtd
,
(
u_char
*
)
buf
,
to
);
if
(
ret
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_write
_ecc
: verify failed %d
\n
"
,
ret
);
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_write: verify failed %d
\n
"
,
ret
);
goto
out
;
}
...
...
@@ -917,23 +895,6 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
return
ret
;
}
/**
* onenand_write - [MTD Interface] compability function for onenand_write_ecc
* @param mtd MTD device structure
* @param to offset to write to
* @param len number of bytes to write
* @param retlen pointer to variable to store the number of written bytes
* @param buf the data to write
*
* This function simply calls onenand_write_ecc
* with oob buffer and oobsel = NULL
*/
static
int
onenand_write
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
)
{
return
onenand_write_ecc
(
mtd
,
to
,
len
,
retlen
,
buf
,
NULL
,
NULL
);
}
/**
* onenand_write_oob - [MTD Interface] OneNAND write out-of-band
* @param mtd MTD device structure
...
...
@@ -1013,144 +974,6 @@ static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
return
ret
;
}
/**
* onenand_writev_ecc - [MTD Interface] write with iovec with ecc
* @param mtd MTD device structure
* @param vecs the iovectors to write
* @param count number of vectors
* @param to offset to write to
* @param retlen pointer to variable to store the number of written bytes
* @param eccbuf filesystem supplied oob data buffer
* @param oobsel oob selection structure
*
* OneNAND write with iovec with ecc
*/
static
int
onenand_writev_ecc
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
{
struct
onenand_chip
*
this
=
mtd
->
priv
;
unsigned
char
*
pbuf
;
size_t
total_len
,
len
;
int
i
,
written
=
0
;
int
ret
=
0
;
/* Preset written len for early exit */
*
retlen
=
0
;
/* Calculate total length of data */
total_len
=
0
;
for
(
i
=
0
;
i
<
count
;
i
++
)
total_len
+=
vecs
[
i
].
iov_len
;
DEBUG
(
MTD_DEBUG_LEVEL3
,
"onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld
\n
"
,
(
unsigned
int
)
to
,
(
unsigned
int
)
total_len
,
count
);
/* Do not allow write past end of the device */
if
(
unlikely
((
to
+
total_len
)
>
mtd
->
size
))
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_writev_ecc: Attempted write past end of device
\n
"
);
return
-
EINVAL
;
}
/* Reject writes, which are not page aligned */
if
(
unlikely
(
NOTALIGNED
(
to
))
||
unlikely
(
NOTALIGNED
(
total_len
)))
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_writev_ecc: Attempt to write not page aligned data
\n
"
);
return
-
EINVAL
;
}
/* Grab the lock and see if the device is available */
onenand_get_device
(
mtd
,
FL_WRITING
);
/* TODO handling oob */
/* Loop until all keve's data has been written */
len
=
0
;
while
(
count
)
{
pbuf
=
this
->
page_buf
;
/*
* If the given tuple is >= pagesize then
* write it out from the iov
*/
if
((
vecs
->
iov_len
-
len
)
>=
mtd
->
writesize
)
{
pbuf
=
vecs
->
iov_base
+
len
;
len
+=
mtd
->
writesize
;
/* Check, if we have to switch to the next tuple */
if
(
len
>=
(
int
)
vecs
->
iov_len
)
{
vecs
++
;
len
=
0
;
count
--
;
}
}
else
{
int
cnt
=
0
,
thislen
;
while
(
cnt
<
mtd
->
writesize
)
{
thislen
=
min_t
(
int
,
mtd
->
writesize
-
cnt
,
vecs
->
iov_len
-
len
);
memcpy
(
this
->
page_buf
+
cnt
,
vecs
->
iov_base
+
len
,
thislen
);
cnt
+=
thislen
;
len
+=
thislen
;
/* Check, if we have to switch to the next tuple */
if
(
len
>=
(
int
)
vecs
->
iov_len
)
{
vecs
++
;
len
=
0
;
count
--
;
}
}
}
this
->
command
(
mtd
,
ONENAND_CMD_BUFFERRAM
,
to
,
mtd
->
writesize
);
this
->
write_bufferram
(
mtd
,
ONENAND_DATARAM
,
pbuf
,
0
,
mtd
->
writesize
);
this
->
write_bufferram
(
mtd
,
ONENAND_SPARERAM
,
ffchars
,
0
,
mtd
->
oobsize
);
this
->
command
(
mtd
,
ONENAND_CMD_PROG
,
to
,
mtd
->
writesize
);
onenand_update_bufferram
(
mtd
,
to
,
1
);
ret
=
this
->
wait
(
mtd
,
FL_WRITING
);
if
(
ret
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_writev_ecc: write failed %d
\n
"
,
ret
);
goto
out
;
}
/* Only check verify write turn on */
ret
=
onenand_verify_page
(
mtd
,
(
u_char
*
)
pbuf
,
to
);
if
(
ret
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"onenand_writev_ecc: verify failed %d
\n
"
,
ret
);
goto
out
;
}
written
+=
mtd
->
writesize
;
to
+=
mtd
->
writesize
;
}
out:
/* Deselect and wakt up anyone waiting on the device */
onenand_release_device
(
mtd
);
*
retlen
=
written
;
return
0
;
}
/**
* onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
* @param mtd MTD device structure
* @param vecs the iovectors to write
* @param count number of vectors
* @param to offset to write to
* @param retlen pointer to variable to store the number of written bytes
*
* OneNAND write with kvec. This just calls the ecc function
*/
static
int
onenand_writev
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
)
{
return
onenand_writev_ecc
(
mtd
,
vecs
,
count
,
to
,
retlen
,
NULL
,
NULL
);
}
/**
* onenand_block_checkbad - [GENERIC] Check if a block is marked bad
* @param mtd MTD device structure
...
...
@@ -1950,8 +1773,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
mtd
->
unpoint
=
NULL
;
mtd
->
read
=
onenand_read
;
mtd
->
write
=
onenand_write
;
mtd
->
read_ecc
=
onenand_read_ecc
;
mtd
->
write_ecc
=
onenand_write_ecc
;
mtd
->
read_oob
=
onenand_read_oob
;
mtd
->
write_oob
=
onenand_write_oob
;
#ifdef CONFIG_MTD_ONENAND_OTP
...
...
@@ -1962,10 +1783,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
mtd
->
write_user_prot_reg
=
onenand_write_user_prot_reg
;
mtd
->
lock_user_prot_reg
=
onenand_lock_user_prot_reg
;
#endif
mtd
->
readv
=
NULL
;
mtd
->
readv_ecc
=
NULL
;
mtd
->
writev
=
onenand_writev
;
mtd
->
writev_ecc
=
onenand_writev_ecc
;
mtd
->
sync
=
onenand_sync
;
mtd
->
lock
=
NULL
;
mtd
->
unlock
=
onenand_unlock
;
...
...
fs/jffs2/wbuf.c
View file @
0305c865
...
...
@@ -236,9 +236,6 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
}
/* Do the read... */
if
(
jffs2_cleanmarker_oob
(
c
))
ret
=
c
->
mtd
->
read_ecc
(
c
->
mtd
,
start
,
c
->
wbuf_ofs
-
start
,
&
retlen
,
buf
,
NULL
,
c
->
oobinfo
);
else
ret
=
c
->
mtd
->
read
(
c
->
mtd
,
start
,
c
->
wbuf_ofs
-
start
,
&
retlen
,
buf
);
if
(
ret
==
-
EBADMSG
&&
retlen
==
c
->
wbuf_ofs
-
start
)
{
...
...
@@ -293,16 +290,13 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
if
(
breakme
++
==
20
)
{
printk
(
KERN_NOTICE
"Faking write error at 0x%08x
\n
"
,
ofs
);
breakme
=
0
;
c
->
mtd
->
write
_ecc
(
c
->
mtd
,
ofs
,
towrite
,
&
retlen
,
brokenbuf
,
NULL
,
c
->
oobinfo
);
c
->
mtd
->
write
(
c
->
mtd
,
ofs
,
towrite
,
&
retlen
,
brokenbuf
);
ret
=
-
EIO
;
}
else
#endif
if
(
jffs2_cleanmarker_oob
(
c
))
ret
=
c
->
mtd
->
write_ecc
(
c
->
mtd
,
ofs
,
towrite
,
&
retlen
,
rewrite_buf
,
NULL
,
c
->
oobinfo
);
else
ret
=
c
->
mtd
->
write
(
c
->
mtd
,
ofs
,
towrite
,
&
retlen
,
rewrite_buf
);
ret
=
c
->
mtd
->
write
(
c
->
mtd
,
ofs
,
towrite
,
&
retlen
,
rewrite_buf
);
if
(
ret
||
retlen
!=
towrite
)
{
/* Argh. We tried. Really we did. */
...
...
@@ -455,15 +449,12 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
if
(
breakme
++
==
20
)
{
printk
(
KERN_NOTICE
"Faking write error at 0x%08x
\n
"
,
c
->
wbuf_ofs
);
breakme
=
0
;
c
->
mtd
->
write
_ecc
(
c
->
mtd
,
c
->
wbuf_ofs
,
c
->
wbuf_pagesize
,
&
retlen
,
brokenbuf
,
NULL
,
c
->
oobinfo
);
c
->
mtd
->
write
(
c
->
mtd
,
c
->
wbuf_ofs
,
c
->
wbuf_pagesize
,
&
retlen
,
brokenbuf
);
ret
=
-
EIO
;
}
else
#endif
if
(
jffs2_cleanmarker_oob
(
c
))
ret
=
c
->
mtd
->
write_ecc
(
c
->
mtd
,
c
->
wbuf_ofs
,
c
->
wbuf_pagesize
,
&
retlen
,
c
->
wbuf
,
NULL
,
c
->
oobinfo
);
else
ret
=
c
->
mtd
->
write
(
c
->
mtd
,
c
->
wbuf_ofs
,
c
->
wbuf_pagesize
,
&
retlen
,
c
->
wbuf
);
if
(
ret
||
retlen
!=
c
->
wbuf_pagesize
)
{
...
...
@@ -792,9 +783,6 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
/* Read flash */
down_read
(
&
c
->
wbuf_sem
);
if
(
jffs2_cleanmarker_oob
(
c
))
ret
=
c
->
mtd
->
read_ecc
(
c
->
mtd
,
ofs
,
len
,
retlen
,
buf
,
NULL
,
c
->
oobinfo
);
else
ret
=
c
->
mtd
->
read
(
c
->
mtd
,
ofs
,
len
,
retlen
,
buf
);
if
(
(
ret
==
-
EBADMSG
)
&&
(
*
retlen
==
len
)
)
{
...
...
include/linux/mtd/mtd.h
View file @
0305c865
...
...
@@ -115,9 +115,6 @@ struct mtd_info {
int
(
*
read
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
(
*
write
)
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
);
int
(
*
read_ecc
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
);
int
(
*
write_ecc
)
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
);
int
(
*
read_oob
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
(
*
write_oob
)
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
);
...
...
@@ -133,17 +130,11 @@ struct mtd_info {
int
(
*
write_user_prot_reg
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
(
*
lock_user_prot_reg
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
);
/* kvec-based read/write methods. We need these especially for NAND flash,
with its limited number of write cycles per erase.
/* kvec-based read/write methods.
NB: The 'count' parameter is the number of _vectors_, each of
which contains an (ofs, len) tuple.
*/
int
(
*
readv
)
(
struct
mtd_info
*
mtd
,
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
from
,
size_t
*
retlen
);
int
(
*
readv_ecc
)
(
struct
mtd_info
*
mtd
,
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
from
,
size_t
*
retlen
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
);
int
(
*
writev
)
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
);
int
(
*
writev_ecc
)
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
);
/* Sync */
void
(
*
sync
)
(
struct
mtd_info
*
mtd
);
...
...
include/linux/mtd/nand.h
View file @
0305c865
...
...
@@ -36,6 +36,9 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from,
size_t
len
,
size_t
ooblen
);
extern
int
nand_write_raw
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
uint8_t
*
buf
,
uint8_t
*
oob
);
/* The maximum number of NAND chips in an array */
#define NAND_MAX_CHIPS 8
...
...
@@ -47,23 +50,20 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from,
/*
* Constants for hardware specific CLE/ALE/NCE function
*/
*
* These are bits which can be or'ed to set/clear multiple
* bits in one go.
*/
/* Select the chip by setting nCE to low */
#define NAND_CTL_SETNCE 1
/* Deselect the chip by setting nCE to high */
#define NAND_CTL_CLRNCE 2
#define NAND_NCE 0x01
/* Select the command latch by setting CLE to high */
#define NAND_CTL_SETCLE 3
/* Deselect the command latch by setting CLE to low */
#define NAND_CTL_CLRCLE 4
#define NAND_CLE 0x02
/* Select the address latch by setting ALE to high */
#define NAND_CTL_SETALE 5
/* Deselect the address latch by setting ALE to low */
#define NAND_CTL_CLRALE 6
/* Set write protection by setting WP to high. Not used! */
#define NAND_CTL_SETWP 7
/* Clear write protection by setting WP to low. Not used! */
#define NAND_CTL_CLRWP 8
#define NAND_ALE 0x04
#define NAND_CTRL_CLE (NAND_NCE | NAND_CLE)
#define NAND_CTRL_ALE (NAND_NCE | NAND_ALE)
#define NAND_CTRL_CHANGE 0x80
/*
* Standard NAND flash commands
...
...
@@ -103,6 +103,8 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from,
#define NAND_CMD_STATUS_RESET 0x7f
#define NAND_CMD_STATUS_CLEAR 0xff
#define NAND_CMD_NONE -1
/* Status bits */
#define NAND_STATUS_FAIL 0x01
#define NAND_STATUS_FAIL_N1 0x02
...
...
@@ -237,7 +239,7 @@ struct nand_ecc_ctrl {
int
steps
;
int
size
;
int
bytes
;
int
(
*
hwctl
)(
struct
mtd_info
*
mtd
,
int
mode
);
void
(
*
hwctl
)(
struct
mtd_info
*
mtd
,
int
mode
);
int
(
*
calculate
)(
struct
mtd_info
*
mtd
,
const
uint8_t
*
dat
,
uint8_t
*
ecc_code
);
...
...
@@ -251,16 +253,15 @@ struct nand_ecc_ctrl {
* @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
* @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
* @read_byte: [REPLACEABLE] read one byte from the chip
* @write_byte: [REPLACEABLE] write one byte to the chip
* @read_word: [REPLACEABLE] read one word from the chip
* @write_word: [REPLACEABLE] write one word to the chip
* @write_buf: [REPLACEABLE] write data from the buffer to the chip
* @read_buf: [REPLACEABLE] read data from the chip into the buffer
* @verify_buf: [REPLACEABLE] verify buffer contents against the chip data
* @select_chip: [REPLACEABLE] select chip nr
* @block_bad: [REPLACEABLE] check, if the block is bad
* @block_markbad: [REPLACEABLE] mark the block bad
* @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines
* @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific funtion for controlling
* ALE/CLE/nCE. Also used to write command and address
* @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line
* If set to NULL no access to ready/busy is available and the ready/busy information
* is read from the chip status register
...
...
@@ -304,17 +305,15 @@ struct nand_chip {
void
__iomem
*
IO_ADDR_W
;
uint8_t
(
*
read_byte
)(
struct
mtd_info
*
mtd
);
void
(
*
write_byte
)(
struct
mtd_info
*
mtd
,
uint8_t
byte
);
u16
(
*
read_word
)(
struct
mtd_info
*
mtd
);
void
(
*
write_word
)(
struct
mtd_info
*
mtd
,
u16
word
);
void
(
*
write_buf
)(
struct
mtd_info
*
mtd
,
const
uint8_t
*
buf
,
int
len
);
void
(
*
read_buf
)(
struct
mtd_info
*
mtd
,
uint8_t
*
buf
,
int
len
);
int
(
*
verify_buf
)(
struct
mtd_info
*
mtd
,
const
uint8_t
*
buf
,
int
len
);
void
(
*
select_chip
)(
struct
mtd_info
*
mtd
,
int
chip
);
int
(
*
block_bad
)(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
int
getchip
);
int
(
*
block_markbad
)(
struct
mtd_info
*
mtd
,
loff_t
ofs
);
void
(
*
hwcontrol
)(
struct
mtd_info
*
mtd
,
int
cmd
);
void
(
*
cmd_ctrl
)(
struct
mtd_info
*
mtd
,
int
dat
,
unsigned
int
ctrl
);
int
(
*
dev_ready
)(
struct
mtd_info
*
mtd
);
void
(
*
cmdfunc
)(
struct
mtd_info
*
mtd
,
unsigned
command
,
int
column
,
int
page_addr
);
int
(
*
waitfunc
)(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
this
,
int
state
);
...
...
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