[MTD NAND] Indent all of drivers/mtd/nand/*.c.

It was just too painful to deal with.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
This commit is contained in:
David Woodhouse 2006-05-13 18:07:53 +01:00
Родитель 6943f8af7d
Коммит e0c7d76753
17 изменённых файлов: 1217 добавлений и 1292 удалений

Просмотреть файл

@ -38,22 +38,20 @@
*/
static struct mtd_info *au1550_mtd = NULL;
static void __iomem *p_nand;
static int nand_width = 1; /* default x8*/
static int nand_width = 1; /* default x8 */
/*
* Define partitions for flash device
*/
static const struct mtd_partition partition_info[] = {
{
.name = "NAND FS 0",
.offset = 0,
.size = 8*1024*1024
},
.name = "NAND FS 0",
.offset = 0,
.size = 8 * 1024 * 1024},
{
.name = "NAND FS 1",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL
}
.name = "NAND FS 1",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL}
};
/**
@ -157,7 +155,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
int i;
struct nand_chip *this = mtd->priv;
for (i=0; i<len; i++) {
for (i = 0; i < len; i++) {
writeb(buf[i], this->IO_ADDR_W);
au_sync();
}
@ -176,7 +174,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
int i;
struct nand_chip *this = mtd->priv;
for (i=0; i<len; i++) {
for (i = 0; i < len; i++) {
buf[i] = readb(this->IO_ADDR_R);
au_sync();
}
@ -195,7 +193,7 @@ static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
int i;
struct nand_chip *this = mtd->priv;
for (i=0; i<len; i++) {
for (i = 0; i < len; i++) {
if (buf[i] != readb(this->IO_ADDR_R))
return -EFAULT;
au_sync();
@ -219,7 +217,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
u16 *p = (u16 *) buf;
len >>= 1;
for (i=0; i<len; i++) {
for (i = 0; i < len; i++) {
writew(p[i], this->IO_ADDR_W);
au_sync();
}
@ -241,7 +239,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
u16 *p = (u16 *) buf;
len >>= 1;
for (i=0; i<len; i++) {
for (i = 0; i < len; i++) {
p[i] = readw(this->IO_ADDR_R);
au_sync();
}
@ -262,7 +260,7 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
u16 *p = (u16 *) buf;
len >>= 1;
for (i=0; i<len; i++) {
for (i = 0; i < len; i++) {
if (p[i] != readw(this->IO_ADDR_R))
return -EFAULT;
au_sync();
@ -275,27 +273,35 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
{
register struct nand_chip *this = mtd->priv;
switch(cmd){
switch (cmd) {
case NAND_CTL_SETCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_CMD; break;
case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break;
case NAND_CTL_SETCLE:
this->IO_ADDR_W = p_nand + MEM_STNAND_CMD;
break;
case NAND_CTL_CLRCLE:
this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
break;
case NAND_CTL_SETALE:
this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR;
break;
case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;
case NAND_CTL_CLRALE:
this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
/* FIXME: Nobody knows why this is neccecary,
/* FIXME: Nobody knows why this is necessary,
* but it works only that way */
udelay(1);
break;
case NAND_CTL_SETNCE:
/* assert (force assert) chip enable */
au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break;
au_writel((1 << (4 + NAND_CS)), MEM_STNDCTL);
break;
case NAND_CTL_CLRNCE:
/* deassert chip enable */
au_writel(0, MEM_STNDCTL); break;
/* deassert chip enable */
au_writel(0, MEM_STNDCTL);
break;
}
@ -315,66 +321,63 @@ int au1550_device_ready(struct mtd_info *mtd)
/*
* Main initialization routine
*/
int __init au1xxx_nand_init (void)
int __init au1xxx_nand_init(void)
{
struct nand_chip *this;
u16 boot_swapboot = 0; /* default value */
u16 boot_swapboot = 0; /* default value */
int retval;
u32 mem_staddr;
u32 nand_phys;
/* Allocate memory for MTD device structure and private data */
au1550_mtd = kmalloc (sizeof(struct mtd_info) +
sizeof (struct nand_chip), GFP_KERNEL);
au1550_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!au1550_mtd) {
printk ("Unable to allocate NAND MTD dev structure.\n");
printk("Unable to allocate NAND MTD dev structure.\n");
return -ENOMEM;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&au1550_mtd[1]);
this = (struct nand_chip *)(&au1550_mtd[1]);
/* Initialize structures */
memset((char *) au1550_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
memset(au1550_mtd, 0, sizeof(struct mtd_info));
memset(this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
au1550_mtd->priv = this;
/* disable interrupts */
au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL);
au_writel(au_readl(MEM_STNDCTL) & ~(1 << 8), MEM_STNDCTL);
/* disable NAND boot */
au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);
au_writel(au_readl(MEM_STNDCTL) & ~(1 << 0), MEM_STNDCTL);
#ifdef CONFIG_MIPS_PB1550
/* set gpio206 high */
au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR);
au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR);
boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
((bcsr->status >> 6) & 0x1);
boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr->status >> 6) & 0x1);
switch (boot_swapboot) {
case 0:
case 2:
case 8:
case 0xC:
case 0xD:
/* x16 NAND Flash */
nand_width = 0;
break;
case 1:
case 9:
case 3:
case 0xE:
case 0xF:
/* x8 NAND Flash */
nand_width = 1;
break;
default:
printk("Pb1550 NAND: bad boot:swap\n");
retval = -EINVAL;
goto outmem;
case 0:
case 2:
case 8:
case 0xC:
case 0xD:
/* x16 NAND Flash */
nand_width = 0;
break;
case 1:
case 9:
case 3:
case 0xE:
case 0xF:
/* x8 NAND Flash */
nand_width = 1;
break;
default:
printk("Pb1550 NAND: bad boot:swap\n");
retval = -EINVAL;
goto outmem;
}
#endif
@ -424,14 +427,13 @@ int __init au1xxx_nand_init (void)
/* make controller and MTD agree */
if (NAND_CS == 0)
nand_width = au_readl(MEM_STCFG0) & (1<<22);
nand_width = au_readl(MEM_STCFG0) & (1 << 22);
if (NAND_CS == 1)
nand_width = au_readl(MEM_STCFG1) & (1<<22);
nand_width = au_readl(MEM_STCFG1) & (1 << 22);
if (NAND_CS == 2)
nand_width = au_readl(MEM_STCFG2) & (1<<22);
nand_width = au_readl(MEM_STCFG2) & (1 << 22);
if (NAND_CS == 3)
nand_width = au_readl(MEM_STCFG3) & (1<<22);
nand_width = au_readl(MEM_STCFG3) & (1 << 22);
/* Set address of hardware control function */
this->hwcontrol = au1550_hwcontrol;
@ -454,7 +456,7 @@ int __init au1xxx_nand_init (void)
this->verify_buf = (!nand_width) ? au_verify_buf16 : au_verify_buf;
/* Scan to find existence of the device */
if (nand_scan (au1550_mtd, 1)) {
if (nand_scan(au1550_mtd, 1)) {
retval = -ENXIO;
goto outio;
}
@ -465,10 +467,10 @@ int __init au1xxx_nand_init (void)
return 0;
outio:
iounmap ((void *)p_nand);
iounmap((void *)p_nand);
outmem:
kfree (au1550_mtd);
kfree(au1550_mtd);
return retval;
}
@ -478,19 +480,20 @@ module_init(au1xxx_nand_init);
* Clean up routine
*/
#ifdef MODULE
static void __exit au1550_cleanup (void)
static void __exit au1550_cleanup(void)
{
struct nand_chip *this = (struct nand_chip *) &au1550_mtd[1];
struct nand_chip *this = (struct nand_chip *)&au1550_mtd[1];
/* Release resources, unregister device */
nand_release (au1550_mtd);
nand_release(au1550_mtd);
/* Free the MTD device structure */
kfree (au1550_mtd);
kfree(au1550_mtd);
/* Unmap */
iounmap ((void *)p_nand);
iounmap((void *)p_nand);
}
module_exit(au1550_cleanup);
#endif

Просмотреть файл

@ -47,7 +47,7 @@ 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;
static void __iomem *autcpu12_fio_base;
/*
* Define partitions for flash devices
@ -95,10 +95,10 @@ static struct mtd_partition partition_info128k[] = {
/*
* hardware specific access to control-lines
*/
static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
{
switch(cmd){
switch (cmd) {
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;
@ -117,41 +117,40 @@ static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
int autcpu12_device_ready(struct mtd_info *mtd)
{
return ( (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0;
return ((*(volatile unsigned char *)(autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0;
}
/*
* Main initialization routine
*/
int __init autcpu12_init (void)
int __init autcpu12_init(void)
{
struct nand_chip *this;
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");
printk("Unable to allocate AUTCPU12 NAND MTD device structure.\n");
err = -ENOMEM;
goto out;
}
/* map physical adress */
autcpu12_fio_base = ioremap(autcpu12_fio_pbase,SZ_1K);
if(!autcpu12_fio_base){
autcpu12_fio_base = ioremap(autcpu12_fio_pbase, SZ_1K);
if (!autcpu12_fio_base) {
printk("Ioremap autcpu12 SmartMedia Card failed\n");
err = -EIO;
goto out_mtd;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&autcpu12_mtd[1]);
this = (struct nand_chip *)(&autcpu12_mtd[1]);
/* Initialize structures */
memset((char *) autcpu12_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
memset(autcpu12_mtd, 0, sizeof(struct mtd_info));
memset(this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
autcpu12_mtd->priv = this;
@ -167,35 +166,34 @@ int __init autcpu12_init (void)
/* Enable the following for a flash based bad block table */
/*
this->options = NAND_USE_FLASH_BBT;
*/
this->options = NAND_USE_FLASH_BBT;
*/
this->options = NAND_USE_FLASH_BBT;
/* Scan to find existance of the device */
if (nand_scan (autcpu12_mtd, 1)) {
if (nand_scan(autcpu12_mtd, 1)) {
err = -ENXIO;
goto out_ior;
}
/* Register the partitions */
switch(autcpu12_mtd->size){
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;
default: {
printk ("Unsupported SmartMedia device\n");
default:
printk("Unsupported SmartMedia device\n");
err = -ENXIO;
goto out_ior;
}
}
goto out;
out_ior:
out_ior:
iounmap((void *)autcpu12_fio_base);
out_mtd:
kfree (autcpu12_mtd);
out:
out_mtd:
kfree(autcpu12_mtd);
out:
return err;
}
@ -205,17 +203,18 @@ module_init(autcpu12_init);
* Clean up routine
*/
#ifdef MODULE
static void __exit autcpu12_cleanup (void)
static void __exit autcpu12_cleanup(void)
{
/* Release resources, unregister device */
nand_release (autcpu12_mtd);
nand_release(autcpu12_mtd);
/* unmap physical adress */
iounmap((void *)autcpu12_fio_base);
/* Free the MTD device structure */
kfree (autcpu12_mtd);
kfree(autcpu12_mtd);
}
module_exit(autcpu12_cleanup);
#endif

Просмотреть файл

@ -50,7 +50,7 @@
/* Pin function selection MSR (IDE vs. flash on the IDE pins) */
#define MSR_DIVIL_BALL_OPTS 0x51400015
#define PIN_OPT_IDE (1<<0) /* 0 for flash, 1 for IDE */
#define PIN_OPT_IDE (1<<0) /* 0 for flash, 1 for IDE */
/* Registers within the NAND flash controller BAR -- memory mapped */
#define MM_NAND_DATA 0x00 /* 0 to 0x7ff, in fact */
@ -128,7 +128,7 @@ static void cs553x_write_byte(struct mtd_info *mtd, u_char byte)
udelay(1);
i--;
}
writeb(byte, this->IO_ADDR_W+0x801);
writeb(byte, this->IO_ADDR_W + 0x801);
}
static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd)
@ -137,7 +137,7 @@ static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd)
void __iomem *mmio_base = this->IO_ADDR_R;
unsigned char ctl;
switch(cmd) {
switch (cmd) {
case NAND_CTL_SETCLE:
ctl = CS_NAND_CTL_CLE;
break;
@ -160,17 +160,15 @@ static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd)
writeb(ctl, mmio_base + MM_NAND_CTL);
}
static int cs553x_device_ready(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
void __iomem *mmio_base = this->IO_ADDR_R;
unsigned char foo = readb(mmio_base + MM_NAND_STS);
return (foo & CS_NAND_STS_FLASH_RDY) && !(foo & CS_NAND_CTLR_BUSY);
return (foo & CS_NAND_STS_FLASH_RDY) && !(foo & CS_NAND_CTLR_BUSY);
}
static void cs_enable_hwecc(struct mtd_info *mtd, int mode)
{
struct nand_chip *this = mtd->priv;
@ -209,7 +207,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
}
/* Allocate memory for MTD device structure and private data */
new_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL);
new_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!new_mtd) {
printk(KERN_WARNING "Unable to allocate CS553X NAND MTD device structure.\n");
err = -ENOMEM;
@ -217,7 +215,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
}
/* Get pointer to private data */
this = (struct nand_chip *) (&new_mtd[1]);
this = (struct nand_chip *)(&new_mtd[1]);
/* Initialize structures */
memset(new_mtd, 0, sizeof(struct mtd_info));
@ -286,16 +284,16 @@ int __init cs553x_init(void)
return -ENXIO;
}
for (i=0; i<NR_CS553X_CONTROLLERS; i++) {
rdmsrl(MSR_DIVIL_LBAR_FLSH0+i, val);
for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
rdmsrl(MSR_DIVIL_LBAR_FLSH0 + i, val);
if ((val & (FLSH_LBAR_EN|FLSH_NOR_NAND)) == (FLSH_LBAR_EN|FLSH_NOR_NAND))
err = cs553x_init_one(i, !!(val & FLSH_MEM_IO), val & 0xFFFFFFFF);
}
/* Register all devices together here. This means we can easily hack it to
do mtdconcat etc. if we want to. */
for (i=0; i<NR_CS553X_CONTROLLERS; i++) {
for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
if (cs553x_mtd[i]) {
add_mtd_device(cs553x_mtd[i]);
@ -306,13 +304,14 @@ int __init cs553x_init(void)
return err;
}
module_init(cs553x_init);
static void __exit cs553x_cleanup (void)
static void __exit cs553x_cleanup(void)
{
int i;
for (i=0; i<NR_CS553X_CONTROLLERS; i++) {
for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
struct mtd_info *mtd = cs553x_mtd[i];
struct nand_chip *this;
void __iomem *mmio_base;
@ -324,7 +323,7 @@ static void __exit cs553x_cleanup (void)
mmio_base = this->IO_ADDR_R;
/* Release resources, unregister device */
nand_release (cs553x_mtd[i]);
nand_release(cs553x_mtd[i]);
cs553x_mtd[i] = NULL;
/* unmap physical adress */
@ -334,6 +333,7 @@ static void __exit cs553x_cleanup (void)
kfree(mtd);
}
}
module_exit(cs553x_cleanup);
MODULE_LICENSE("GPL");

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -25,7 +25,7 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */
#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */
#include <asm/sizes.h>
#include <asm/hardware/clps7111.h>
@ -54,29 +54,29 @@ static struct mtd_info *ep7312_mtd = NULL;
*/
static unsigned long ep7312_fio_pbase = EP7312_FIO_PBASE;
static void __iomem * ep7312_pxdr = (void __iomem *) EP7312_PXDR;
static void __iomem * ep7312_pxddr = (void __iomem *) EP7312_PXDDR;
static void __iomem *ep7312_pxdr = (void __iomem *)EP7312_PXDR;
static void __iomem *ep7312_pxddr = (void __iomem *)EP7312_PXDDR;
#ifdef CONFIG_MTD_PARTITIONS
/*
* Define static partitions for flash device
*/
static struct mtd_partition partition_info[] = {
{ .name = "EP7312 Nand Flash",
.offset = 0,
.size = 8*1024*1024 }
{.name = "EP7312 Nand Flash",
.offset = 0,
.size = 8 * 1024 * 1024}
};
#define NUM_PARTITIONS 1
#endif
/*
* hardware specific access to control-lines
*/
static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd)
{
switch(cmd) {
switch (cmd) {
case NAND_CTL_SETCLE:
clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr);
@ -108,6 +108,7 @@ static int ep7312_device_ready(struct mtd_info *mtd)
{
return 1;
}
#ifdef CONFIG_MTD_PARTITIONS
const char *part_probes[] = { "cmdlinepart", NULL };
#endif
@ -115,18 +116,16 @@ const char *part_probes[] = { "cmdlinepart", NULL };
/*
* Main initialization routine
*/
static int __init ep7312_init (void)
static int __init ep7312_init(void)
{
struct nand_chip *this;
const char *part_type = 0;
int mtd_parts_nb = 0;
struct mtd_partition *mtd_parts = 0;
void __iomem * ep7312_fio_base;
void __iomem *ep7312_fio_base;
/* Allocate memory for MTD device structure and private data */
ep7312_mtd = kmalloc(sizeof(struct mtd_info) +
sizeof(struct nand_chip),
GFP_KERNEL);
ep7312_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!ep7312_mtd) {
printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
return -ENOMEM;
@ -134,18 +133,18 @@ static int __init ep7312_init (void)
/* map physical adress */
ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
if(!ep7312_fio_base) {
if (!ep7312_fio_base) {
printk("ioremap EDB7312 NAND flash failed\n");
kfree(ep7312_mtd);
return -EIO;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&ep7312_mtd[1]);
this = (struct nand_chip *)(&ep7312_mtd[1]);
/* Initialize structures */
memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
memset(ep7312_mtd, 0, sizeof(struct mtd_info));
memset(this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
ep7312_mtd->priv = this;
@ -165,16 +164,14 @@ static int __init ep7312_init (void)
this->chip_delay = 15;
/* Scan to find existence of the device */
if (nand_scan (ep7312_mtd, 1)) {
if (nand_scan(ep7312_mtd, 1)) {
iounmap((void *)ep7312_fio_base);
kfree (ep7312_mtd);
kfree(ep7312_mtd);
return -ENXIO;
}
#ifdef CONFIG_MTD_PARTITIONS
ep7312_mtd->name = "edb7312-nand";
mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes,
&mtd_parts, 0);
mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, &mtd_parts, 0);
if (mtd_parts_nb > 0)
part_type = "command line";
else
@ -193,24 +190,26 @@ static int __init ep7312_init (void)
/* Return happy */
return 0;
}
module_init(ep7312_init);
/*
* Clean up routine
*/
static void __exit ep7312_cleanup (void)
static void __exit ep7312_cleanup(void)
{
struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1];
struct nand_chip *this = (struct nand_chip *)&ep7312_mtd[1];
/* Release resources, unregister device */
nand_release (ap7312_mtd);
nand_release(ap7312_mtd);
/* Free internal data buffer */
kfree (this->data_buf);
kfree(this->data_buf);
/* Free the MTD device structure */
kfree (ep7312_mtd);
kfree(ep7312_mtd);
}
module_exit(ep7312_cleanup);
MODULE_LICENSE("GPL");

Просмотреть файл

@ -26,7 +26,7 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */
#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */
#include <asm/sizes.h>
#include <asm/arch/h1900-gpio.h>
#include <asm/arch/ipaq.h>
@ -45,23 +45,23 @@ static struct mtd_info *h1910_nand_mtd = NULL;
* Define static partitions for flash device
*/
static struct mtd_partition partition_info[] = {
{ name: "h1910 NAND Flash",
offset: 0,
size: 16*1024*1024 }
{name:"h1910 NAND Flash",
offset:0,
size:16 * 1024 * 1024}
};
#define NUM_PARTITIONS 1
#endif
/*
* hardware specific access to control-lines
*/
static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
{
struct nand_chip* this = (struct nand_chip *) (mtd->priv);
struct nand_chip *this = (struct nand_chip *)(mtd->priv);
switch(cmd) {
switch (cmd) {
case NAND_CTL_SETCLE:
this->IO_ADDR_R |= (1 << 2);
@ -101,7 +101,7 @@ static int h1910_device_ready(struct mtd_info *mtd)
/*
* Main initialization routine
*/
static int __init h1910_init (void)
static int __init h1910_init(void)
{
struct nand_chip *this;
const char *part_type = 0;
@ -119,21 +119,19 @@ static int __init h1910_init (void)
}
/* Allocate memory for MTD device structure and private data */
h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) +
sizeof(struct nand_chip),
GFP_KERNEL);
h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!h1910_nand_mtd) {
printk("Unable to allocate h1910 NAND MTD device structure.\n");
iounmap ((void *) nandaddr);
iounmap((void *)nandaddr);
return -ENOMEM;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&h1910_nand_mtd[1]);
this = (struct nand_chip *)(&h1910_nand_mtd[1]);
/* Initialize structures */
memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
memset(h1910_nand_mtd, 0, sizeof(struct mtd_info));
memset(this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
h1910_nand_mtd->priv = this;
@ -154,23 +152,20 @@ static int __init h1910_init (void)
this->options = NAND_NO_AUTOINCR;
/* Scan to find existence of the device */
if (nand_scan (h1910_nand_mtd, 1)) {
if (nand_scan(h1910_nand_mtd, 1)) {
printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
kfree (h1910_nand_mtd);
iounmap ((void *) nandaddr);
kfree(h1910_nand_mtd);
iounmap((void *)nandaddr);
return -ENXIO;
}
#ifdef CONFIG_MTD_CMDLINE_PARTS
mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts,
"h1910-nand");
mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, "h1910-nand");
if (mtd_parts_nb > 0)
part_type = "command line";
part_type = "command line";
else
mtd_parts_nb = 0;
mtd_parts_nb = 0;
#endif
if (mtd_parts_nb == 0)
{
if (mtd_parts_nb == 0) {
mtd_parts = partition_info;
mtd_parts_nb = NUM_PARTITIONS;
part_type = "static";
@ -183,24 +178,26 @@ static int __init h1910_init (void)
/* Return happy */
return 0;
}
module_init(h1910_init);
/*
* Clean up routine
*/
static void __exit h1910_cleanup (void)
static void __exit h1910_cleanup(void)
{
struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1];
struct nand_chip *this = (struct nand_chip *)&h1910_nand_mtd[1];
/* Release resources, unregister device */
nand_release (h1910_nand_mtd);
nand_release(h1910_nand_mtd);
/* Release io resource */
iounmap ((void *) this->IO_ADDR_W);
iounmap((void *)this->IO_ADDR_W);
/* Free the MTD device structure */
kfree (h1910_nand_mtd);
kfree(h1910_nand_mtd);
}
module_exit(h1910_cleanup);
MODULE_LICENSE("GPL");

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -48,7 +48,7 @@
*
* Following assumptions are made:
* - bbts start at a page boundary, if autolocated on a block boundary
* - the space neccecary for a bbt in FLASH does not exceed a block boundary
* - the space necessary for a bbt in FLASH does not exceed a block boundary
*
*/
@ -75,7 +75,7 @@
* pattern area contain 0xff
*
*/
static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
{
int i, end = 0;
uint8_t *p = buf;
@ -116,7 +116,7 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
* no optional empty check
*
*/
static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
{
int i;
uint8_t *p = buf;
@ -142,8 +142,8 @@ static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
* Read the bad block table starting from page.
*
*/
static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
int bits, int offs, int reserved_block_code)
static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
int bits, int offs, int reserved_block_code)
{
int res, i, j, act = 0;
struct nand_chip *this = mtd->priv;
@ -152,17 +152,17 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
uint8_t msk = (uint8_t) ((1 << bits) - 1);
totlen = (num * bits) >> 3;
from = ((loff_t)page) << this->page_shift;
from = ((loff_t) page) << this->page_shift;
while (totlen) {
len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
res = mtd->read_ecc(mtd, from, len, &retlen, buf, NULL, this->autooob);
if (res < 0) {
if (retlen != len) {
printk (KERN_INFO "nand_bbt: Error reading bad block table\n");
printk(KERN_INFO "nand_bbt: Error reading bad block table\n");
return res;
}
printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
}
/* Analyse data */
@ -172,17 +172,16 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
uint8_t tmp = (dat >> j) & msk;
if (tmp == msk)
continue;
if (reserved_block_code &&
(tmp == reserved_block_code)) {
printk (KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
if (reserved_block_code && (tmp == reserved_block_code)) {
printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
continue;
}
/* Leave it for now, if its matured we can move this
* message to MTD_DEBUG_LEVEL0 */
printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
/* Factory marked bad or worn out ? */
if (tmp == 0)
this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
@ -207,7 +206,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
* Read the bad block table for all chips starting at a given page
* We assume that the bbt bits are in consecutive order.
*/
static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
{
struct nand_chip *this = mtd->priv;
int res = 0, i;
@ -242,23 +241,22 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
* We assume that the bbt bits are in consecutive order.
*
*/
static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td,
struct nand_bbt_descr *md)
static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
{
struct nand_chip *this = mtd->priv;
/* Read the primary version, if available */
if (td->options & NAND_BBT_VERSION) {
nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
nand_read_raw(mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
td->version[0] = buf[mtd->oobblock + td->veroffs];
printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
}
/* Read the mirror version, if available */
if (md && (md->options & NAND_BBT_VERSION)) {
nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
nand_read_raw(mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
md->version[0] = buf[mtd->oobblock + md->veroffs];
printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
}
return 1;
@ -275,7 +273,7 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
* Create a bad block table by scanning the device
* for the given good/bad block identify pattern
*/
static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
{
struct nand_chip *this = mtd->priv;
int i, j, numblocks, len, scanlen;
@ -283,7 +281,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
loff_t from;
size_t readlen, ooblen;
printk (KERN_INFO "Scanning device for bad blocks\n");
printk(KERN_INFO "Scanning device for bad blocks\n");
if (bd->options & NAND_BBT_SCANALLPAGES)
len = 1 << (this->bbt_erase_shift - this->page_shift);
@ -300,7 +298,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
readlen = bd->len;
} else {
/* Full page content should be read */
scanlen = mtd->oobblock + mtd->oobsize;
scanlen = mtd->oobblock + mtd->oobsize;
readlen = len * mtd->oobblock;
ooblen = len * mtd->oobsize;
}
@ -313,8 +311,8 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
from = 0;
} else {
if (chip >= this->numchips) {
printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
chip + 1, this->numchips);
printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
chip + 1, this->numchips);
return -EINVAL;
}
numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
@ -327,7 +325,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
int ret;
if (bd->options & NAND_BBT_SCANEMPTY)
if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
if ((ret = nand_read_raw(mtd, buf, from, readlen, ooblen)))
return ret;
for (j = 0; j < len; j++) {
@ -336,22 +334,21 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
/* Read the full oob until read_oob is fixed to
* handle single byte reads for 16 bit buswidth */
ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
mtd->oobsize, &retlen, buf);
ret = mtd->read_oob(mtd, from + j * mtd->oobblock, mtd->oobsize, &retlen, buf);
if (ret)
return ret;
if (check_short_pattern (buf, bd)) {
if (check_short_pattern(buf, bd)) {
this->bbt[i >> 3] |= 0x03 << (i & 0x6);
printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int) from);
printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int)from);
break;
}
} else {
if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
if (check_pattern(&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
this->bbt[i >> 3] |= 0x03 << (i & 0x6);
printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int) from);
printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int)from);
break;
}
}
@ -374,12 +371,12 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
* block.
* If the option NAND_BBT_PERCHIP is given, each chip is searched
* for a bbt, which contains the bad block information of this chip.
* This is neccecary to provide support for certain DOC devices.
* This is necessary to provide support for certain DOC devices.
*
* The bbt ident pattern resides in the oob area of the first page
* in a block.
*/
static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
{
struct nand_chip *this = mtd->priv;
int i, chips;
@ -389,7 +386,7 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
/* Search direction top -> down ? */
if (td->options & NAND_BBT_LASTBLOCK) {
startblock = (mtd->size >> this->bbt_erase_shift) -1;
startblock = (mtd->size >> this->bbt_erase_shift) - 1;
dir = -1;
} else {
startblock = 0;
@ -417,7 +414,7 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
for (block = 0; block < td->maxblocks; block++) {
int actblock = startblock + dir * block;
/* Read first page */
nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
nand_read_raw(mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
if (td->options & NAND_BBT_VERSION) {
@ -431,9 +428,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
/* Check, if we found a bbt for each requested chip */
for (i = 0; i < chips; i++) {
if (td->pages[i] == -1)
printk (KERN_WARNING "Bad block table not found for chip %d\n", i);
printk(KERN_WARNING "Bad block table not found for chip %d\n", i);
else
printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
td->version[i]);
}
return 0;
}
@ -447,21 +445,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
*
* Search and read the bad block table(s)
*/
static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md)
static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
{
/* Search the primary table */
search_bbt (mtd, buf, td);
search_bbt(mtd, buf, td);
/* Search the mirror table */
if (md)
search_bbt (mtd, buf, md);
search_bbt(mtd, buf, md);
/* Force result check */
return 1;
}
/**
* write_bbt - [GENERIC] (Re)write the bad block table
*
@ -474,8 +470,8 @@ static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
* (Re)write the bad block table
*
*/
static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
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_chip *this = mtd->priv;
struct nand_oobinfo oobinfo;
@ -492,7 +488,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
rcode = 0xff;
/* Write bad block table per chip rather than per device ? */
if (td->options & NAND_BBT_PERCHIP) {
numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
/* Full device write or specific chip ? */
if (chipsel == -1) {
nrchips = this->numchips;
@ -501,7 +497,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
chip = chipsel;
}
} else {
numblocks = (int) (mtd->size >> this->bbt_erase_shift);
numblocks = (int)(mtd->size >> this->bbt_erase_shift);
nrchips = 1;
}
@ -540,9 +536,9 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
if (!md || md->pages[chip] != page)
goto write;
}
printk (KERN_ERR "No space left to write bad block table\n");
printk(KERN_ERR "No space left to write bad block table\n");
return -ENOSPC;
write:
write:
/* Set up shift count and masks for the flash table */
bits = td->options & NAND_BBT_NRBITS_MSK;
@ -558,7 +554,7 @@ write:
to = ((loff_t) page) << this->page_shift;
memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
memcpy(&oobinfo, this->autooob, sizeof(oobinfo));
oobinfo.useecc = MTD_NANDECC_PLACEONLY;
/* Must we save the block contents ? */
@ -566,22 +562,23 @@ write:
/* 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_ecc(mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
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");
}
/* 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));
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);
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];
}
@ -589,22 +586,22 @@ write:
/* Calc length */
len = (size_t) (numblocks >> sft);
/* Make it page aligned ! */
len = (len + (mtd->oobblock-1)) & ~(mtd->oobblock-1);
len = (len + (mtd->oobblock - 1)) & ~(mtd->oobblock - 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;
/* Pattern is located in oob area of first page */
memcpy (&buf[len + td->offs], td->pattern, td->len);
memcpy(&buf[len + td->offs], td->pattern, td->len);
if (td->options & NAND_BBT_VERSION) {
buf[len + td->veroffs] = td->version[chip];
}
}
/* walk through the memory table */
for (i = 0; i < numblocks; ) {
for (i = 0; i < numblocks;) {
uint8_t dat;
dat = this->bbt[bbtoffs + (i >> 2)];
for (j = 0; j < 4; j++ , i++) {
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);
@ -612,23 +609,23 @@ write:
}
}
memset (&einfo, 0, sizeof (einfo));
memset(&einfo, 0, sizeof(einfo));
einfo.mtd = mtd;
einfo.addr = (unsigned long) to;
einfo.addr = (unsigned long)to;
einfo.len = 1 << this->bbt_erase_shift;
res = nand_erase_nand (mtd, &einfo, 1);
res = nand_erase_nand(mtd, &einfo, 1);
if (res < 0) {
printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
printk(KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
return res;
}
res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
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);
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]);
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;
@ -644,27 +641,27 @@ write:
* The function creates a memory based bbt by scanning the device
* for manufacturer / software marked good / bad blocks
*/
static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
{
struct nand_chip *this = mtd->priv;
bd->options &= ~NAND_BBT_SCANEMPTY;
return create_bbt (mtd, this->data_buf, bd, -1);
return create_bbt(mtd, this->data_buf, bd, -1);
}
/**
* check_create - [GENERIC] create and write bbt(s) if neccecary
* check_create - [GENERIC] create and write bbt(s) if necessary
* @mtd: MTD device structure
* @buf: temporary buffer
* @bd: descriptor for the good/bad block search pattern
*
* The function checks the results of the previous call to read_bbt
* and creates / updates the bbt(s) if neccecary
* Creation is neccecary if no bbt was found for the chip/device
* Update is neccecary if one of the tables is missing or the
* and creates / updates the bbt(s) if necessary
* Creation is necessary if no bbt was found for the chip/device
* Update is necessary if one of the tables is missing or the
* version nr. of one table is less than the other
*/
static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
{
int i, chips, writeops, chipsel, res;
struct nand_chip *this = mtd->priv;
@ -732,35 +729,35 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
rd = td;
goto writecheck;
}
create:
create:
/* Create the bad block table by scanning the device ? */
if (!(td->options & NAND_BBT_CREATE))
continue;
/* Create the table in memory by scanning the chip(s) */
create_bbt (mtd, buf, bd, chipsel);
create_bbt(mtd, buf, bd, chipsel);
td->version[i] = 1;
if (md)
md->version[i] = 1;
writecheck:
writecheck:
/* read back first ? */
if (rd)
read_abs_bbt (mtd, buf, rd, chipsel);
read_abs_bbt(mtd, buf, rd, chipsel);
/* If they weren't versioned, read both. */
if (rd2)
read_abs_bbt (mtd, buf, rd2, chipsel);
read_abs_bbt(mtd, buf, rd2, chipsel);
/* Write the bad block table to the device ? */
if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
res = write_bbt (mtd, buf, td, md, chipsel);
res = write_bbt(mtd, buf, td, md, chipsel);
if (res < 0)
return res;
}
/* Write the mirror bad block table to the device ? */
if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
res = write_bbt (mtd, buf, md, td, chipsel);
res = write_bbt(mtd, buf, md, td, chipsel);
if (res < 0)
return res;
}
@ -777,7 +774,7 @@ writecheck:
* accidental erasures / writes. The regions are identified by
* the mark 0x02.
*/
static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
{
struct nand_chip *this = mtd->priv;
int i, j, chips, block, nrblocks, update;
@ -795,7 +792,8 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
for (i = 0; i < chips; i++) {
if ((td->options & NAND_BBT_ABSPAGE) ||
!(td->options & NAND_BBT_WRITE)) {
if (td->pages[i] == -1) continue;
if (td->pages[i] == -1)
continue;
block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
block <<= 1;
oldval = this->bbt[(block >> 3)];
@ -815,7 +813,8 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
oldval = this->bbt[(block >> 3)];
newval = oldval | (0x2 << (block & 0x06));
this->bbt[(block >> 3)] = newval;
if (oldval != newval) update = 1;
if (oldval != newval)
update = 1;
block += 2;
}
/* If we want reserved blocks to be recorded to flash, and some
@ -840,7 +839,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
* by calling the nand_free_bbt function.
*
*/
int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
{
struct nand_chip *this = mtd->priv;
int len, res = 0;
@ -850,21 +849,21 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
len = mtd->size >> (this->bbt_erase_shift + 2);
/* Allocate memory (2bit per block) */
this->bbt = kmalloc (len, GFP_KERNEL);
this->bbt = kmalloc(len, GFP_KERNEL);
if (!this->bbt) {
printk (KERN_ERR "nand_scan_bbt: Out of memory\n");
printk(KERN_ERR "nand_scan_bbt: Out of memory\n");
return -ENOMEM;
}
/* Clear the memory bad block table */
memset (this->bbt, 0x00, len);
memset(this->bbt, 0x00, len);
/* If no primary table decriptor is given, scan the device
* to build a memory based bad block table
*/
if (!td) {
if ((res = nand_memory_bbt(mtd, bd))) {
printk (KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
kfree (this->bbt);
printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
kfree(this->bbt);
this->bbt = NULL;
}
return res;
@ -875,33 +874,32 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
len += (len >> this->page_shift) * mtd->oobsize;
buf = vmalloc(len);
if (!buf) {
printk (KERN_ERR "nand_bbt: Out of memory\n");
kfree (this->bbt);
printk(KERN_ERR "nand_bbt: Out of memory\n");
kfree(this->bbt);
this->bbt = NULL;
return -ENOMEM;
}
/* Is the bbt at a given page ? */
if (td->options & NAND_BBT_ABSPAGE) {
res = read_abs_bbts (mtd, buf, td, md);
res = read_abs_bbts(mtd, buf, td, md);
} else {
/* Search the bad block table using a pattern in oob */
res = search_read_bbts (mtd, buf, td, md);
res = search_read_bbts(mtd, buf, td, md);
}
if (res)
res = check_create (mtd, buf, bd);
res = check_create(mtd, buf, bd);
/* Prevent the bbt regions from erasing / writing */
mark_bbt_region (mtd, td);
mark_bbt_region(mtd, td);
if (md)
mark_bbt_region (mtd, md);
mark_bbt_region(mtd, md);
vfree (buf);
vfree(buf);
return res;
}
/**
* nand_update_bbt - [NAND Interface] update bad block table(s)
* @mtd: MTD device structure
@ -909,7 +907,7 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
*
* The function updates the bad block table(s)
*/
int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
{
struct nand_chip *this = mtd->priv;
int len, res = 0, writeops = 0;
@ -925,9 +923,9 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
/* Allocate a temporary buffer for one eraseblock incl. oob */
len = (1 << this->bbt_erase_shift);
len += (len >> this->page_shift) * mtd->oobsize;
buf = kmalloc (len, GFP_KERNEL);
buf = kmalloc(len, GFP_KERNEL);
if (!buf) {
printk (KERN_ERR "nand_update_bbt: Out of memory\n");
printk(KERN_ERR "nand_update_bbt: Out of memory\n");
return -ENOMEM;
}
@ -935,7 +933,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
/* Do we have a bbt per chip ? */
if (td->options & NAND_BBT_PERCHIP) {
chip = (int) (offs >> this->chip_shift);
chip = (int)(offs >> this->chip_shift);
chipsel = chip;
} else {
chip = 0;
@ -948,17 +946,17 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
/* Write the bad block table to the device ? */
if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
res = write_bbt (mtd, buf, td, md, chipsel);
res = write_bbt(mtd, buf, td, md, chipsel);
if (res < 0)
goto out;
}
/* Write the mirror bad block table to the device ? */
if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
res = write_bbt (mtd, buf, md, td, chipsel);
res = write_bbt(mtd, buf, md, td, chipsel);
}
out:
kfree (buf);
out:
kfree(buf);
return res;
}
@ -1036,7 +1034,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
* support for the device and calls the nand_scan_bbt function
*
*/
int nand_default_bbt (struct mtd_info *mtd)
int nand_default_bbt(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
@ -1046,7 +1044,7 @@ int nand_default_bbt (struct mtd_info *mtd)
* of the good / bad information, so we _must_ store
* this information in a good / bad table during
* startup
*/
*/
if (this->options & NAND_IS_AND) {
/* Use the default pattern descriptors */
if (!this->bbt_td) {
@ -1054,10 +1052,9 @@ int nand_default_bbt (struct mtd_info *mtd)
this->bbt_md = &bbt_mirror_descr;
}
this->options |= NAND_USE_FLASH_BBT;
return nand_scan_bbt (mtd, &agand_flashbased);
return nand_scan_bbt(mtd, &agand_flashbased);
}
/* Is a flash based bad block table requested ? */
if (this->options & NAND_USE_FLASH_BBT) {
/* Use the default pattern descriptors */
@ -1066,18 +1063,17 @@ int nand_default_bbt (struct mtd_info *mtd)
this->bbt_md = &bbt_mirror_descr;
}
if (!this->badblock_pattern) {
this->badblock_pattern = (mtd->oobblock > 512) ?
&largepage_flashbased : &smallpage_flashbased;
this->badblock_pattern = (mtd->oobblock > 512) ? &largepage_flashbased : &smallpage_flashbased;
}
} else {
this->bbt_td = NULL;
this->bbt_md = NULL;
if (!this->badblock_pattern) {
this->badblock_pattern = (mtd->oobblock > 512) ?
&largepage_memorybased : &smallpage_memorybased;
&largepage_memorybased : &smallpage_memorybased;
}
}
return nand_scan_bbt (mtd, this->badblock_pattern);
return nand_scan_bbt(mtd, this->badblock_pattern);
}
/**
@ -1087,26 +1083,29 @@ int nand_default_bbt (struct mtd_info *mtd)
* @allowbbt: allow access to bad block table region
*
*/
int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
{
struct nand_chip *this = mtd->priv;
int block;
uint8_t res;
uint8_t res;
/* Get block number * 2 */
block = (int) (offs >> (this->bbt_erase_shift - 1));
block = (int)(offs >> (this->bbt_erase_shift - 1));
res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
(unsigned int)offs, block >> 1, res);
DEBUG(MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
(unsigned int)offs, block >> 1, res);
switch ((int)res) {
case 0x00: return 0;
case 0x01: return 1;
case 0x02: return allowbbt ? 0 : 1;
case 0x00:
return 0;
case 0x01:
return 1;
case 0x02:
return allowbbt ? 0 : 1;
}
return 1;
}
EXPORT_SYMBOL (nand_scan_bbt);
EXPORT_SYMBOL (nand_default_bbt);
EXPORT_SYMBOL(nand_scan_bbt);
EXPORT_SYMBOL(nand_default_bbt);

Просмотреть файл

@ -62,7 +62,6 @@ static const u_char nand_ecc_precalc_table[] = {
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
};
/**
* nand_trans_result - [GENERIC] create non-inverted ECC
* @reg2: line parity reg 2
@ -71,8 +70,7 @@ static const u_char nand_ecc_precalc_table[] = {
*
* Creates non-inverted ECC code from line parity
*/
static void nand_trans_result(u_char reg2, u_char reg3,
u_char *ecc_code)
static void nand_trans_result(u_char reg2, u_char reg3, u_char *ecc_code)
{
u_char a, b, i, tmp1, tmp2;
@ -82,10 +80,10 @@ static void nand_trans_result(u_char reg2, u_char reg3,
/* Calculate first ECC byte */
for (i = 0; i < 4; i++) {
if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
tmp1 |= b;
b >>= 1;
if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
tmp1 |= b;
b >>= 1;
a >>= 1;
@ -94,10 +92,10 @@ static void nand_trans_result(u_char reg2, u_char reg3,
/* Calculate second ECC byte */
b = 0x80;
for (i = 0; i < 4; i++) {
if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
tmp2 |= b;
b >>= 1;
if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
tmp2 |= b;
b >>= 1;
a >>= 1;
@ -124,7 +122,7 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
/* Build up column parity */
for(j = 0; j < 256; j++) {
for (j = 0; j < 256; j++) {
/* Get CP0 - CP5 from table */
idx = nand_ecc_precalc_table[dat[j]];
@ -168,8 +166,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
if ((d1 | d2 | d3) == 0) {
/* No errors */
return 0;
}
else {
} else {
a = (d1 ^ (d1 >> 1)) & 0x55;
b = (d2 ^ (d2 >> 1)) & 0x55;
c = (d3 ^ (d3 >> 1)) & 0x54;
@ -179,14 +176,14 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
c = 0x80;
add = 0;
a = 0x80;
for (i=0; i<4; i++) {
for (i = 0; i < 4; i++) {
if (d1 & c)
add |= a;
c >>= 2;
a >>= 1;
}
c = 0x80;
for (i=0; i<4; i++) {
for (i = 0; i < 4; i++) {
if (d2 & c)
add |= a;
c >>= 2;
@ -195,7 +192,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
bit = 0;
b = 0x04;
c = 0x80;
for (i=0; i<3; i++) {
for (i = 0; i < 3; i++) {
if (d3 & c)
bit |= b;
c >>= 2;
@ -206,8 +203,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
a ^= (b << bit);
dat[add] = a;
return 1;
}
else {
} else {
i = 0;
while (d1) {
if (d1 & 0x01)
@ -230,8 +226,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
read_ecc[1] = calc_ecc[1];
read_ecc[2] = calc_ecc[2];
return 2;
}
else {
} else {
/* Uncorrectable Error */
return -1;
}

Просмотреть файл

@ -125,13 +125,13 @@ struct nand_manufacturers nand_manuf_ids[] = {
{NAND_MFR_NATIONAL, "National"},
{NAND_MFR_RENESAS, "Renesas"},
{NAND_MFR_STMICRO, "ST Micro"},
{NAND_MFR_HYNIX, "Hynix"},
{NAND_MFR_HYNIX, "Hynix"},
{0x0, "Unknown"}
};
EXPORT_SYMBOL (nand_manuf_ids);
EXPORT_SYMBOL (nand_flash_ids);
EXPORT_SYMBOL(nand_manuf_ids);
EXPORT_SYMBOL(nand_flash_ids);
MODULE_LICENSE ("GPL");
MODULE_AUTHOR ("Thomas Gleixner <tglx@linutronix.de>");
MODULE_DESCRIPTION ("Nand device & manufacturer ID's");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
MODULE_DESCRIPTION("Nand device & manufacturer IDs");

Просмотреть файл

@ -58,21 +58,21 @@
/*
* MTD structure for PPChameleonEVB board
*/
static struct mtd_info *ppchameleon_mtd = NULL;
static struct mtd_info *ppchameleon_mtd = NULL;
static struct mtd_info *ppchameleonevb_mtd = NULL;
/*
* Module stuff
*/
static unsigned long ppchameleon_fio_pbase = CFG_NAND0_PADDR;
static unsigned long ppchameleon_fio_pbase = CFG_NAND0_PADDR;
static unsigned long ppchameleonevb_fio_pbase = CFG_NAND1_PADDR;
#ifdef MODULE
module_param(ppchameleon_fio_pbase, ulong, 0);
module_param(ppchameleonevb_fio_pbase, ulong, 0);
#else
__setup("ppchameleon_fio_pbase=",ppchameleon_fio_pbase);
__setup("ppchameleonevb_fio_pbase=",ppchameleonevb_fio_pbase);
__setup("ppchameleon_fio_pbase=", ppchameleon_fio_pbase);
__setup("ppchameleonevb_fio_pbase=", ppchameleonevb_fio_pbase);
#endif
#ifdef CONFIG_MTD_PARTITIONS
@ -80,80 +80,80 @@ __setup("ppchameleonevb_fio_pbase=",ppchameleonevb_fio_pbase);
* Define static partitions for flash devices
*/
static struct mtd_partition partition_info_hi[] = {
{ name: "PPChameleon HI Nand Flash",
offset: 0,
size: 128*1024*1024 }
{ .name = "PPChameleon HI Nand Flash",
offset = 0,
.size = 128 * 1024 * 1024
}
};
static struct mtd_partition partition_info_me[] = {
{ name: "PPChameleon ME Nand Flash",
offset: 0,
size: 32*1024*1024 }
{ .name = "PPChameleon ME Nand Flash",
.offset = 0,
.size = 32 * 1024 * 1024
}
};
static struct mtd_partition partition_info_evb[] = {
{ name: "PPChameleonEVB Nand Flash",
offset: 0,
size: 32*1024*1024 }
{ .name = "PPChameleonEVB Nand Flash",
.offset = 0,
.size = 32 * 1024 * 1024
}
};
#define NUM_PARTITIONS 1
extern int parse_cmdline_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
const char *mtd_id);
extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, const char *mtd_id);
#endif
/*
* hardware specific access to control-lines
*/
static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd)
{
switch(cmd) {
switch (cmd) {
case NAND_CTL_SETCLE:
MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR);
MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR);
break;
case NAND_CTL_CLRCLE:
MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR);
MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR);
break;
case NAND_CTL_SETALE:
MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR);
MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR);
break;
case NAND_CTL_CLRALE:
MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR);
MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR);
break;
case NAND_CTL_SETNCE:
MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR);
MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR);
break;
case NAND_CTL_CLRNCE:
MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR);
MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR);
break;
}
}
static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd)
{
switch(cmd) {
switch (cmd) {
case NAND_CTL_SETCLE:
MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR);
MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR);
break;
case NAND_CTL_CLRCLE:
MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR);
MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR);
break;
case NAND_CTL_SETALE:
MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR);
MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR);
break;
case NAND_CTL_CLRALE:
MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR);
MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR);
break;
case NAND_CTL_SETNCE:
MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR);
MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR);
break;
case NAND_CTL_CLRNCE:
MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR);
MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR);
break;
}
}
@ -164,15 +164,15 @@ static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd)
*/
static int ppchameleon_device_ready(struct mtd_info *minfo)
{
if (in_be32((volatile unsigned*)GPIO0_IR) & NAND_RB_GPIO_PIN)
if (in_be32((volatile unsigned *)GPIO0_IR) & NAND_RB_GPIO_PIN)
return 1;
return 0;
}
static int ppchameleonevb_device_ready(struct mtd_info *minfo)
{
if (in_be32((volatile unsigned*)GPIO0_IR) & NAND_EVB_RB_GPIO_PIN)
return 1;
if (in_be32((volatile unsigned *)GPIO0_IR) & NAND_EVB_RB_GPIO_PIN)
return 1;
return 0;
}
#endif
@ -185,7 +185,7 @@ const char *part_probes_evb[] = { "cmdlinepart", NULL };
/*
* Main initialization routine
*/
static int __init ppchameleonevb_init (void)
static int __init ppchameleonevb_init(void)
{
struct nand_chip *this;
const char *part_type = 0;
@ -194,13 +194,11 @@ static int __init ppchameleonevb_init (void)
void __iomem *ppchameleon_fio_base;
void __iomem *ppchameleonevb_fio_base;
/*********************************
* Processor module NAND (if any) *
*********************************/
/* Allocate memory for MTD device structure and private data */
ppchameleon_mtd = kmalloc(sizeof(struct mtd_info) +
sizeof(struct nand_chip), GFP_KERNEL);
ppchameleon_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!ppchameleon_mtd) {
printk("Unable to allocate PPChameleon NAND MTD device structure.\n");
return -ENOMEM;
@ -208,43 +206,45 @@ static int __init ppchameleonevb_init (void)
/* map physical address */
ppchameleon_fio_base = ioremap(ppchameleon_fio_pbase, SZ_4M);
if(!ppchameleon_fio_base) {
if (!ppchameleon_fio_base) {
printk("ioremap PPChameleon NAND flash failed\n");
kfree(ppchameleon_mtd);
return -EIO;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&ppchameleon_mtd[1]);
this = (struct nand_chip *)(&ppchameleon_mtd[1]);
/* Initialize structures */
memset((char *) ppchameleon_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
memset(ppchameleon_mtd, 0, sizeof(struct mtd_info));
memset(this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
ppchameleon_mtd->priv = this;
/* Initialize GPIOs */
/* Initialize GPIOs */
/* Pin mapping for NAND chip */
/*
CE GPIO_01
CLE GPIO_02
ALE GPIO_03
R/B GPIO_04
*/
CE GPIO_01
CLE GPIO_02
ALE GPIO_03
R/B GPIO_04
*/
/* output select */
out_be32((volatile unsigned*)GPIO0_OSRH, in_be32((volatile unsigned*)GPIO0_OSRH) & 0xC0FFFFFF);
out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xC0FFFFFF);
/* three-state select */
out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xC0FFFFFF);
out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xC0FFFFFF);
/* enable output driver */
out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_nCE_GPIO_PIN | NAND_CLE_GPIO_PIN | NAND_ALE_GPIO_PIN);
out_be32((volatile unsigned *)GPIO0_TCR,
in_be32((volatile unsigned *)GPIO0_TCR) | NAND_nCE_GPIO_PIN | NAND_CLE_GPIO_PIN | NAND_ALE_GPIO_PIN);
#ifdef USE_READY_BUSY_PIN
/* three-state select */
out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFF3FFFFF);
out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFF3FFFFF);
/* high-impedecence */
out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) & (~NAND_RB_GPIO_PIN));
out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_RB_GPIO_PIN));
/* input select */
out_be32((volatile unsigned*)GPIO0_ISR1H, (in_be32((volatile unsigned*)GPIO0_ISR1H) & 0xFF3FFFFF) | 0x00400000);
out_be32((volatile unsigned *)GPIO0_ISR1H,
(in_be32((volatile unsigned *)GPIO0_ISR1H) & 0xFF3FFFFF) | 0x00400000);
#endif
/* insert callbacks */
@ -259,12 +259,11 @@ static int __init ppchameleonevb_init (void)
this->eccmode = NAND_ECC_SOFT;
/* Scan to find existence of the device (it could not be mounted) */
if (nand_scan (ppchameleon_mtd, 1)) {
if (nand_scan(ppchameleon_mtd, 1)) {
iounmap((void *)ppchameleon_fio_base);
kfree (ppchameleon_mtd);
kfree(ppchameleon_mtd);
goto nand_evb_init;
}
#ifndef USE_READY_BUSY_PIN
/* Adjust delay if necessary */
if (ppchameleon_mtd->size == NAND_SMALL_SIZE)
@ -275,12 +274,11 @@ static int __init ppchameleonevb_init (void)
ppchameleon_mtd->name = "ppchameleon-nand";
mtd_parts_nb = parse_mtd_partitions(ppchameleon_mtd, part_probes, &mtd_parts, 0);
if (mtd_parts_nb > 0)
part_type = "command line";
part_type = "command line";
else
mtd_parts_nb = 0;
mtd_parts_nb = 0;
#endif
if (mtd_parts_nb == 0)
{
if (mtd_parts_nb == 0) {
if (ppchameleon_mtd->size == NAND_SMALL_SIZE)
mtd_parts = partition_info_me;
else
@ -293,13 +291,12 @@ static int __init ppchameleonevb_init (void)
printk(KERN_NOTICE "Using %s partition definition\n", part_type);
add_mtd_partitions(ppchameleon_mtd, mtd_parts, mtd_parts_nb);
nand_evb_init:
nand_evb_init:
/****************************
* EVB NAND (always present) *
****************************/
/* Allocate memory for MTD device structure and private data */
ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) +
sizeof(struct nand_chip), GFP_KERNEL);
ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!ppchameleonevb_mtd) {
printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n");
return -ENOMEM;
@ -307,46 +304,47 @@ nand_evb_init:
/* map physical address */
ppchameleonevb_fio_base = ioremap(ppchameleonevb_fio_pbase, SZ_4M);
if(!ppchameleonevb_fio_base) {
if (!ppchameleonevb_fio_base) {
printk("ioremap PPChameleonEVB NAND flash failed\n");
kfree(ppchameleonevb_mtd);
return -EIO;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&ppchameleonevb_mtd[1]);
this = (struct nand_chip *)(&ppchameleonevb_mtd[1]);
/* Initialize structures */
memset((char *) ppchameleonevb_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
memset(ppchameleonevb_mtd, 0, sizeof(struct mtd_info));
memset(this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
ppchameleonevb_mtd->priv = this;
/* Initialize GPIOs */
/* Initialize GPIOs */
/* Pin mapping for NAND chip */
/*
CE GPIO_14
CLE GPIO_15
ALE GPIO_16
R/B GPIO_31
*/
CE GPIO_14
CLE GPIO_15
ALE GPIO_16
R/B GPIO_31
*/
/* output select */
out_be32((volatile unsigned*)GPIO0_OSRH, in_be32((volatile unsigned*)GPIO0_OSRH) & 0xFFFFFFF0);
out_be32((volatile unsigned*)GPIO0_OSRL, in_be32((volatile unsigned*)GPIO0_OSRL) & 0x3FFFFFFF);
out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xFFFFFFF0);
out_be32((volatile unsigned *)GPIO0_OSRL, in_be32((volatile unsigned *)GPIO0_OSRL) & 0x3FFFFFFF);
/* three-state select */
out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0);
out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF);
out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFFFFFFF0);
out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0x3FFFFFFF);
/* enable output driver */
out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN);
#ifdef USE_READY_BUSY_PIN
/* three-state select */
out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0xFFFFFFFC);
out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0xFFFFFFFC);
/* high-impedecence */
out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) & (~NAND_EVB_RB_GPIO_PIN));
out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_EVB_RB_GPIO_PIN));
/* input select */
out_be32((volatile unsigned*)GPIO0_ISR1L, (in_be32((volatile unsigned*)GPIO0_ISR1L) & 0xFFFFFFFC) | 0x00000001);
out_be32((volatile unsigned *)GPIO0_ISR1L,
(in_be32((volatile unsigned *)GPIO0_ISR1L) & 0xFFFFFFFC) | 0x00000001);
#endif
/* insert callbacks */
@ -362,22 +360,20 @@ nand_evb_init:
this->eccmode = NAND_ECC_SOFT;
/* Scan to find existence of the device */
if (nand_scan (ppchameleonevb_mtd, 1)) {
if (nand_scan(ppchameleonevb_mtd, 1)) {
iounmap((void *)ppchameleonevb_fio_base);
kfree (ppchameleonevb_mtd);
kfree(ppchameleonevb_mtd);
return -ENXIO;
}
#ifdef CONFIG_MTD_PARTITIONS
ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME;
mtd_parts_nb = parse_mtd_partitions(ppchameleonevb_mtd, part_probes_evb, &mtd_parts, 0);
if (mtd_parts_nb > 0)
part_type = "command line";
part_type = "command line";
else
mtd_parts_nb = 0;
mtd_parts_nb = 0;
#endif
if (mtd_parts_nb == 0)
{
if (mtd_parts_nb == 0) {
mtd_parts = partition_info_evb;
mtd_parts_nb = NUM_PARTITIONS;
part_type = "static";
@ -390,18 +386,19 @@ nand_evb_init:
/* Return happy */
return 0;
}
module_init(ppchameleonevb_init);
/*
* Clean up routine
*/
static void __exit ppchameleonevb_cleanup (void)
static void __exit ppchameleonevb_cleanup(void)
{
struct nand_chip *this;
/* Release resources, unregister device(s) */
nand_release (ppchameleon_mtd);
nand_release (ppchameleonevb_mtd);
nand_release(ppchameleon_mtd);
nand_release(ppchameleonevb_mtd);
/* Release iomaps */
this = (struct nand_chip *) &ppchameleon_mtd[1];

Просмотреть файл

@ -97,12 +97,12 @@ static struct mtd_info *rtc_from4_mtd = NULL;
static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE);
static const struct mtd_partition partition_info[] = {
{
.name = "Renesas flash partition 1",
.offset = 0,
.size = MTDPART_SIZ_FULL
},
{
.name = "Renesas flash partition 1",
.offset = 0,
.size = MTDPART_SIZ_FULL},
};
#define NUM_PARTITIONS 1
/*
@ -111,8 +111,8 @@ static const struct mtd_partition partition_info[] = {
* NAND_BBT_CREATE and/or NAND_BBT_WRITE
*
*/
static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' };
static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' };
static struct nand_bbt_descr rtc_from4_bbt_main_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
@ -134,8 +134,6 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
.pattern = mirror_pattern
};
#ifdef RTC_FROM4_HWECC
/* the Reed Solomon control structure */
@ -148,11 +146,11 @@ static struct nand_oobinfo rtc_from4_nand_oobinfo = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 32,
.eccpos = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31},
.oobfree = { {32, 32} }
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31},
.oobfree = {{32, 32}}
};
/* Aargh. I missed the reversed bit order, when I
@ -162,44 +160,42 @@ static struct nand_oobinfo rtc_from4_nand_oobinfo = {
* of the ecc byte which we get from the FPGA
*/
static uint8_t revbits[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
};
#endif
/*
* rtc_from4_hwcontrol - hardware specific access to control-lines
* @mtd: MTD device structure
@ -214,9 +210,9 @@ static uint8_t revbits[256] = {
*/
static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
{
struct nand_chip* this = (struct nand_chip *) (mtd->priv);
struct nand_chip *this = (struct nand_chip *)(mtd->priv);
switch(cmd) {
switch (cmd) {
case NAND_CTL_SETCLE:
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE);
@ -240,7 +236,6 @@ static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
}
}
/*
* rtc_from4_nand_select_chip - hardware specific chip select
* @mtd: MTD device structure
@ -252,26 +247,25 @@ static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
*/
static void rtc_from4_nand_select_chip(struct mtd_info *mtd, int chip)
{
struct nand_chip *this = mtd->priv;
struct nand_chip *this = mtd->priv;
this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R & ~RTC_FROM4_NAND_ADDR_MASK);
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_NAND_ADDR_MASK);
switch(chip) {
switch (chip) {
case 0: /* select slot 3 chip */
case 0: /* select slot 3 chip */
this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT3);
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT3);
break;
case 1: /* select slot 4 chip */
break;
case 1: /* select slot 4 chip */
this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT4);
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT4);
break;
break;
}
}
}
/*
* rtc_from4_nand_device_ready - hardware specific ready/busy check
* @mtd: MTD device structure
@ -290,7 +284,6 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
}
/*
* deplete - code to perform device recovery in case there was a power loss
* @mtd: MTD device structure
@ -306,24 +299,23 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
*/
static void deplete(struct mtd_info *mtd, int chip)
{
struct nand_chip *this = mtd->priv;
struct nand_chip *this = mtd->priv;
/* wait until device is ready */
while (!this->dev_ready(mtd));
/* wait until device is ready */
while (!this->dev_ready(mtd)) ;
this->select_chip(mtd, chip);
/* Send the commands for device recovery, phase 1 */
this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1);
/* Send the commands for device recovery, phase 2 */
this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004);
this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004);
this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1);
}
#ifdef RTC_FROM4_HWECC
/*
* rtc_from4_enable_hwecc - hardware specific hardware ECC enable function
@ -335,39 +327,35 @@ static void deplete(struct mtd_info *mtd, int chip)
*/
static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
{
volatile unsigned short * rs_ecc_ctl = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CTL);
volatile unsigned short *rs_ecc_ctl = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CTL);
unsigned short status;
switch (mode) {
case NAND_ECC_READ :
status = RTC_FROM4_RS_ECC_CTL_CLR
| RTC_FROM4_RS_ECC_CTL_FD_E;
case NAND_ECC_READ:
status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_FD_E;
*rs_ecc_ctl = status;
break;
case NAND_ECC_READSYN :
status = 0x00;
case NAND_ECC_READSYN:
status = 0x00;
*rs_ecc_ctl = status;
break;
case NAND_ECC_WRITE :
status = RTC_FROM4_RS_ECC_CTL_CLR
| RTC_FROM4_RS_ECC_CTL_GEN
| RTC_FROM4_RS_ECC_CTL_FD_E;
case NAND_ECC_WRITE:
status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_GEN | RTC_FROM4_RS_ECC_CTL_FD_E;
*rs_ecc_ctl = status;
break;
default:
default:
BUG();
break;
}
}
/*
* rtc_from4_calculate_ecc - hardware specific code to read ECC code
* @mtd: MTD device structure
@ -383,7 +371,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
*/
static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
{
volatile unsigned short * rs_eccn = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECCN);
volatile unsigned short *rs_eccn = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECCN);
unsigned short value;
int i;
@ -395,7 +383,6 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
ecc_code[7] |= 0x0f; /* set the last four bits (not used) */
}
/*
* rtc_from4_correct_data - hardware specific code to correct data using ECC code
* @mtd: MTD device structure
@ -414,7 +401,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
unsigned short status;
uint16_t par[6], syn[6];
uint8_t ecc[8];
volatile unsigned short *rs_ecc;
volatile unsigned short *rs_ecc;
status = *((volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CHK));
@ -424,23 +411,18 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
/* Read the syndrom pattern from the FPGA and correct the bitorder */
rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC);
for (i = 0; i < 8; i++) {
ecc[i] = revbits[(*rs_ecc) & 0xFF];
rs_ecc++;
}
for (i = 0; i < 8; i++) {
ecc[i] = revbits[(*rs_ecc) & 0xFF];
rs_ecc++;
}
/* convert into 6 10bit syndrome fields */
par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) |
(((uint16_t)ecc[1] << 8) & 0x300)];
par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) |
(((uint16_t)ecc[2] << 6) & 0x3c0)];
par[3] = rs_decoder->index_of[(((uint16_t)ecc[2] >> 4) & 0x00f) |
(((uint16_t)ecc[3] << 4) & 0x3f0)];
par[2] = rs_decoder->index_of[(((uint16_t)ecc[3] >> 6) & 0x003) |
(((uint16_t)ecc[4] << 2) & 0x3fc)];
par[1] = rs_decoder->index_of[(((uint16_t)ecc[5] >> 0) & 0x0ff) |
(((uint16_t)ecc[6] << 8) & 0x300)];
par[0] = (((uint16_t)ecc[6] >> 2) & 0x03f) | (((uint16_t)ecc[7] << 6) & 0x3c0);
par[5] = rs_decoder->index_of[(((uint16_t) ecc[0] >> 0) & 0x0ff) | (((uint16_t) ecc[1] << 8) & 0x300)];
par[4] = rs_decoder->index_of[(((uint16_t) ecc[1] >> 2) & 0x03f) | (((uint16_t) ecc[2] << 6) & 0x3c0)];
par[3] = rs_decoder->index_of[(((uint16_t) ecc[2] >> 4) & 0x00f) | (((uint16_t) ecc[3] << 4) & 0x3f0)];
par[2] = rs_decoder->index_of[(((uint16_t) ecc[3] >> 6) & 0x003) | (((uint16_t) ecc[4] << 2) & 0x3fc)];
par[1] = rs_decoder->index_of[(((uint16_t) ecc[5] >> 0) & 0x0ff) | (((uint16_t) ecc[6] << 8) & 0x300)];
par[0] = (((uint16_t) ecc[6] >> 2) & 0x03f) | (((uint16_t) ecc[7] << 6) & 0x3c0);
/* Convert to computable syndrome */
for (i = 0; i < 6; i++) {
@ -453,16 +435,14 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
syn[i] = rs_decoder->index_of[syn[i]];
}
/* Let the library code do its magic.*/
res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL);
/* Let the library code do its magic. */
res = decode_rs8(rs_decoder, (uint8_t *) buf, par, 512, syn, 0, NULL, 0xff, NULL);
if (res > 0) {
DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: "
"ECC corrected %d errors on read\n", res);
DEBUG(MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " "ECC corrected %d errors on read\n", res);
}
return res;
}
/**
* rtc_from4_errstat - perform additional error status checks
* @mtd: MTD device structure
@ -480,44 +460,44 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
*/
static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page)
{
int er_stat=0;
int rtn, retlen;
size_t len;
int er_stat = 0;
int rtn, retlen;
size_t len;
uint8_t *buf;
int i;
int i;
this->cmdfunc (mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
this->cmdfunc(mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
if (state == FL_ERASING) {
for (i=0; i<4; i++) {
if (status & 1<<(i+1)) {
this->cmdfunc (mtd, (NAND_CMD_STATUS_ERROR + i + 1), -1, -1);
if (state == FL_ERASING) {
for (i = 0; i < 4; i++) {
if (status & 1 << (i + 1)) {
this->cmdfunc(mtd, (NAND_CMD_STATUS_ERROR + i + 1), -1, -1);
rtn = this->read_byte(mtd);
this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1);
this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
er_stat |= 1<<(i+1); /* err_ecc_not_avail */
er_stat |= 1 << (i + 1); /* err_ecc_not_avail */
}
}
}
} else if (state == FL_WRITING) {
/* single bank write logic */
this->cmdfunc (mtd, NAND_CMD_STATUS_ERROR, -1, -1);
this->cmdfunc(mtd, NAND_CMD_STATUS_ERROR, -1, -1);
rtn = this->read_byte(mtd);
this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1);
this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
er_stat |= 1<<1; /* err_ecc_not_avail */
er_stat |= 1 << 1; /* err_ecc_not_avail */
} else {
len = mtd->oobblock;
buf = kmalloc (len, GFP_KERNEL);
buf = kmalloc(len, GFP_KERNEL);
if (!buf) {
printk (KERN_ERR "rtc_from4_errstat: Out of memory!\n");
er_stat = 1; /* if we can't check, assume failed */
printk(KERN_ERR "rtc_from4_errstat: Out of memory!\n");
er_stat = 1; /* if we can't check, assume failed */
} else {
/* recovery read */
/* page read */
rtn = nand_do_read_ecc (mtd, page, len, &retlen, buf, NULL, this->autooob, 1);
rtn = nand_do_read_ecc(mtd, page, len, &retlen, buf, NULL, this->autooob, 1);
if (rtn) { /* if read failed or > 1-bit error corrected */
er_stat |= 1<<1; /* ECC read failed */
er_stat |= 1 << 1; /* ECC read failed */
}
kfree(buf);
}
@ -525,7 +505,7 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int s
}
rtn = status;
if (er_stat == 0) { /* if ECC is available */
if (er_stat == 0) { /* if ECC is available */
rtn = (status & ~NAND_STATUS_FAIL); /* clear the error bit */
}
@ -533,30 +513,28 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int s
}
#endif
/*
* Main initialization routine
*/
int __init rtc_from4_init (void)
int __init rtc_from4_init(void)
{
struct nand_chip *this;
unsigned short bcr1, bcr2, wcr2;
int i;
/* Allocate memory for MTD device structure and private data */
rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip),
GFP_KERNEL);
rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!rtc_from4_mtd) {
printk ("Unable to allocate Renesas NAND MTD device structure.\n");
printk("Unable to allocate Renesas NAND MTD device structure.\n");
return -ENOMEM;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&rtc_from4_mtd[1]);
this = (struct nand_chip *)(&rtc_from4_mtd[1]);
/* Initialize structures */
memset((char *) rtc_from4_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
memset(rtc_from4_mtd, 0, sizeof(struct mtd_info));
memset(this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
rtc_from4_mtd->priv = this;
@ -582,7 +560,7 @@ int __init rtc_from4_init (void)
/* Set address of hardware control function */
this->hwcontrol = rtc_from4_hwcontrol;
/* Set address of chip select function */
this->select_chip = rtc_from4_nand_select_chip;
this->select_chip = rtc_from4_nand_select_chip;
/* command delay time (in us) */
this->chip_delay = 100;
/* return the status of the Ready/Busy line */
@ -591,7 +569,7 @@ int __init rtc_from4_init (void)
#ifdef RTC_FROM4_HWECC
printk(KERN_INFO "rtc_from4_init: using hardware ECC detection.\n");
this->eccmode = NAND_ECC_HW8_512;
this->eccmode = NAND_ECC_HW8_512;
this->options |= NAND_HWECC_SYNDROME;
/* return the status of extra status and ECC checks */
this->errstat = rtc_from4_errstat;
@ -617,7 +595,7 @@ int __init rtc_from4_init (void)
}
/* Perform 'device recovery' for each chip in case there was a power loss. */
for (i=0; i < this->numchips; i++) {
for (i = 0; i < this->numchips; i++) {
deplete(rtc_from4_mtd, i);
}
@ -643,7 +621,7 @@ int __init rtc_from4_init (void)
*/
rs_decoder = init_rs(10, 0x409, 0, 1, 6);
if (!rs_decoder) {
printk (KERN_ERR "Could not create a RS decoder\n");
printk(KERN_ERR "Could not create a RS decoder\n");
nand_release(rtc_from4_mtd);
kfree(rtc_from4_mtd);
return -ENOMEM;
@ -652,20 +630,20 @@ int __init rtc_from4_init (void)
/* Return happy */
return 0;
}
module_init(rtc_from4_init);
module_init(rtc_from4_init);
/*
* Clean up routine
*/
#ifdef MODULE
static void __exit rtc_from4_cleanup (void)
static void __exit rtc_from4_cleanup(void)
{
/* Release resource, unregister partitions */
nand_release(rtc_from4_mtd);
/* Free the MTD device structure */
kfree (rtc_from4_mtd);
kfree(rtc_from4_mtd);
#ifdef RTC_FROM4_HWECC
/* Free the reed solomon resources */
@ -674,10 +652,10 @@ static void __exit rtc_from4_cleanup (void)
}
#endif
}
module_exit(rtc_from4_cleanup);
#endif
MODULE_LICENSE("GPL");
MODULE_AUTHOR("d.marlin <dmarlin@redhat.com");
MODULE_DESCRIPTION("Board-specific glue layer for AG-AND flash on Renesas FROM_BOARD4");

Просмотреть файл

@ -77,10 +77,10 @@ static int hardware_ecc = 0;
*/
static struct nand_oobinfo nand_hw_eccoob = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 3,
.eccpos = {0, 1, 2 },
.oobfree = { {8, 8} }
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 3,
.eccpos = {0, 1, 2},
.oobfree = {{8, 8}}
};
/* controller and mtd information */
@ -149,8 +149,7 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
pr_debug("result %d from %ld, %d\n", result, clk, wanted);
if (result > max) {
printk("%d ns is too big for current clock rate %ld\n",
wanted, clk);
printk("%d ns is too big for current clock rate %ld\n", wanted, clk);
return -1;
}
@ -164,8 +163,7 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
/* controller setup */
static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
struct platform_device *pdev)
static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, struct platform_device *pdev)
{
struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
unsigned long clkrate = clk_get_rate(info->clk);
@ -177,7 +175,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
clkrate /= 1000; /* turn clock into kHz for ease of use */
if (plat != NULL) {
tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);
} else {
@ -193,19 +191,17 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
}
printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
tacls, to_ns(tacls, clkrate),
twrph0, to_ns(twrph0, clkrate),
twrph1, to_ns(twrph1, clkrate));
tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate));
if (!info->is_s3c2440) {
cfg = S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls-1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);
cfg = S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
} else {
cfg = S3C2440_NFCONF_TACLS(tacls-1);
cfg |= S3C2440_NFCONF_TWRPH0(twrph0-1);
cfg |= S3C2440_NFCONF_TWRPH1(twrph1-1);
cfg = S3C2440_NFCONF_TACLS(tacls - 1);
cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
}
pr_debug(PFX "NF_CONF is 0x%lx\n", cfg);
@ -229,7 +225,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
info = nmtd->info;
bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE;
reg = info->regs+((info->is_s3c2440) ? S3C2440_NFCONT:S3C2410_NFCONF);
reg = info->regs + ((info->is_s3c2440) ? S3C2440_NFCONT : S3C2410_NFCONF);
cur = readl(reg);
@ -243,7 +239,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
if (info->platform != NULL) {
if (info->platform->select_chip != NULL)
(info->platform->select_chip)(nmtd->set, chip);
(info->platform->select_chip) (nmtd->set, chip);
}
cur &= ~bit;
@ -330,22 +326,16 @@ static int s3c2410_nand_devready(struct mtd_info *mtd)
return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
}
/* ECC handling functions */
static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc)
static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
{
pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n",
mtd, dat, read_ecc, calc_ecc);
pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc);
pr_debug("eccs: read %02x,%02x,%02x vs calc %02x,%02x,%02x\n",
read_ecc[0], read_ecc[1], read_ecc[2],
calc_ecc[0], calc_ecc[1], calc_ecc[2]);
read_ecc[0], read_ecc[1], read_ecc[2], calc_ecc[0], calc_ecc[1], calc_ecc[2]);
if (read_ecc[0] == calc_ecc[0] &&
read_ecc[1] == calc_ecc[1] &&
read_ecc[2] == calc_ecc[2])
if (read_ecc[0] == calc_ecc[0] && read_ecc[1] == calc_ecc[1] && read_ecc[2] == calc_ecc[2])
return 0;
/* we curently have no method for correcting the error */
@ -378,8 +368,7 @@ static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT);
}
static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
const u_char *dat, u_char *ecc_code)
static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
@ -387,15 +376,12 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1);
ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2);
pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n",
ecc_code[0], ecc_code[1], ecc_code[2]);
pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
return 0;
}
static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd,
const u_char *dat, u_char *ecc_code)
static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
unsigned long ecc = readl(info->regs + S3C2440_NFMECC0);
@ -404,13 +390,11 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd,
ecc_code[1] = ecc >> 8;
ecc_code[2] = ecc >> 16;
pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n",
ecc_code[0], ecc_code[1], ecc_code[2]);
pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
return 0;
}
/* over-ride the standard functions for a little more speed. We can
* use read/write block to move the data buffers to/from the controller
*/
@ -421,8 +405,7 @@ static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
readsb(this->IO_ADDR_R, buf, len);
}
static void s3c2410_nand_write_buf(struct mtd_info *mtd,
const u_char *buf, int len)
static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
writesb(this->IO_ADDR_W, buf, len);
@ -488,9 +471,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
return add_mtd_device(&mtd->mtd);
if (set->nr_partitions > 0 && set->partitions != NULL) {
return add_mtd_partitions(&mtd->mtd,
set->partitions,
set->nr_partitions);
return add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions);
}
return add_mtd_device(&mtd->mtd);
@ -654,13 +635,11 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440)
nmtd = info->mtds;
for (setno = 0; setno < nr_sets; setno++, nmtd++) {
pr_debug("initialising set %d (%p, info %p)\n",
setno, nmtd, info);
pr_debug("initialising set %d (%p, info %p)\n", setno, nmtd, info);
s3c2410_nand_init_chip(info, nmtd, sets);
nmtd->scan_res = nand_scan(&nmtd->mtd,
(sets) ? sets->nr_chips : 1);
nmtd->scan_res = nand_scan(&nmtd->mtd, (sets) ? sets->nr_chips : 1);
if (nmtd->scan_res == 0) {
s3c2410_nand_add_partition(info, nmtd, sets);

Просмотреть файл

@ -46,7 +46,6 @@ static int sharpsl_phys_base = 0x0C000000;
#define FLCLE (1 << 1)
#define FLCE0 (1 << 0)
/*
* MTD structure for SharpSL
*/
@ -60,27 +59,26 @@ static struct mtd_info *sharpsl_mtd = NULL;
static int nr_partitions;
static struct mtd_partition sharpsl_nand_default_partition_info[] = {
{
.name = "System Area",
.offset = 0,
.size = 7 * 1024 * 1024,
},
.name = "System Area",
.offset = 0,
.size = 7 * 1024 * 1024,
},
{
.name = "Root Filesystem",
.offset = 7 * 1024 * 1024,
.size = 30 * 1024 * 1024,
},
.name = "Root Filesystem",
.offset = 7 * 1024 * 1024,
.size = 30 * 1024 * 1024,
},
{
.name = "Home Filesystem",
.offset = MTDPART_OFS_APPEND ,
.size = MTDPART_SIZ_FULL ,
},
.name = "Home Filesystem",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
/*
* hardware specific access to control-lines
*/
static void
sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
switch (cmd) {
case NAND_CTL_SETCLE:
@ -98,10 +96,10 @@ sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
break;
case NAND_CTL_SETNCE:
writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
writeb(readb(FLASHCTL) & ~(FLCE0 | FLCE1), FLASHCTL);
break;
case NAND_CTL_CLRNCE:
writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
writeb(readb(FLASHCTL) | (FLCE0 | FLCE1), FLASHCTL);
break;
}
}
@ -126,27 +124,23 @@ static struct nand_oobinfo akita_oobinfo = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 24,
.eccpos = {
0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
.oobfree = { {0x08, 0x09} }
0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
.oobfree = {{0x08, 0x09}}
};
static int
sharpsl_nand_dev_ready(struct mtd_info* mtd)
static int sharpsl_nand_dev_ready(struct mtd_info *mtd)
{
return !((readb(FLASHCTL) & FLRYBY) == 0);
}
static void
sharpsl_nand_enable_hwecc(struct mtd_info* mtd, int mode)
static void sharpsl_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
writeb(0 ,ECCCLRR);
writeb(0, ECCCLRR);
}
static int
sharpsl_nand_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
u_char* ecc_code)
static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat, u_char * ecc_code)
{
ecc_code[0] = ~readb(ECCLPUB);
ecc_code[1] = ~readb(ECCLPLB);
@ -154,44 +148,40 @@ sharpsl_nand_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
return readb(ECCCNTR) != 0;
}
#ifdef CONFIG_MTD_PARTITIONS
const char *part_probes[] = { "cmdlinepart", NULL };
#endif
/*
* Main initialization routine
*/
int __init
sharpsl_nand_init(void)
int __init sharpsl_nand_init(void)
{
struct nand_chip *this;
struct mtd_partition* sharpsl_partition_info;
struct mtd_partition *sharpsl_partition_info;
int err = 0;
/* Allocate memory for MTD device structure and private data */
sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
GFP_KERNEL);
sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!sharpsl_mtd) {
printk ("Unable to allocate SharpSL NAND MTD device structure.\n");
printk("Unable to allocate SharpSL NAND MTD device structure.\n");
return -ENOMEM;
}
/* map physical adress */
sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
if(!sharpsl_io_base){
if (!sharpsl_io_base) {
printk("ioremap to access Sharp SL NAND chip failed\n");
kfree(sharpsl_mtd);
return -EIO;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&sharpsl_mtd[1]);
this = (struct nand_chip *)(&sharpsl_mtd[1]);
/* Initialize structures */
memset((char *) sharpsl_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
memset(sharpsl_mtd, 0, sizeof(struct mtd_info));
memset(this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
sharpsl_mtd->priv = this;
@ -221,7 +211,7 @@ sharpsl_nand_init(void)
this->correct_data = nand_correct_data;
/* Scan to find existence of the device */
err=nand_scan(sharpsl_mtd,1);
err = nand_scan(sharpsl_mtd, 1);
if (err) {
iounmap(sharpsl_io_base);
kfree(sharpsl_mtd);
@ -230,24 +220,23 @@ sharpsl_nand_init(void)
/* Register the partitions */
sharpsl_mtd->name = "sharpsl-nand";
nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes,
&sharpsl_partition_info, 0);
nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, &sharpsl_partition_info, 0);
if (nr_partitions <= 0) {
nr_partitions = DEFAULT_NUM_PARTITIONS;
sharpsl_partition_info = sharpsl_nand_default_partition_info;
if (machine_is_poodle()) {
sharpsl_partition_info[1].size=22 * 1024 * 1024;
sharpsl_partition_info[1].size = 22 * 1024 * 1024;
} else if (machine_is_corgi() || machine_is_shepherd()) {
sharpsl_partition_info[1].size=25 * 1024 * 1024;
sharpsl_partition_info[1].size = 25 * 1024 * 1024;
} else if (machine_is_husky()) {
sharpsl_partition_info[1].size=53 * 1024 * 1024;
sharpsl_partition_info[1].size = 53 * 1024 * 1024;
} else if (machine_is_spitz()) {
sharpsl_partition_info[1].size=5 * 1024 * 1024;
sharpsl_partition_info[1].size = 5 * 1024 * 1024;
} else if (machine_is_akita()) {
sharpsl_partition_info[1].size=58 * 1024 * 1024;
sharpsl_partition_info[1].size = 58 * 1024 * 1024;
} else if (machine_is_borzoi()) {
sharpsl_partition_info[1].size=32 * 1024 * 1024;
sharpsl_partition_info[1].size = 32 * 1024 * 1024;
}
}
@ -261,6 +250,7 @@ sharpsl_nand_init(void)
/* Return happy */
return 0;
}
module_init(sharpsl_nand_init);
/*
@ -269,7 +259,7 @@ module_init(sharpsl_nand_init);
#ifdef MODULE
static void __exit sharpsl_nand_cleanup(void)
{
struct nand_chip *this = (struct nand_chip *) &sharpsl_mtd[1];
struct nand_chip *this = (struct nand_chip *)&sharpsl_mtd[1];
/* Release resources, unregister device */
nand_release(sharpsl_mtd);
@ -279,6 +269,7 @@ static void __exit sharpsl_nand_cleanup(void)
/* Free the MTD device structure */
kfree(sharpsl_mtd);
}
module_exit(sharpsl_nand_cleanup);
#endif

Просмотреть файл

@ -39,16 +39,16 @@ static struct mtd_info *spia_mtd = NULL;
*/
#define SPIA_IO_BASE 0xd0000000 /* Start of EP7212 IO address space */
#define SPIA_FIO_BASE 0xf0000000 /* Address where flash is mapped */
#define SPIA_PEDR 0x0080 /*
* IO offset to Port E data register
* where the CLE, ALE and NCE pins
* are wired to.
*/
#define SPIA_PEDDR 0x00c0 /*
* IO offset to Port E data direction
* register so we can control the IO
* lines.
*/
#define SPIA_PEDR 0x0080 /*
* IO offset to Port E data register
* where the CLE, ALE and NCE pins
* are wired to.
*/
#define SPIA_PEDDR 0x00c0 /*
* IO offset to Port E data direction
* register so we can control the IO
* lines.
*/
/*
* Module stuff
@ -69,25 +69,23 @@ module_param(spia_peddr, int, 0);
*/
static const struct mtd_partition partition_info[] = {
{
.name = "SPIA flash partition 1",
.offset = 0,
.size = 2*1024*1024
},
.name = "SPIA flash partition 1",
.offset = 0,
.size = 2 * 1024 * 1024},
{
.name = "SPIA flash partition 2",
.offset = 2*1024*1024,
.size = 6*1024*1024
}
.name = "SPIA flash partition 2",
.offset = 2 * 1024 * 1024,
.size = 6 * 1024 * 1024}
};
#define NUM_PARTITIONS 2
#define NUM_PARTITIONS 2
/*
* hardware specific access to control-lines
*/
static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
switch(cmd){
static void spia_hwcontrol(struct mtd_info *mtd, int cmd)
{
switch (cmd) {
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;
@ -97,30 +95,29 @@ static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
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;
}
}
}
/*
* Main initialization routine
*/
int __init spia_init (void)
int __init spia_init(void)
{
struct nand_chip *this;
/* Allocate memory for MTD device structure and private data */
spia_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
GFP_KERNEL);
spia_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!spia_mtd) {
printk ("Unable to allocate SPIA NAND MTD device structure.\n");
printk("Unable to allocate SPIA NAND MTD device structure.\n");
return -ENOMEM;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&spia_mtd[1]);
this = (struct nand_chip *)(&spia_mtd[1]);
/* Initialize structures */
memset((char *) spia_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
memset(spia_mtd, 0, sizeof(struct mtd_info));
memset(this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
spia_mtd->priv = this;
@ -129,19 +126,19 @@ int __init spia_init (void)
* Set GPIO Port E control register so that the pins are configured
* to be outputs for controlling the NAND flash.
*/
(*(volatile unsigned char *) (spia_io_base + spia_peddr)) = 0x07;
(*(volatile unsigned char *)(spia_io_base + spia_peddr)) = 0x07;
/* Set address of NAND IO lines */
this->IO_ADDR_R = (void __iomem *) spia_fio_base;
this->IO_ADDR_W = (void __iomem *) spia_fio_base;
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->hwcontrol = spia_hwcontrol;
/* 15 us command delay time */
this->chip_delay = 15;
/* Scan to find existence of the device */
if (nand_scan (spia_mtd, 1)) {
kfree (spia_mtd);
if (nand_scan(spia_mtd, 1)) {
kfree(spia_mtd);
return -ENXIO;
}
@ -151,20 +148,22 @@ int __init spia_init (void)
/* Return happy */
return 0;
}
module_init(spia_init);
/*
* Clean up routine
*/
#ifdef MODULE
static void __exit spia_cleanup (void)
static void __exit spia_cleanup(void)
{
/* Release resources, unregister device */
nand_release (spia_mtd);
nand_release(spia_mtd);
/* Free the MTD device structure */
kfree (spia_mtd);
kfree(spia_mtd);
}
module_exit(spia_cleanup);
#endif

Просмотреть файл

@ -48,7 +48,7 @@ static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
#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 :( */
#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
@ -98,9 +98,8 @@ static struct mtd_partition partition_info32M[] = {
static void toto_hwcontrol(struct mtd_info *mtd, int cmd)
{
udelay(1); /* hopefully enough time for tc make proceding write to clear */
switch(cmd){
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;
@ -110,32 +109,31 @@ static void toto_hwcontrol(struct mtd_info *mtd, int cmd)
case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break;
case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break;
}
udelay(1); /* allow time to ensure gpio state to over take memory write */
udelay(1); /* allow time to ensure gpio state to over take memory write */
}
/*
* Main initialization routine
*/
int __init toto_init (void)
int __init toto_init(void)
{
struct nand_chip *this;
int err = 0;
/* Allocate memory for MTD device structure and private data */
toto_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
GFP_KERNEL);
toto_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!toto_mtd) {
printk (KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n");
printk(KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n");
err = -ENOMEM;
goto out;
}
/* Get pointer to private data */
this = (struct nand_chip *) (&toto_mtd[1]);
this = (struct nand_chip *)(&toto_mtd[1]);
/* Initialize structures */
memset((char *) toto_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
memset(toto_mtd, 0, sizeof(struct mtd_info));
memset(this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */
toto_mtd->priv = this;
@ -149,33 +147,37 @@ int __init toto_init (void)
this->chip_delay = 30;
this->eccmode = NAND_ECC_SOFT;
/* Scan to find existance of the device */
if (nand_scan (toto_mtd, 1)) {
/* Scan to find existance of the device */
if (nand_scan(toto_mtd, 1)) {
err = -ENXIO;
goto out_mtd;
}
/* Register the partitions */
switch(toto_mtd->size){
case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break;
case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break;
default: {
printk (KERN_WARNING "Unsupported Nand device\n");
switch (toto_mtd->size) {
case SZ_64M:
add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M);
break;
case SZ_32M:
add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M);
break;
default:{
printk(KERN_WARNING "Unsupported Nand device\n");
err = -ENXIO;
goto out_buf;
}
}
gpioreserve(NAND_MASK); /* claim our gpios */
archflashwp(0,0); /* open up flash for writing */
gpioreserve(NAND_MASK); /* claim our gpios */
archflashwp(0, 0); /* open up flash for writing */
goto out;
out_buf:
kfree (this->data_buf);
out_mtd:
kfree (toto_mtd);
out:
out_buf:
kfree(this->data_buf);
out_mtd:
kfree(toto_mtd);
out:
return err;
}
@ -184,20 +186,21 @@ module_init(toto_init);
/*
* Clean up routine
*/
static void __exit toto_cleanup (void)
static void __exit toto_cleanup(void)
{
/* Release resources, unregister device */
nand_release (toto_mtd);
nand_release(toto_mtd);
/* Free the MTD device structure */
kfree (toto_mtd);
kfree(toto_mtd);
/* stop flash writes */
archflashwp(0,1);
archflashwp(0, 1);
/* release gpios to system */
gpiorelease(NAND_MASK);
gpiorelease(NAND_MASK);
}
module_exit(toto_cleanup);
MODULE_LICENSE("GPL");

Просмотреть файл

@ -88,7 +88,7 @@ static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd)
{
unsigned long ctrl = TS72XX_NAND_CONTROL_VIRT_BASE;
switch(cmd) {
switch (cmd) {
case NAND_CTL_SETCLE:
__raw_writeb(__raw_readb(ctrl) | 0x2, ctrl);
break;
@ -132,8 +132,7 @@ static int __init ts7250_init(void)
return -ENXIO;
/* Allocate memory for MTD device structure and private data */
ts7250_mtd = kmalloc(sizeof(struct mtd_info) +
sizeof(struct nand_chip), GFP_KERNEL);
ts7250_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!ts7250_mtd) {
printk("Unable to allocate TS7250 NAND MTD device structure.\n");
return -ENOMEM;
@ -163,11 +162,9 @@ static int __init ts7250_init(void)
kfree(ts7250_mtd);
return -ENXIO;
}
#ifdef CONFIG_MTD_PARTITIONS
ts7250_mtd->name = "ts7250-nand";
mtd_parts_nb = parse_mtd_partitions(ts7250_mtd, part_probes,
&mtd_parts, 0);
mtd_parts_nb = parse_mtd_partitions(ts7250_mtd, part_probes, &mtd_parts, 0);
if (mtd_parts_nb > 0)
part_type = "command line";
else
@ -188,6 +185,7 @@ static int __init ts7250_init(void)
/* Return happy */
return 0;
}
module_init(ts7250_init);
/*
@ -201,6 +199,7 @@ static void __exit ts7250_cleanup(void)
/* Free the MTD device structure */
kfree(ts7250_mtd);
}
module_exit(ts7250_cleanup);
MODULE_LICENSE("GPL");