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
Expand all
Hide 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,14 +80,12 @@ 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
)
{
if
(
INFTL_mount
(
inftl
)
<
0
)
{
printk
(
KERN_WARNING
"INFTL: could not mount device
\n
"
);
kfree
(
inftl
);
return
;
}
}
/* OK, it's a new one. Set up all the data structures. */
...
...
@@ -221,7 +220,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
* Scan to find the Erase Unit which holds the actual data for each
* 512-byte block within the Chain.
*/
silly
=
MAX_LOOPS
;
silly
=
MAX_LOOPS
;
while
(
thisEUN
<
inftl
->
nb_blocks
)
{
for
(
block
=
0
;
block
<
inftl
->
EraseSize
/
SECTORSIZE
;
block
++
)
{
if
((
BlockMap
[
block
]
!=
0xffff
)
||
BlockDeleted
[
block
])
...
...
@@ -232,7 +231,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
(
char
*
)
&
oob
)
<
0
)
status
=
SECTOR_IGNORE
;
else
status
=
oob
.
b
.
Status
|
oob
.
b
.
Status1
;
status
=
oob
.
b
.
Status
|
oob
.
b
.
Status1
;
switch
(
status
)
{
case
SECTOR_FREE
:
...
...
@@ -282,29 +281,30 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
continue
;
}
/*
/*
* Copy only in non free block (free blocks can only
* happen in case of media errors or deleted blocks).
*/
if
(
BlockMap
[
block
]
==
BLOCK_NIL
)
continue
;
if
(
BlockMap
[
block
]
==
BLOCK_NIL
)
continue
;
ret
=
MTD_READ
(
inftl
->
mbd
.
mtd
,
(
inftl
->
EraseSize
*
ret
=
MTD_READ
(
inftl
->
mbd
.
mtd
,
(
inftl
->
EraseSize
*
BlockMap
[
block
])
+
(
block
*
SECTORSIZE
),
SECTORSIZE
,
&
retlen
,
movebuf
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ret
=
MTD_READ
(
inftl
->
mbd
.
mtd
,
(
inftl
->
EraseSize
*
BlockMap
[
block
])
+
(
block
*
SECTORSIZE
),
SECTORSIZE
,
&
retlen
,
movebuf
);
if
(
ret
!=
-
EIO
)
DEBUG
(
MTD_DEBUG_LEVEL1
,
"INFTL: error went "
"away on retry?
\n
"
);
}
memset
(
&
oob
,
0xff
,
sizeof
(
struct
inftl_oob
));
oob
.
b
.
Status
=
oob
.
b
.
Status1
=
SECTOR_USED
;
MTD_WRITEECC
(
inftl
->
mbd
.
mtd
,
(
inftl
->
EraseSize
*
targetEUN
)
+
(
block
*
SECTORSIZE
),
SECTORSIZE
,
&
retlen
,
movebuf
,
(
char
*
)
&
oob
,
&
inftl
->
oobinfo
);
DEBUG
(
MTD_DEBUG_LEVEL1
,
"INFTL: error went "
"away on retry?
\n
"
);
}
memset
(
&
oob
,
0xff
,
sizeof
(
struct
inftl_oob
));
oob
.
b
.
Status
=
oob
.
b
.
Status1
=
SECTOR_USED
;
nand_write_raw
(
inftl
->
mbd
.
mtd
,
(
inftl
->
EraseSize
*
targetEUN
)
+
(
block
*
SECTORSIZE
),
SECTORSIZE
,
&
retlen
,
movebuf
,
(
char
*
)
&
oob
);
}
/*
...
...
@@ -329,17 +329,17 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
if
(
thisEUN
==
targetEUN
)
break
;
if
(
INFTL_formatblock
(
inftl
,
thisEUN
)
<
0
)
{
if
(
INFTL_formatblock
(
inftl
,
thisEUN
)
<
0
)
{
/*
* Could not erase : mark block as reserved.
*/
inftl
->
PUtable
[
thisEUN
]
=
BLOCK_RESERVED
;
}
else
{
}
else
{
/* Correctly erased : mark it as free */
inftl
->
PUtable
[
thisEUN
]
=
BLOCK_FREE
;
inftl
->
PUtable
[
prevEUN
]
=
BLOCK_NIL
;
inftl
->
numfreeEUNs
++
;
}
}
}
return
targetEUN
;
...
...
@@ -437,7 +437,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
MTD_READOOB
(
inftl
->
mbd
.
mtd
,
(
thisEUN
*
inftl
->
EraseSize
)
+
blockofs
,
8
,
&
retlen
,
(
char
*
)
&
bci
);
status
=
bci
.
Status
|
bci
.
Status1
;
status
=
bci
.
Status
|
bci
.
Status1
;
DEBUG
(
MTD_DEBUG_LEVEL3
,
"INFTL: status of block %d in "
"EUN %d is %x
\n
"
,
block
,
writeEUN
,
status
);
...
...
@@ -670,12 +670,12 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
DEBUG
(
MTD_DEBUG_LEVEL3
,
"Deleting EUN %d from VUC %d
\n
"
,
thisEUN
,
thisVUC
);
if
(
INFTL_formatblock
(
inftl
,
thisEUN
)
<
0
)
{
if
(
INFTL_formatblock
(
inftl
,
thisEUN
)
<
0
)
{
/*
* Could not erase : mark block as reserved.
*/
inftl
->
PUtable
[
thisEUN
]
=
BLOCK_RESERVED
;
}
else
{
}
else
{
/* Correctly erased : mark it as free */
inftl
->
PUtable
[
thisEUN
]
=
BLOCK_FREE
;
inftl
->
numfreeEUNs
++
;
...
...
@@ -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
)
+
blockofs
,
SECTORSIZE
,
&
retlen
,
(
char
*
)
buffer
,
(
char
*
)
&
oob
,
&
inftl
->
oobinfo
);
nand_write_raw
(
inftl
->
mbd
.
mtd
,
(
writeEUN
*
inftl
->
EraseSize
)
+
blockofs
,
SECTORSIZE
,
&
retlen
,
(
char
*
)
buffer
,
(
char
*
)
&
oob
);
/*
* need to write SECTOR_USED flags since they are not written
* in mtd_writeecc
...
...
@@ -804,9 +805,9 @@ static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
struct
INFTLrecord
*
inftl
=
(
void
*
)
mbd
;
unsigned
int
thisEUN
=
inftl
->
VUtable
[
block
/
(
inftl
->
EraseSize
/
SECTORSIZE
)];
unsigned
long
blockofs
=
(
block
*
SECTORSIZE
)
&
(
inftl
->
EraseSize
-
1
);
unsigned
int
status
;
unsigned
int
status
;
int
silly
=
MAX_LOOPS
;
struct
inftl_bci
bci
;
struct
inftl_bci
bci
;
size_t
retlen
;
DEBUG
(
MTD_DEBUG_LEVEL3
,
"INFTL: inftl_readblock(inftl=%p,block=%ld,"
...
...
@@ -850,7 +851,7 @@ static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
/* The requested block is not on the media, return all 0x00 */
memset
(
buffer
,
0
,
SECTORSIZE
);
}
else
{
size_t
retlen
;
size_t
retlen
;
loff_t
ptr
=
(
thisEUN
*
inftl
->
EraseSize
)
+
blockofs
;
if
(
MTD_READ
(
inftl
->
mbd
.
mtd
,
ptr
,
SECTORSIZE
,
&
retlen
,
buffer
))
...
...
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
);
return
part
->
master
->
read
(
part
->
master
,
from
+
part
->
offset
,
len
,
retlen
,
buf
);
}
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
);
return
part
->
master
->
write
(
part
->
master
,
to
+
part
->
offset
,
len
,
retlen
,
buf
);
}
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
,
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
{
...
...
@@ -200,7 +199,7 @@ static int __init ams_delta_init(void)
AMS_DELTA_LATCH2_NAND_NCE
|
AMS_DELTA_LATCH2_NAND_NWP
);
/* Scan to find existance of the device */
/* Scan to find existance of the device */
if
(
nand_scan
(
ams_delta_mtd
,
1
))
{
err
=
-
ENXIO
;
goto
out_mtd
;
...
...
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
...
...
@@ -4,7 +4,7 @@
* Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
*
* Derived from drivers/mtd/spia.c
*
Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
*
* $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $
*
...
...
@@ -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
);
}
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
);
}
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
);
}
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
This diff is collapsed.
Click to expand it.
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,54 +108,68 @@ 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
)
{
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
MACRO_NAND_CTL_SETCLE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
case
NAND_CTL_CLRCLE
:
MACRO_NAND_CTL_CLRCLE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
case
NAND_CTL_SETALE
:
MACRO_NAND_CTL_SETALE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
case
NAND_CTL_CLRALE
:
MACRO_NAND_CTL_CLRALE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
case
NAND_CTL_SETNCE
:
MACRO_NAND_ENABLE_CE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
case
NAND_CTL_CLRNCE
:
MACRO_NAND_DISABLE_CE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
struct
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
;
case
NAND_CTL_CLRCLE
:
MACRO_NAND_CTL_CLRCLE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
case
NAND_CTL_SETALE
:
MACRO_NAND_CTL_SETALE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
case
NAND_CTL_CLRALE
:
MACRO_NAND_CTL_CLRALE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
case
NAND_CTL_SETNCE
:
MACRO_NAND_ENABLE_CE
((
unsigned
long
)
CFG_NAND0_PADDR
);
break
;
case
NAND_CTL_CLRNCE
:
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
)
{
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
MACRO_NAND_CTL_SETCLE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
case
NAND_CTL_CLRCLE
:
MACRO_NAND_CTL_CLRCLE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
case
NAND_CTL_SETALE
:
MACRO_NAND_CTL_SETALE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
case
NAND_CTL_CLRALE
:
MACRO_NAND_CTL_CLRALE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
case
NAND_CTL_SETNCE
:
MACRO_NAND_ENABLE_CE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
case
NAND_CTL_CLRNCE
:
MACRO_NAND_DISABLE_CE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
struct
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
;
case
NAND_CTL_CLRCLE
:
MACRO_NAND_CTL_CLRCLE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
case
NAND_CTL_SETALE
:
MACRO_NAND_CTL_SETALE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
case
NAND_CTL_CLRALE
:
MACRO_NAND_CTL_CLRALE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
case
NAND_CTL_SETNCE
:
MACRO_NAND_ENABLE_CE
((
unsigned
long
)
CFG_NAND1_PADDR
);
break
;
case
NAND_CTL_CLRNCE
:
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
;
/* NAND_CTL_CLRCLE: */
/* NAND_CTL_CLRALE: */
default:
chip
->
IO_ADDR_W
=
info
->
regs
+
S3C2410_NFDATA
;
break
;
}
if
(
cmd
==
NAND_CMD_NONE
)
return
;
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
;
/* NAND_CTL_CLRCLE: */
/* NAND_CTL_CLRALE: */
default:
chip
->
IO_ADDR_W
=
info
->
regs
+
S3C2440_NFDATA
;
break
;
}
if
(
cmd
==
NAND_CMD_NONE
)
return
;
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
This diff is collapsed.
Click to expand it.
fs/jffs2/wbuf.c
View file @
0305c865
...
...
@@ -236,10 +236,7 @@ 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
);
ret
=
c
->
mtd
->
read
(
c
->
mtd
,
start
,
c
->
wbuf_ofs
-
start
,
&
retlen
,
buf
);
if
(
ret
==
-
EBADMSG
&&
retlen
==
c
->
wbuf_ofs
-
start
)
{
/* ECC recovered */
...
...
@@ -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,10 +783,7 @@ 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
);
ret
=
c
->
mtd
->
read
(
c
->
mtd
,
ofs
,
len
,
retlen
,
buf
);
if
(
(
ret
==
-
EBADMSG
)
&&
(
*
retlen
==
len
)
)
{
printk
(
KERN_WARNING
"mtd->read(0x%zx bytes from 0x%llx) returned ECC error
\n
"
,
...
...
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