[MTD] NAND s3c2410: Simplify command handling

Updated with tglx's suggestion to simply the command invocation by
simply changing the address of the IO write area

Signed-off-by: Ben Dooks <ben@simtec.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Ben Dooks 2005-03-17 11:31:30 +00:00 committed by Thomas Gleixner
parent 09c7933547
commit 3e4ef3bb77

View File

@ -11,9 +11,10 @@
* 23-Sep-2004 BJD Mulitple device support * 23-Sep-2004 BJD Mulitple device support
* 28-Sep-2004 BJD Fixed ECC placement for Hardware mode * 28-Sep-2004 BJD Fixed ECC placement for Hardware mode
* 12-Oct-2004 BJD Fixed errors in use of platform data * 12-Oct-2004 BJD Fixed errors in use of platform data
* 18-Feb-2004 BJD Fix sparse errors * 18-Feb-2005 BJD Fix sparse errors
* 14-Mar-2005 BJD Applied tglx's code reduction patch
* *
* $Id: s3c2410.c,v 1.8 2005/02/18 14:46:12 bjd Exp $ * $Id: s3c2410.c,v 1.12 2005/03/17 11:31:26 bjd Exp $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -236,6 +237,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd) static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{ {
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
struct nand_chip *chip = mtd->priv;
unsigned long cur; unsigned long cur;
switch (cmd) { switch (cmd) {
@ -251,117 +253,22 @@ static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
writel(cur, info->regs + S3C2410_NFCONF); writel(cur, info->regs + S3C2410_NFCONF);
break; break;
/* we don't need to implement these */
case NAND_CTL_SETCLE: case NAND_CTL_SETCLE:
case NAND_CTL_CLRCLE: chip->IO_ADDR_W = info->regs + S3C2410_NFCMD;
break;
case NAND_CTL_SETALE: case NAND_CTL_SETALE:
case NAND_CTL_CLRALE: chip->IO_ADDR_W = info->regs + S3C2410_NFADDR;
pr_debug(PFX "s3c2410_nand_hwcontrol(%d) unusedn", cmd); break;
/* NAND_CTL_CLRCLE: */
/* NAND_CTL_CLRALE: */
default:
chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
break; break;
} }
} }
/* s3c2410_nand_command
*
* This function implements sending commands and the relevant address
* information to the chip, via the hardware controller. Since the
* S3C2410 generates the correct ALE/CLE signaling automatically, we
* do not need to use hwcontrol.
*/
static void s3c2410_nand_command (struct mtd_info *mtd, unsigned command,
int column, int page_addr)
{
register struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
register struct nand_chip *this = mtd->priv;
/*
* Write out the command to the device.
*/
if (command == NAND_CMD_SEQIN) {
int readcmd;
if (column >= mtd->oobblock) {
/* OOB area */
column -= mtd->oobblock;
readcmd = NAND_CMD_READOOB;
} else if (column < 256) {
/* First 256 bytes --> READ0 */
readcmd = NAND_CMD_READ0;
} else {
column -= 256;
readcmd = NAND_CMD_READ1;
}
writeb(readcmd, info->regs + S3C2410_NFCMD);
}
writeb(command, info->regs + S3C2410_NFCMD);
/* Set ALE and clear CLE to start address cycle */
if (column != -1 || page_addr != -1) {
/* Serially input address */
if (column != -1) {
/* Adjust columns for 16 bit buswidth */
if (this->options & NAND_BUSWIDTH_16)
column >>= 1;
writeb(column, info->regs + S3C2410_NFADDR);
}
if (page_addr != -1) {
writeb((unsigned char) (page_addr), info->regs + S3C2410_NFADDR);
writeb((unsigned char) (page_addr >> 8), info->regs + S3C2410_NFADDR);
/* One more address cycle for higher density devices */
if (this->chipsize & 0x0c000000)
writeb((unsigned char) ((page_addr >> 16) & 0x0f),
info->regs + S3C2410_NFADDR);
}
/* Latch in address */
}
/*
* program and erase have their own busy handlers
* status and sequential in needs no delay
*/
switch (command) {
case NAND_CMD_PAGEPROG:
case NAND_CMD_ERASE1:
case NAND_CMD_ERASE2:
case NAND_CMD_SEQIN:
case NAND_CMD_STATUS:
return;
case NAND_CMD_RESET:
if (this->dev_ready)
break;
udelay(this->chip_delay);
writeb(NAND_CMD_STATUS, info->regs + S3C2410_NFCMD);
while ( !(this->read_byte(mtd) & 0x40));
return;
/* This applies to read commands */
default:
/*
* If we don't have access to the busy pin, we apply the given
* command delay
*/
if (!this->dev_ready) {
udelay (this->chip_delay);
return;
}
}
/* Apply this short delay always to ensure that we do wait tWB in
* any case on any machine. */
ndelay (100);
/* wait until command is processed */
while (!this->dev_ready(mtd));
}
/* s3c2410_nand_devready() /* s3c2410_nand_devready()
* *
* returns 0 if the nand is busy, 1 if it is ready * returns 0 if the nand is busy, 1 if it is ready
@ -529,7 +436,6 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
chip->hwcontrol = s3c2410_nand_hwcontrol; chip->hwcontrol = s3c2410_nand_hwcontrol;
chip->dev_ready = s3c2410_nand_devready; chip->dev_ready = s3c2410_nand_devready;
chip->cmdfunc = s3c2410_nand_command;
chip->write_buf = s3c2410_nand_write_buf; chip->write_buf = s3c2410_nand_write_buf;
chip->read_buf = s3c2410_nand_read_buf; chip->read_buf = s3c2410_nand_read_buf;
chip->select_chip = s3c2410_nand_select_chip; chip->select_chip = s3c2410_nand_select_chip;