aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-27 22:13:56 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-27 22:13:56 -0400
commit936813a8807c5684c6a97f1081b31027403d4a93 (patch)
treebc3a1343ea1548195ab4e5dd11b1830f8b9cc52b /drivers/mtd
parent73a0e405dce7d720808536b708f7c738b413b1a2 (diff)
parent6a93096195305f6f2a39544a034e77e2e74d5799 (diff)
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: [MTD] NAND: Select chip before checking write protect status [MTD] CORE mtdchar.c: fix off-by-one error in lseek() [MTD] NAND: Fix typo in mtd/nand/ts7250.c [JFFS2][XATTR] coexistence between xattr and write buffering support. [JFFS2][XATTR] Fix wrong copyright [JFFS2][XATTR] Re-define xd->refcnt as atomic_t [JFFS2][XATTR] Fix memory leak with jffs2_xattr_ref [JFFS2][XATTR] rid unnecessary writing of delete marker. [JFFS2][XATTR] Fix ACL bug when updating null xattr by null ACL. [JFFS2][XATTR] using 'delete marker' for xdatum/xref deletion [MTD] Fix off-by-one error in physmap.c [MTD] Remove unused 'nr_banks' variable from ixp2000 map driver [MTD NAND] s3c2412 support in s3c2410.c [MTD] Initialize 'writesize' [MTD] NAND: ndfc fix address offset thinko [MTD] NAND: S3C2410 convert prinks to dev_*()s [MTD] NAND: Missing fixups
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c1
-rw-r--r--drivers/mtd/chips/jedec.c1
-rw-r--r--drivers/mtd/chips/map_absent.c3
-rw-r--r--drivers/mtd/chips/map_ram.c1
-rw-r--r--drivers/mtd/chips/map_rom.c1
-rw-r--r--drivers/mtd/devices/block2mtd.c1
-rw-r--r--drivers/mtd/devices/ms02-nv.c1
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c1
-rw-r--r--drivers/mtd/devices/phram.c1
-rw-r--r--drivers/mtd/devices/pmc551.c3
-rw-r--r--drivers/mtd/devices/slram.c1
-rw-r--r--drivers/mtd/maps/ixp2000.c2
-rw-r--r--drivers/mtd/maps/physmap.c2
-rw-r--r--drivers/mtd/mtdchar.c2
-rw-r--r--drivers/mtd/nand/nand_base.c16
-rw-r--r--drivers/mtd/nand/ndfc.c6
-rw-r--r--drivers/mtd/nand/s3c2410.c164
-rw-r--r--drivers/mtd/nand/ts7250.c2
18 files changed, 142 insertions, 67 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 0d435814aaa1..39edb8250fbc 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -357,6 +357,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
357 mtd->resume = cfi_intelext_resume; 357 mtd->resume = cfi_intelext_resume;
358 mtd->flags = MTD_CAP_NORFLASH; 358 mtd->flags = MTD_CAP_NORFLASH;
359 mtd->name = map->name; 359 mtd->name = map->name;
360 mtd->writesize = 1;
360 361
361 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; 362 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
362 363
diff --git a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
index c40b48dabed3..2c3f019197c1 100644
--- a/drivers/mtd/chips/jedec.c
+++ b/drivers/mtd/chips/jedec.c
@@ -256,6 +256,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
256 MTD->name = map->name; 256 MTD->name = map->name;
257 MTD->type = MTD_NORFLASH; 257 MTD->type = MTD_NORFLASH;
258 MTD->flags = MTD_CAP_NORFLASH; 258 MTD->flags = MTD_CAP_NORFLASH;
259 MTD->writesize = 1;
259 MTD->erasesize = SectorSize*(map->buswidth); 260 MTD->erasesize = SectorSize*(map->buswidth);
260 // printk("MTD->erasesize is %x\n",(unsigned int)MTD->erasesize); 261 // printk("MTD->erasesize is %x\n",(unsigned int)MTD->erasesize);
261 MTD->size = priv->size; 262 MTD->size = priv->size;
diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c
index a611de9b1515..ac01a949b687 100644
--- a/drivers/mtd/chips/map_absent.c
+++ b/drivers/mtd/chips/map_absent.c
@@ -64,7 +64,8 @@ static struct mtd_info *map_absent_probe(struct map_info *map)
64 mtd->write = map_absent_write; 64 mtd->write = map_absent_write;
65 mtd->sync = map_absent_sync; 65 mtd->sync = map_absent_sync;
66 mtd->flags = 0; 66 mtd->flags = 0;
67 mtd->erasesize = PAGE_SIZE; 67 mtd->erasesize = PAGE_SIZE;
68 mtd->writesize = 1;
68 69
69 __module_get(THIS_MODULE); 70 __module_get(THIS_MODULE);
70 return mtd; 71 return mtd;
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
index 763925747db6..3a66680abfd0 100644
--- a/drivers/mtd/chips/map_ram.c
+++ b/drivers/mtd/chips/map_ram.c
@@ -71,6 +71,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
71 mtd->write = mapram_write; 71 mtd->write = mapram_write;
72 mtd->sync = mapram_nop; 72 mtd->sync = mapram_nop;
73 mtd->flags = MTD_CAP_RAM; 73 mtd->flags = MTD_CAP_RAM;
74 mtd->writesize = 1;
74 75
75 mtd->erasesize = PAGE_SIZE; 76 mtd->erasesize = PAGE_SIZE;
76 while(mtd->size & (mtd->erasesize - 1)) 77 while(mtd->size & (mtd->erasesize - 1))
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
index bc6ee9ef8a31..1b328b1378fd 100644
--- a/drivers/mtd/chips/map_rom.c
+++ b/drivers/mtd/chips/map_rom.c
@@ -47,6 +47,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
47 mtd->sync = maprom_nop; 47 mtd->sync = maprom_nop;
48 mtd->flags = MTD_CAP_ROM; 48 mtd->flags = MTD_CAP_ROM;
49 mtd->erasesize = map->size; 49 mtd->erasesize = map->size;
50 mtd->writesize = 1;
50 51
51 __module_get(THIS_MODULE); 52 __module_get(THIS_MODULE);
52 return mtd; 53 return mtd;
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 0d98c223c5fc..be3f1c136d02 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -324,6 +324,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
324 324
325 dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; 325 dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
326 dev->mtd.erasesize = erase_size; 326 dev->mtd.erasesize = erase_size;
327 dev->mtd.writesize = 1;
327 dev->mtd.type = MTD_RAM; 328 dev->mtd.type = MTD_RAM;
328 dev->mtd.flags = MTD_CAP_RAM; 329 dev->mtd.flags = MTD_CAP_RAM;
329 dev->mtd.erase = block2mtd_erase; 330 dev->mtd.erase = block2mtd_erase;
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
index 4ab7670770e4..08dfb899b272 100644
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -225,6 +225,7 @@ static int __init ms02nv_init_one(ulong addr)
225 mtd->owner = THIS_MODULE; 225 mtd->owner = THIS_MODULE;
226 mtd->read = ms02nv_read; 226 mtd->read = ms02nv_read;
227 mtd->write = ms02nv_write; 227 mtd->write = ms02nv_write;
228 mtd->writesize = 1;
228 229
229 ret = -EIO; 230 ret = -EIO;
230 if (add_mtd_device(mtd)) { 231 if (add_mtd_device(mtd)) {
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index a19480d07888..04271d02b6b6 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -478,6 +478,7 @@ add_dataflash(struct spi_device *spi, char *name,
478 device->name = (pdata && pdata->name) ? pdata->name : priv->name; 478 device->name = (pdata && pdata->name) ? pdata->name : priv->name;
479 device->size = nr_pages * pagesize; 479 device->size = nr_pages * pagesize;
480 device->erasesize = pagesize; 480 device->erasesize = pagesize;
481 device->writesize = pagesize;
481 device->owner = THIS_MODULE; 482 device->owner = THIS_MODULE;
482 device->type = MTD_DATAFLASH; 483 device->type = MTD_DATAFLASH;
483 device->flags = MTD_CAP_NORFLASH; 484 device->flags = MTD_CAP_NORFLASH;
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index e09e416667d3..6c7337f9ebbb 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -151,6 +151,7 @@ static int register_device(char *name, unsigned long start, unsigned long len)
151 new->mtd.owner = THIS_MODULE; 151 new->mtd.owner = THIS_MODULE;
152 new->mtd.type = MTD_RAM; 152 new->mtd.type = MTD_RAM;
153 new->mtd.erasesize = PAGE_SIZE; 153 new->mtd.erasesize = PAGE_SIZE;
154 new->mtd.writesize = 1;
154 155
155 ret = -EAGAIN; 156 ret = -EAGAIN;
156 if (add_mtd_device(&new->mtd)) { 157 if (add_mtd_device(&new->mtd)) {
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index 666cce1bf60c..f620d74f1004 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -778,7 +778,8 @@ static int __init init_pmc551(void)
778 mtd->type = MTD_RAM; 778 mtd->type = MTD_RAM;
779 mtd->name = "PMC551 RAM board"; 779 mtd->name = "PMC551 RAM board";
780 mtd->erasesize = 0x10000; 780 mtd->erasesize = 0x10000;
781 mtd->owner = THIS_MODULE; 781 mtd->writesize = 1;
782 mtd->owner = THIS_MODULE;
782 783
783 if (add_mtd_device(mtd)) { 784 if (add_mtd_device(mtd)) {
784 printk(KERN_NOTICE "pmc551: Failed to register new device\n"); 785 printk(KERN_NOTICE "pmc551: Failed to register new device\n");
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index b3f665e3c38b..542a0c009006 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -209,6 +209,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
209 (*curmtd)->mtdinfo->owner = THIS_MODULE; 209 (*curmtd)->mtdinfo->owner = THIS_MODULE;
210 (*curmtd)->mtdinfo->type = MTD_RAM; 210 (*curmtd)->mtdinfo->type = MTD_RAM;
211 (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ; 211 (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ;
212 (*curmtd)->mtdinfo->writesize = 1;
212 213
213 if (add_mtd_device((*curmtd)->mtdinfo)) { 214 if (add_mtd_device((*curmtd)->mtdinfo)) {
214 E("slram: Failed to register new device\n"); 215 E("slram: Failed to register new device\n");
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index 2c9cc7f37e92..c26488a1793a 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -42,7 +42,6 @@ struct ixp2000_flash_info {
42 struct map_info map; 42 struct map_info map;
43 struct mtd_partition *partitions; 43 struct mtd_partition *partitions;
44 struct resource *res; 44 struct resource *res;
45 int nr_banks;
46}; 45};
47 46
48static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs) 47static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs)
@@ -183,7 +182,6 @@ static int ixp2000_flash_probe(struct platform_device *dev)
183 */ 182 */
184 info->map.phys = NO_XIP; 183 info->map.phys = NO_XIP;
185 184
186 info->nr_banks = ixp_data->nr_banks;
187 info->map.size = ixp_data->nr_banks * window_size; 185 info->map.size = ixp_data->nr_banks * window_size;
188 info->map.bankwidth = 1; 186 info->map.bankwidth = 1;
189 187
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 433c3cac3ca9..d6301f08906d 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -182,7 +182,7 @@ static struct physmap_flash_data physmap_flash_data = {
182 182
183static struct resource physmap_flash_resource = { 183static struct resource physmap_flash_resource = {
184 .start = CONFIG_MTD_PHYSMAP_START, 184 .start = CONFIG_MTD_PHYSMAP_START,
185 .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN, 185 .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN - 1,
186 .flags = IORESOURCE_MEM, 186 .flags = IORESOURCE_MEM,
187}; 187};
188 188
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index aa18d45b264b..9a4b59d92525 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -78,7 +78,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
78 return -EINVAL; 78 return -EINVAL;
79 } 79 }
80 80
81 if (offset >= 0 && offset < mtd->size) 81 if (offset >= 0 && offset <= mtd->size)
82 return file->f_pos = offset; 82 return file->f_pos = offset;
83 83
84 return -EINVAL; 84 return -EINVAL;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 27083ed0a017..80a76654d963 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1176,7 +1176,7 @@ static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
1176 1176
1177 status = chip->waitfunc(mtd, chip); 1177 status = chip->waitfunc(mtd, chip);
1178 1178
1179 return status; 1179 return status & NAND_STATUS_FAIL ? -EIO : 0;
1180} 1180}
1181 1181
1182/** 1182/**
@@ -1271,10 +1271,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1271 sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); 1271 sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
1272 buf = nand_transfer_oob(chip, buf, ops); 1272 buf = nand_transfer_oob(chip, buf, ops);
1273 1273
1274 readlen -= ops->ooblen;
1275 if (!readlen)
1276 break;
1277
1278 if (!(chip->options & NAND_NO_READRDY)) { 1274 if (!(chip->options & NAND_NO_READRDY)) {
1279 /* 1275 /*
1280 * Apply delay or wait for ready/busy pin. Do this 1276 * Apply delay or wait for ready/busy pin. Do this
@@ -1288,6 +1284,10 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1288 nand_wait_ready(mtd); 1284 nand_wait_ready(mtd);
1289 } 1285 }
1290 1286
1287 readlen -= ops->ooblen;
1288 if (!readlen)
1289 break;
1290
1291 /* Increment page address */ 1291 /* Increment page address */
1292 realpage++; 1292 realpage++;
1293 1293
@@ -1610,13 +1610,13 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
1610 if (!writelen) 1610 if (!writelen)
1611 return 0; 1611 return 0;
1612 1612
1613 chipnr = (int)(to >> chip->chip_shift);
1614 chip->select_chip(mtd, chipnr);
1615
1613 /* Check, if it is write protected */ 1616 /* Check, if it is write protected */
1614 if (nand_check_wp(mtd)) 1617 if (nand_check_wp(mtd))
1615 return -EIO; 1618 return -EIO;
1616 1619
1617 chipnr = (int)(to >> chip->chip_shift);
1618 chip->select_chip(mtd, chipnr);
1619
1620 realpage = (int)(to >> chip->page_shift); 1620 realpage = (int)(to >> chip->page_shift);
1621 page = realpage & chip->pagemask; 1621 page = realpage & chip->pagemask;
1622 blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; 1622 blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index fe8d38514ba6..e5bd88f2d560 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -61,15 +61,15 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip)
61 61
62static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) 62static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
63{ 63{
64 struct nand_chip *chip = mtd->priv; 64 struct ndfc_controller *ndfc = &ndfc_ctrl;
65 65
66 if (cmd == NAND_CMD_NONE) 66 if (cmd == NAND_CMD_NONE)
67 return; 67 return;
68 68
69 if (ctrl & NAND_CLE) 69 if (ctrl & NAND_CLE)
70 writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_CMD); 70 writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_CMD);
71 else 71 else
72 writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_ALE); 72 writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_ALE);
73} 73}
74 74
75static int ndfc_ready(struct mtd_info *mtd) 75static int ndfc_ready(struct mtd_info *mtd)
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 2c262fe03d8a..ff5cef24d5bb 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -63,8 +63,6 @@
63#include <asm/arch/regs-nand.h> 63#include <asm/arch/regs-nand.h>
64#include <asm/arch/nand.h> 64#include <asm/arch/nand.h>
65 65
66#define PFX "s3c2410-nand: "
67
68#ifdef CONFIG_MTD_NAND_S3C2410_HWECC 66#ifdef CONFIG_MTD_NAND_S3C2410_HWECC
69static int hardware_ecc = 1; 67static int hardware_ecc = 1;
70#else 68#else
@@ -99,6 +97,12 @@ struct s3c2410_nand_mtd {
99 int scan_res; 97 int scan_res;
100}; 98};
101 99
100enum s3c_cpu_type {
101 TYPE_S3C2410,
102 TYPE_S3C2412,
103 TYPE_S3C2440,
104};
105
102/* overview of the s3c2410 nand state */ 106/* overview of the s3c2410 nand state */
103 107
104struct s3c2410_nand_info { 108struct s3c2410_nand_info {
@@ -112,9 +116,11 @@ struct s3c2410_nand_info {
112 struct resource *area; 116 struct resource *area;
113 struct clk *clk; 117 struct clk *clk;
114 void __iomem *regs; 118 void __iomem *regs;
119 void __iomem *sel_reg;
120 int sel_bit;
115 int mtd_count; 121 int mtd_count;
116 122
117 unsigned char is_s3c2440; 123 enum s3c_cpu_type cpu_type;
118}; 124};
119 125
120/* conversion functions */ 126/* conversion functions */
@@ -148,7 +154,7 @@ static inline int allow_clk_stop(struct s3c2410_nand_info *info)
148 154
149#define NS_IN_KHZ 1000000 155#define NS_IN_KHZ 1000000
150 156
151static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max) 157static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max)
152{ 158{
153 int result; 159 int result;
154 160
@@ -172,53 +178,58 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
172 178
173/* controller setup */ 179/* controller setup */
174 180
175static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, struct platform_device *pdev) 181static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
182 struct platform_device *pdev)
176{ 183{
177 struct s3c2410_platform_nand *plat = to_nand_plat(pdev); 184 struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
178 unsigned long clkrate = clk_get_rate(info->clk); 185 unsigned long clkrate = clk_get_rate(info->clk);
186 int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4;
179 int tacls, twrph0, twrph1; 187 int tacls, twrph0, twrph1;
180 unsigned long cfg; 188 unsigned long cfg = 0;
181 189
182 /* calculate the timing information for the controller */ 190 /* calculate the timing information for the controller */
183 191
184 clkrate /= 1000; /* turn clock into kHz for ease of use */ 192 clkrate /= 1000; /* turn clock into kHz for ease of use */
185 193
186 if (plat != NULL) { 194 if (plat != NULL) {
187 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4); 195 tacls = s3c_nand_calc_rate(plat->tacls, clkrate, tacls_max);
188 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); 196 twrph0 = s3c_nand_calc_rate(plat->twrph0, clkrate, 8);
189 twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8); 197 twrph1 = s3c_nand_calc_rate(plat->twrph1, clkrate, 8);
190 } else { 198 } else {
191 /* default timings */ 199 /* default timings */
192 tacls = 4; 200 tacls = tacls_max;
193 twrph0 = 8; 201 twrph0 = 8;
194 twrph1 = 8; 202 twrph1 = 8;
195 } 203 }
196 204
197 if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { 205 if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {
198 printk(KERN_ERR PFX "cannot get timings suitable for board\n"); 206 dev_err(info->device, "cannot get suitable timings\n");
199 return -EINVAL; 207 return -EINVAL;
200 } 208 }
201 209
202 printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", 210 dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
203 tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate)); 211 tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate));
204 212
205 if (!info->is_s3c2440) { 213 switch (info->cpu_type) {
214 case TYPE_S3C2410:
206 cfg = S3C2410_NFCONF_EN; 215 cfg = S3C2410_NFCONF_EN;
207 cfg |= S3C2410_NFCONF_TACLS(tacls - 1); 216 cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
208 cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); 217 cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
209 cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); 218 cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
210 } else { 219 break;
220
221 case TYPE_S3C2440:
222 case TYPE_S3C2412:
211 cfg = S3C2440_NFCONF_TACLS(tacls - 1); 223 cfg = S3C2440_NFCONF_TACLS(tacls - 1);
212 cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); 224 cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
213 cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); 225 cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
214 226
215 /* enable the controller and de-assert nFCE */ 227 /* enable the controller and de-assert nFCE */
216 228
217 writel(S3C2440_NFCONT_ENABLE | S3C2440_NFCONT_ENABLE, 229 writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT);
218 info->regs + S3C2440_NFCONT);
219 } 230 }
220 231
221 pr_debug(PFX "NF_CONF is 0x%lx\n", cfg); 232 dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg);
222 233
223 writel(cfg, info->regs + S3C2410_NFCONF); 234 writel(cfg, info->regs + S3C2410_NFCONF);
224 return 0; 235 return 0;
@@ -231,26 +242,21 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
231 struct s3c2410_nand_info *info; 242 struct s3c2410_nand_info *info;
232 struct s3c2410_nand_mtd *nmtd; 243 struct s3c2410_nand_mtd *nmtd;
233 struct nand_chip *this = mtd->priv; 244 struct nand_chip *this = mtd->priv;
234 void __iomem *reg;
235 unsigned long cur; 245 unsigned long cur;
236 unsigned long bit;
237 246
238 nmtd = this->priv; 247 nmtd = this->priv;
239 info = nmtd->info; 248 info = nmtd->info;
240 249
241 bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE;
242 reg = info->regs + ((info->is_s3c2440) ? S3C2440_NFCONT : S3C2410_NFCONF);
243
244 if (chip != -1 && allow_clk_stop(info)) 250 if (chip != -1 && allow_clk_stop(info))
245 clk_enable(info->clk); 251 clk_enable(info->clk);
246 252
247 cur = readl(reg); 253 cur = readl(info->sel_reg);
248 254
249 if (chip == -1) { 255 if (chip == -1) {
250 cur |= bit; 256 cur |= info->sel_bit;
251 } else { 257 } else {
252 if (nmtd->set != NULL && chip > nmtd->set->nr_chips) { 258 if (nmtd->set != NULL && chip > nmtd->set->nr_chips) {
253 printk(KERN_ERR PFX "chip %d out of range\n", chip); 259 dev_err(info->device, "invalid chip %d\n", chip);
254 return; 260 return;
255 } 261 }
256 262
@@ -259,10 +265,10 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
259 (info->platform->select_chip) (nmtd->set, chip); 265 (info->platform->select_chip) (nmtd->set, chip);
260 } 266 }
261 267
262 cur &= ~bit; 268 cur &= ~info->sel_bit;
263 } 269 }
264 270
265 writel(cur, reg); 271 writel(cur, info->sel_reg);
266 272
267 if (chip == -1 && allow_clk_stop(info)) 273 if (chip == -1 && allow_clk_stop(info))
268 clk_disable(info->clk); 274 clk_disable(info->clk);
@@ -311,15 +317,25 @@ static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd,
311static int s3c2410_nand_devready(struct mtd_info *mtd) 317static int s3c2410_nand_devready(struct mtd_info *mtd)
312{ 318{
313 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 319 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
314
315 if (info->is_s3c2440)
316 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY;
317 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; 320 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
318} 321}
319 322
323static int s3c2440_nand_devready(struct mtd_info *mtd)
324{
325 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
326 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY;
327}
328
329static int s3c2412_nand_devready(struct mtd_info *mtd)
330{
331 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
332 return readb(info->regs + S3C2412_NFSTAT) & S3C2412_NFSTAT_READY;
333}
334
320/* ECC handling functions */ 335/* ECC handling functions */
321 336
322static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) 337static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
338 u_char *read_ecc, u_char *calc_ecc)
323{ 339{
324 pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc); 340 pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc);
325 341
@@ -487,11 +503,8 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
487 struct s3c2410_nand_set *set) 503 struct s3c2410_nand_set *set)
488{ 504{
489 struct nand_chip *chip = &nmtd->chip; 505 struct nand_chip *chip = &nmtd->chip;
506 void __iomem *regs = info->regs;
490 507
491 chip->IO_ADDR_R = info->regs + S3C2410_NFDATA;
492 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
493 chip->cmd_ctrl = s3c2410_nand_hwcontrol;
494 chip->dev_ready = s3c2410_nand_devready;
495 chip->write_buf = s3c2410_nand_write_buf; 508 chip->write_buf = s3c2410_nand_write_buf;
496 chip->read_buf = s3c2410_nand_read_buf; 509 chip->read_buf = s3c2410_nand_read_buf;
497 chip->select_chip = s3c2410_nand_select_chip; 510 chip->select_chip = s3c2410_nand_select_chip;
@@ -500,11 +513,37 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
500 chip->options = 0; 513 chip->options = 0;
501 chip->controller = &info->controller; 514 chip->controller = &info->controller;
502 515
503 if (info->is_s3c2440) { 516 switch (info->cpu_type) {
504 chip->IO_ADDR_R = info->regs + S3C2440_NFDATA; 517 case TYPE_S3C2410:
505 chip->IO_ADDR_W = info->regs + S3C2440_NFDATA; 518 chip->IO_ADDR_W = regs + S3C2410_NFDATA;
506 chip->cmd_ctrl = s3c2440_nand_hwcontrol; 519 info->sel_reg = regs + S3C2410_NFCONF;
507 } 520 info->sel_bit = S3C2410_NFCONF_nFCE;
521 chip->cmd_ctrl = s3c2410_nand_hwcontrol;
522 chip->dev_ready = s3c2410_nand_devready;
523 break;
524
525 case TYPE_S3C2440:
526 chip->IO_ADDR_W = regs + S3C2440_NFDATA;
527 info->sel_reg = regs + S3C2440_NFCONT;
528 info->sel_bit = S3C2440_NFCONT_nFCE;
529 chip->cmd_ctrl = s3c2440_nand_hwcontrol;
530 chip->dev_ready = s3c2440_nand_devready;
531 break;
532
533 case TYPE_S3C2412:
534 chip->IO_ADDR_W = regs + S3C2440_NFDATA;
535 info->sel_reg = regs + S3C2440_NFCONT;
536 info->sel_bit = S3C2412_NFCONT_nFCE0;
537 chip->cmd_ctrl = s3c2440_nand_hwcontrol;
538 chip->dev_ready = s3c2412_nand_devready;
539
540 if (readl(regs + S3C2410_NFCONF) & S3C2412_NFCONF_NANDBOOT)
541 dev_info(info->device, "System booted from NAND\n");
542
543 break;
544 }
545
546 chip->IO_ADDR_R = chip->IO_ADDR_W;
508 547
509 nmtd->info = info; 548 nmtd->info = info;
510 nmtd->mtd.priv = chip; 549 nmtd->mtd.priv = chip;
@@ -512,17 +551,25 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
512 nmtd->set = set; 551 nmtd->set = set;
513 552
514 if (hardware_ecc) { 553 if (hardware_ecc) {
515 chip->ecc.correct = s3c2410_nand_correct_data;
516 chip->ecc.hwctl = s3c2410_nand_enable_hwecc;
517 chip->ecc.calculate = s3c2410_nand_calculate_ecc; 554 chip->ecc.calculate = s3c2410_nand_calculate_ecc;
555 chip->ecc.correct = s3c2410_nand_correct_data;
518 chip->ecc.mode = NAND_ECC_HW; 556 chip->ecc.mode = NAND_ECC_HW;
519 chip->ecc.size = 512; 557 chip->ecc.size = 512;
520 chip->ecc.bytes = 3; 558 chip->ecc.bytes = 3;
521 chip->ecc.layout = &nand_hw_eccoob; 559 chip->ecc.layout = &nand_hw_eccoob;
522 560
523 if (info->is_s3c2440) { 561 switch (info->cpu_type) {
524 chip->ecc.hwctl = s3c2440_nand_enable_hwecc; 562 case TYPE_S3C2410:
525 chip->ecc.calculate = s3c2440_nand_calculate_ecc; 563 chip->ecc.hwctl = s3c2410_nand_enable_hwecc;
564 chip->ecc.calculate = s3c2410_nand_calculate_ecc;
565 break;
566
567 case TYPE_S3C2412:
568 case TYPE_S3C2440:
569 chip->ecc.hwctl = s3c2440_nand_enable_hwecc;
570 chip->ecc.calculate = s3c2440_nand_calculate_ecc;
571 break;
572
526 } 573 }
527 } else { 574 } else {
528 chip->ecc.mode = NAND_ECC_SOFT; 575 chip->ecc.mode = NAND_ECC_SOFT;
@@ -537,7 +584,8 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
537 * nand layer to look for devices 584 * nand layer to look for devices
538*/ 585*/
539 586
540static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440) 587static int s3c24xx_nand_probe(struct platform_device *pdev,
588 enum s3c_cpu_type cpu_type)
541{ 589{
542 struct s3c2410_platform_nand *plat = to_nand_plat(pdev); 590 struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
543 struct s3c2410_nand_info *info; 591 struct s3c2410_nand_info *info;
@@ -592,7 +640,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440)
592 info->device = &pdev->dev; 640 info->device = &pdev->dev;
593 info->platform = plat; 641 info->platform = plat;
594 info->regs = ioremap(res->start, size); 642 info->regs = ioremap(res->start, size);
595 info->is_s3c2440 = is_s3c2440; 643 info->cpu_type = cpu_type;
596 644
597 if (info->regs == NULL) { 645 if (info->regs == NULL) {
598 dev_err(&pdev->dev, "cannot reserve register region\n"); 646 dev_err(&pdev->dev, "cannot reserve register region\n");
@@ -699,12 +747,17 @@ static int s3c24xx_nand_resume(struct platform_device *dev)
699 747
700static int s3c2410_nand_probe(struct platform_device *dev) 748static int s3c2410_nand_probe(struct platform_device *dev)
701{ 749{
702 return s3c24xx_nand_probe(dev, 0); 750 return s3c24xx_nand_probe(dev, TYPE_S3C2410);
703} 751}
704 752
705static int s3c2440_nand_probe(struct platform_device *dev) 753static int s3c2440_nand_probe(struct platform_device *dev)
706{ 754{
707 return s3c24xx_nand_probe(dev, 1); 755 return s3c24xx_nand_probe(dev, TYPE_S3C2440);
756}
757
758static int s3c2412_nand_probe(struct platform_device *dev)
759{
760 return s3c24xx_nand_probe(dev, TYPE_S3C2412);
708} 761}
709 762
710static struct platform_driver s3c2410_nand_driver = { 763static struct platform_driver s3c2410_nand_driver = {
@@ -729,16 +782,29 @@ static struct platform_driver s3c2440_nand_driver = {
729 }, 782 },
730}; 783};
731 784
785static struct platform_driver s3c2412_nand_driver = {
786 .probe = s3c2412_nand_probe,
787 .remove = s3c2410_nand_remove,
788 .suspend = s3c24xx_nand_suspend,
789 .resume = s3c24xx_nand_resume,
790 .driver = {
791 .name = "s3c2412-nand",
792 .owner = THIS_MODULE,
793 },
794};
795
732static int __init s3c2410_nand_init(void) 796static int __init s3c2410_nand_init(void)
733{ 797{
734 printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n"); 798 printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");
735 799
800 platform_driver_register(&s3c2412_nand_driver);
736 platform_driver_register(&s3c2440_nand_driver); 801 platform_driver_register(&s3c2440_nand_driver);
737 return platform_driver_register(&s3c2410_nand_driver); 802 return platform_driver_register(&s3c2410_nand_driver);
738} 803}
739 804
740static void __exit s3c2410_nand_exit(void) 805static void __exit s3c2410_nand_exit(void)
741{ 806{
807 platform_driver_unregister(&s3c2412_nand_driver);
742 platform_driver_unregister(&s3c2440_nand_driver); 808 platform_driver_unregister(&s3c2440_nand_driver);
743 platform_driver_unregister(&s3c2410_nand_driver); 809 platform_driver_unregister(&s3c2410_nand_driver);
744} 810}
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c
index a0b4b1edcb0d..f40081069ab2 100644
--- a/drivers/mtd/nand/ts7250.c
+++ b/drivers/mtd/nand/ts7250.c
@@ -97,7 +97,7 @@ static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
97 unsigned long addr = TS72XX_NAND_CONTROL_VIRT_BASE; 97 unsigned long addr = TS72XX_NAND_CONTROL_VIRT_BASE;
98 unsigned char bits; 98 unsigned char bits;
99 99
100 bits = (ctrl & NAND_CNE) << 2; 100 bits = (ctrl & NAND_NCE) << 2;
101 bits |= ctrl & NAND_CLE; 101 bits |= ctrl & NAND_CLE;
102 bits |= (ctrl & NAND_ALE) >> 2; 102 bits |= (ctrl & NAND_ALE) >> 2;
103 103