Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Ben Dooks and committed by
Thomas Gleixner
3e4ef3bb 09c79335

+14 -108
+14 -108
drivers/mtd/nand/s3c2410.c
··· 11 11 * 23-Sep-2004 BJD Mulitple device support 12 12 * 28-Sep-2004 BJD Fixed ECC placement for Hardware mode 13 13 * 12-Oct-2004 BJD Fixed errors in use of platform data 14 - * 18-Feb-2004 BJD Fix sparse errors 14 + * 18-Feb-2005 BJD Fix sparse errors 15 + * 14-Mar-2005 BJD Applied tglx's code reduction patch 15 16 * 16 - * $Id: s3c2410.c,v 1.8 2005/02/18 14:46:12 bjd Exp $ 17 + * $Id: s3c2410.c,v 1.12 2005/03/17 11:31:26 bjd Exp $ 17 18 * 18 19 * This program is free software; you can redistribute it and/or modify 19 20 * it under the terms of the GNU General Public License as published by ··· 237 236 static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd) 238 237 { 239 238 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 239 + struct nand_chip *chip = mtd->priv; 240 240 unsigned long cur; 241 241 242 242 switch (cmd) { ··· 253 251 writel(cur, info->regs + S3C2410_NFCONF); 254 252 break; 255 253 256 - /* we don't need to implement these */ 257 254 case NAND_CTL_SETCLE: 258 - case NAND_CTL_CLRCLE: 255 + chip->IO_ADDR_W = info->regs + S3C2410_NFCMD; 256 + break; 257 + 259 258 case NAND_CTL_SETALE: 260 - case NAND_CTL_CLRALE: 261 - pr_debug(PFX "s3c2410_nand_hwcontrol(%d) unusedn", cmd); 259 + chip->IO_ADDR_W = info->regs + S3C2410_NFADDR; 260 + break; 261 + 262 + /* NAND_CTL_CLRCLE: */ 263 + /* NAND_CTL_CLRALE: */ 264 + default: 265 + chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; 262 266 break; 263 267 } 264 268 } 265 - 266 - /* s3c2410_nand_command 267 - * 268 - * This function implements sending commands and the relevant address 269 - * information to the chip, via the hardware controller. Since the 270 - * S3C2410 generates the correct ALE/CLE signaling automatically, we 271 - * do not need to use hwcontrol. 272 - */ 273 - 274 - static void s3c2410_nand_command (struct mtd_info *mtd, unsigned command, 275 - int column, int page_addr) 276 - { 277 - register struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 278 - register struct nand_chip *this = mtd->priv; 279 - 280 - /* 281 - * Write out the command to the device. 282 - */ 283 - if (command == NAND_CMD_SEQIN) { 284 - int readcmd; 285 - 286 - if (column >= mtd->oobblock) { 287 - /* OOB area */ 288 - column -= mtd->oobblock; 289 - readcmd = NAND_CMD_READOOB; 290 - } else if (column < 256) { 291 - /* First 256 bytes --> READ0 */ 292 - readcmd = NAND_CMD_READ0; 293 - } else { 294 - column -= 256; 295 - readcmd = NAND_CMD_READ1; 296 - } 297 - 298 - writeb(readcmd, info->regs + S3C2410_NFCMD); 299 - } 300 - writeb(command, info->regs + S3C2410_NFCMD); 301 - 302 - /* Set ALE and clear CLE to start address cycle */ 303 - 304 - if (column != -1 || page_addr != -1) { 305 - 306 - /* Serially input address */ 307 - if (column != -1) { 308 - /* Adjust columns for 16 bit buswidth */ 309 - if (this->options & NAND_BUSWIDTH_16) 310 - column >>= 1; 311 - writeb(column, info->regs + S3C2410_NFADDR); 312 - } 313 - if (page_addr != -1) { 314 - writeb((unsigned char) (page_addr), info->regs + S3C2410_NFADDR); 315 - writeb((unsigned char) (page_addr >> 8), info->regs + S3C2410_NFADDR); 316 - /* One more address cycle for higher density devices */ 317 - if (this->chipsize & 0x0c000000) 318 - writeb((unsigned char) ((page_addr >> 16) & 0x0f), 319 - info->regs + S3C2410_NFADDR); 320 - } 321 - /* Latch in address */ 322 - } 323 - 324 - /* 325 - * program and erase have their own busy handlers 326 - * status and sequential in needs no delay 327 - */ 328 - switch (command) { 329 - 330 - case NAND_CMD_PAGEPROG: 331 - case NAND_CMD_ERASE1: 332 - case NAND_CMD_ERASE2: 333 - case NAND_CMD_SEQIN: 334 - case NAND_CMD_STATUS: 335 - return; 336 - 337 - case NAND_CMD_RESET: 338 - if (this->dev_ready) 339 - break; 340 - 341 - udelay(this->chip_delay); 342 - writeb(NAND_CMD_STATUS, info->regs + S3C2410_NFCMD); 343 - 344 - while ( !(this->read_byte(mtd) & 0x40)); 345 - return; 346 - 347 - /* This applies to read commands */ 348 - default: 349 - /* 350 - * If we don't have access to the busy pin, we apply the given 351 - * command delay 352 - */ 353 - if (!this->dev_ready) { 354 - udelay (this->chip_delay); 355 - return; 356 - } 357 - } 358 - 359 - /* Apply this short delay always to ensure that we do wait tWB in 360 - * any case on any machine. */ 361 - ndelay (100); 362 - /* wait until command is processed */ 363 - while (!this->dev_ready(mtd)); 364 - } 365 - 366 269 367 270 /* s3c2410_nand_devready() 368 271 * ··· 436 529 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; 437 530 chip->hwcontrol = s3c2410_nand_hwcontrol; 438 531 chip->dev_ready = s3c2410_nand_devready; 439 - chip->cmdfunc = s3c2410_nand_command; 440 532 chip->write_buf = s3c2410_nand_write_buf; 441 533 chip->read_buf = s3c2410_nand_read_buf; 442 534 chip->select_chip = s3c2410_nand_select_chip;