summaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorBen Dooks <ben@simtec.co.uk>2005-03-17 12:31:30 +0100
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-05-23 12:55:50 +0200
commit3e4ef3bb77f7b87c631ba188d4a4b4eb30b2f16f (patch)
tree3ca45d8f929bf85f79036d8419519073f79b9d0b /drivers/mtd
parent[MTD] cfi_cmdset_0001: Fix state after sync (diff)
downloadlinux-3e4ef3bb77f7b87c631ba188d4a4b4eb30b2f16f.tar.xz
linux-3e4ef3bb77f7b87c631ba188d4a4b4eb30b2f16f.zip
[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>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/s3c2410.c118
1 files changed, 12 insertions, 106 deletions
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index cb04b3c771e4..64b1d95e3e37 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -11,9 +11,10 @@
* 23-Sep-2004 BJD Mulitple device support
* 28-Sep-2004 BJD Fixed ECC placement for Hardware mode
* 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
* 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)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+ struct nand_chip *chip = mtd->priv;
unsigned long cur;
switch (cmd) {
@@ -251,117 +253,22 @@ static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
writel(cur, info->regs + S3C2410_NFCONF);
break;
- /* we don't need to implement these */
case NAND_CTL_SETCLE:
- case NAND_CTL_CLRCLE:
- case NAND_CTL_SETALE:
- case NAND_CTL_CLRALE:
- pr_debug(PFX "s3c2410_nand_hwcontrol(%d) unusedn", cmd);
+ chip->IO_ADDR_W = info->regs + S3C2410_NFCMD;
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) {
+ case NAND_CTL_SETALE:
+ chip->IO_ADDR_W = info->regs + S3C2410_NFADDR;
+ break;
- /* 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 */
+ /* NAND_CTL_CLRCLE: */
+ /* NAND_CTL_CLRALE: */
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;
- }
+ chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
+ break;
}
-
- /* 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()
*
* 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->hwcontrol = s3c2410_nand_hwcontrol;
chip->dev_ready = s3c2410_nand_devready;
- chip->cmdfunc = s3c2410_nand_command;
chip->write_buf = s3c2410_nand_write_buf;
chip->read_buf = s3c2410_nand_read_buf;
chip->select_chip = s3c2410_nand_select_chip;