From fdf2fd52746bbffeffa19e24cb0608abc5429bc2 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 18 Feb 2005 14:46:15 +0000 Subject: [MTD] Sparse fixes Fix sparse errors due to lack of address-space markers Updated header comments Small re-format of initialiser Signed-off-by: Ben Dooks Signed-off-by: Thomas Gleixner --- drivers/mtd/nand/s3c2410.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers/mtd/nand/s3c2410.c') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index d05e9b97947..cb04b3c771e 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -1,7 +1,8 @@ /* linux/drivers/mtd/nand/s3c2410.c * * Copyright (c) 2004 Simtec Electronics - * Ben Dooks + * http://www.simtec.co.uk/products/SWLINUX/ + * Ben Dooks * * Samsung S3C2410 NAND driver * @@ -10,8 +11,9 @@ * 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 * - * $Id: s3c2410.c,v 1.7 2005/01/05 18:05:14 dwmw2 Exp $ + * $Id: s3c2410.c,v 1.8 2005/02/18 14:46:12 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 @@ -69,10 +71,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 */ @@ -99,7 +101,7 @@ struct s3c2410_nand_info { struct device *device; struct resource *area; struct clk *clk; - void *regs; + void __iomem *regs; int mtd_count; }; @@ -523,8 +525,8 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, { struct nand_chip *chip = &nmtd->chip; - chip->IO_ADDR_R = (char *)info->regs + S3C2410_NFDATA; - chip->IO_ADDR_W = (char *)info->regs + S3C2410_NFDATA; + chip->IO_ADDR_R = info->regs + S3C2410_NFDATA; + chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; chip->hwcontrol = s3c2410_nand_hwcontrol; chip->dev_ready = s3c2410_nand_devready; chip->cmdfunc = s3c2410_nand_command; -- cgit v1.2.3 From 3e4ef3bb77f7b87c631ba188d4a4b4eb30b2f16f Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 17 Mar 2005 11:31:30 +0000 Subject: [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 Signed-off-by: Thomas Gleixner --- drivers/mtd/nand/s3c2410.c | 118 +++++---------------------------------------- 1 file changed, 12 insertions(+), 106 deletions(-) (limited to 'drivers/mtd/nand/s3c2410.c') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index cb04b3c771e..64b1d95e3e3 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; -- cgit v1.2.3 From a4f957f16d41b9ff944dddd84c4892496a129f68 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 20 Jun 2005 12:48:25 +0100 Subject: [MTD] NAND: s3c24xx updates Fix error in timing generation, Tacls is only in the range 0..3 Add proper support for the s3c2440 NAND controller, which has now been tested on several s3c2440 implementations. Signed-off-by: Ben Dooks Signed-off-by: Thomas Gleixner --- drivers/mtd/nand/s3c2410.c | 180 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 148 insertions(+), 32 deletions(-) (limited to 'drivers/mtd/nand/s3c2410.c') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 64b1d95e3e3..630a9c0edf3 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -1,10 +1,10 @@ /* linux/drivers/mtd/nand/s3c2410.c * - * Copyright (c) 2004 Simtec Electronics + * Copyright (c) 2004,2005 Simtec Electronics * http://www.simtec.co.uk/products/SWLINUX/ * Ben Dooks * - * Samsung S3C2410 NAND driver + * Samsung S3C2410/S3C240 NAND driver * * Changelog: * 21-Sep-2004 BJD Initial version @@ -13,8 +13,11 @@ * 12-Oct-2004 BJD Fixed errors in use of platform data * 18-Feb-2005 BJD Fix sparse errors * 14-Mar-2005 BJD Applied tglx's code reduction patch + * 02-May-2005 BJD Fixed s3c2440 support + * 02-May-2005 BJD Reduced hwcontrol decode + * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug * - * $Id: s3c2410.c,v 1.12 2005/03/17 11:31:26 bjd Exp $ + * $Id: s3c2410.c,v 1.13 2005/06/20 11:48:21 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 @@ -104,6 +107,8 @@ struct s3c2410_nand_info { struct clk *clk; void __iomem *regs; int mtd_count; + + unsigned char is_s3c2440; }; /* conversion functions */ @@ -168,12 +173,12 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, /* calculate the timing information for the controller */ if (plat != NULL) { - tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 8); + 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 { /* default timings */ - tacls = 8; + tacls = 4; twrph0 = 8; twrph1 = 8; } @@ -188,10 +193,16 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, to_ns(twrph0, clkrate), to_ns(twrph1, clkrate)); - cfg = S3C2410_NFCONF_EN; - cfg |= S3C2410_NFCONF_TACLS(tacls-1); - cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1); - cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1); + 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); + } else { + 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); @@ -206,15 +217,20 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) struct s3c2410_nand_info *info; struct s3c2410_nand_mtd *nmtd; struct nand_chip *this = mtd->priv; + void __iomem *reg; unsigned long cur; + unsigned long bit; nmtd = this->priv; info = nmtd->info; - cur = readl(info->regs + S3C2410_NFCONF); + bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE; + reg = info->regs+((info->is_s3c2440) ? S3C2440_NFCONT:S3C2410_NFCONF); + + cur = readl(reg); if (chip == -1) { - cur |= S3C2410_NFCONF_nFCE; + cur |= bit; } else { if (chip > nmtd->set->nr_chips) { printk(KERN_ERR PFX "chip %d out of range\n", chip); @@ -226,45 +242,72 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) (info->platform->select_chip)(nmtd->set, chip); } - cur &= ~S3C2410_NFCONF_nFCE; + cur &= ~bit; } - writel(cur, info->regs + S3C2410_NFCONF); + writel(cur, reg); } -/* command and control functions */ +/* command and control functions + * + * Note, these all use tglx's method of changing the IO_ADDR_W field + * to make the code simpler, and use the nand layer's code to issue the + * command and address sequences via the proper IO ports. + * +*/ 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) { case NAND_CTL_SETNCE: - cur = readl(info->regs + S3C2410_NFCONF); - cur &= ~S3C2410_NFCONF_nFCE; - writel(cur, info->regs + S3C2410_NFCONF); + case NAND_CTL_CLRNCE: + printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__); + break; + + case NAND_CTL_SETCLE: + chip->IO_ADDR_W = info->regs + S3C2410_NFCMD; + break; + + case NAND_CTL_SETALE: + chip->IO_ADDR_W = info->regs + S3C2410_NFADDR; + break; + + /* NAND_CTL_CLRCLE: */ + /* NAND_CTL_CLRALE: */ + default: + chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; break; + } +} + +/* command and control functions */ + +static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd) +{ + struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); + struct nand_chip *chip = mtd->priv; + switch (cmd) { + case NAND_CTL_SETNCE: case NAND_CTL_CLRNCE: - cur = readl(info->regs + S3C2410_NFCONF); - cur |= S3C2410_NFCONF_nFCE; - writel(cur, info->regs + S3C2410_NFCONF); + printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__); break; case NAND_CTL_SETCLE: - chip->IO_ADDR_W = info->regs + S3C2410_NFCMD; + chip->IO_ADDR_W = info->regs + S3C2440_NFCMD; break; case NAND_CTL_SETALE: - chip->IO_ADDR_W = info->regs + S3C2410_NFADDR; + chip->IO_ADDR_W = info->regs + S3C2440_NFADDR; break; /* NAND_CTL_CLRCLE: */ /* NAND_CTL_CLRALE: */ default: - chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; + chip->IO_ADDR_W = info->regs + S3C2440_NFDATA; break; } } @@ -278,9 +321,12 @@ static int s3c2410_nand_devready(struct mtd_info *mtd) { struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); + if (info->is_s3c2440) + return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; 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, @@ -303,6 +349,12 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, return -1; } +/* ECC functions + * + * These allow the s3c2410 and s3c2440 to use the controller's ECC + * generator block to ECC the data as it passes through] +*/ + static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode) { struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); @@ -313,6 +365,15 @@ static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode) writel(ctrl, info->regs + S3C2410_NFCONF); } +static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode) +{ + struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); + unsigned long ctrl; + + ctrl = readl(info->regs + S3C2440_NFCONT); + 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) { @@ -329,7 +390,26 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, } -/* over-ride the standard functions for a little more speed? */ +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); + + ecc_code[0] = ecc; + 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]); + + 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 +*/ static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { @@ -444,6 +524,12 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->options = 0; chip->controller = &info->controller; + if (info->is_s3c2440) { + chip->IO_ADDR_R = info->regs + S3C2440_NFDATA; + chip->IO_ADDR_W = info->regs + S3C2440_NFDATA; + chip->hwcontrol = s3c2440_nand_hwcontrol; + } + nmtd->info = info; nmtd->mtd.priv = chip; nmtd->set = set; @@ -454,6 +540,11 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->calculate_ecc = s3c2410_nand_calculate_ecc; chip->eccmode = NAND_ECC_HW3_512; chip->autooob = &nand_hw_eccoob; + + if (info->is_s3c2440) { + chip->enable_hwecc = s3c2440_nand_enable_hwecc; + chip->calculate_ecc = s3c2440_nand_calculate_ecc; + } } else { chip->eccmode = NAND_ECC_SOFT; } @@ -467,7 +558,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, * nand layer to look for devices */ -static int s3c2410_nand_probe(struct device *dev) +static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440) { struct platform_device *pdev = to_platform_device(dev); struct s3c2410_platform_nand *plat = to_nand_plat(dev); @@ -493,6 +584,7 @@ static int s3c2410_nand_probe(struct device *dev) dev_set_drvdata(dev, info); spin_lock_init(&info->controller.lock); + init_waitqueue_head(&info->controller.wq); /* get the clock source and enable it */ @@ -508,7 +600,8 @@ static int s3c2410_nand_probe(struct device *dev) /* allocate and map the resource */ - res = pdev->resource; /* assume that the flash has one resource */ + /* currently we assume we have the one resource */ + res = pdev->resource; size = res->end - res->start + 1; info->area = request_mem_region(res->start, size, pdev->name); @@ -519,9 +612,10 @@ static int s3c2410_nand_probe(struct device *dev) goto exit_error; } - info->device = dev; - info->platform = plat; - info->regs = ioremap(res->start, size); + info->device = dev; + info->platform = plat; + info->regs = ioremap(res->start, size); + info->is_s3c2440 = is_s3c2440; if (info->regs == NULL) { printk(KERN_ERR PFX "cannot reserve register region\n"); @@ -586,6 +680,18 @@ static int s3c2410_nand_probe(struct device *dev) return err; } +/* driver device registration */ + +static int s3c2410_nand_probe(struct device *dev) +{ + return s3c24xx_nand_probe(dev, 0); +} + +static int s3c2440_nand_probe(struct device *dev) +{ + return s3c24xx_nand_probe(dev, 1); +} + static struct device_driver s3c2410_nand_driver = { .name = "s3c2410-nand", .bus = &platform_bus_type, @@ -593,14 +699,24 @@ static struct device_driver s3c2410_nand_driver = { .remove = s3c2410_nand_remove, }; +static struct device_driver s3c2440_nand_driver = { + .name = "s3c2440-nand", + .bus = &platform_bus_type, + .probe = s3c2440_nand_probe, + .remove = s3c2410_nand_remove, +}; + static int __init s3c2410_nand_init(void) { - printk("S3C2410 NAND Driver, (c) 2004 Simtec Electronics\n"); + printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n"); + + driver_register(&s3c2440_nand_driver); return driver_register(&s3c2410_nand_driver); } static void __exit s3c2410_nand_exit(void) { + driver_unregister(&s3c2440_nand_driver); driver_unregister(&s3c2410_nand_driver); } @@ -609,4 +725,4 @@ module_exit(s3c2410_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ben Dooks "); -MODULE_DESCRIPTION("S3C2410 MTD NAND driver"); +MODULE_DESCRIPTION("S3C24XX MTD NAND driver"); -- cgit v1.2.3 From fb8d82a865b1ff601fad8293cd6a2a1b1908545b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 6 Jul 2005 21:05:10 +0100 Subject: [MTD] NAND s3c2410: Add missing NULL pointer check Fix OOPs if there was no platform set information passed Signed-off-by: Ben Dooks Signed-off-by: Thomas Gleixner --- drivers/mtd/nand/s3c2410.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/mtd/nand/s3c2410.c') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 630a9c0edf3..891e3a1b911 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -16,8 +16,9 @@ * 02-May-2005 BJD Fixed s3c2440 support * 02-May-2005 BJD Reduced hwcontrol decode * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug + * 08-Jul-2005 BJD Fix OOPS when no platform data supplied * - * $Id: s3c2410.c,v 1.13 2005/06/20 11:48:21 bjd Exp $ + * $Id: s3c2410.c,v 1.14 2005/07/06 20:05:06 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 @@ -232,7 +233,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) if (chip == -1) { cur |= bit; } else { - if (chip > nmtd->set->nr_chips) { + if (nmtd->set != NULL && chip > nmtd->set->nr_chips) { printk(KERN_ERR PFX "chip %d out of range\n", chip); return; } -- cgit v1.2.3