1 diff -Nur linux-2.4.30/drivers/mtd/chips/Config.in linux-2.4.30.openwrt/drivers/mtd/chips/Config.in
2 --- linux-2.4.30/drivers/mtd/chips/Config.in 2003-06-13 16:51:34.000000000 +0200
3 +++ linux-2.4.30.openwrt/drivers/mtd/chips/Config.in 2005-06-28 11:26:26.000000000 +0200
5 dep_tristate ' Support for Intel/Sharp flash chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_GEN_PROBE
6 dep_tristate ' Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_GEN_PROBE
7 dep_tristate ' Support for ST (Advanced Architecture) flash chips' CONFIG_MTD_CFI_STAA $CONFIG_MTD_GEN_PROBE
8 +dep_tristate ' Support for SST flash chips' CONFIG_MTD_CFI_SSTSTD $CONFIG_MTD_GEN_PROBE
10 dep_tristate ' Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
11 dep_tristate ' Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD
12 diff -Nur linux-2.4.30/drivers/mtd/chips/Makefile linux-2.4.30.openwrt/drivers/mtd/chips/Makefile
13 --- linux-2.4.30/drivers/mtd/chips/Makefile 2003-06-13 16:51:34.000000000 +0200
14 +++ linux-2.4.30.openwrt/drivers/mtd/chips/Makefile 2005-06-28 11:26:26.000000000 +0200
16 obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
17 obj-$(CONFIG_MTD_CFI) += cfi_probe.o
18 obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
19 +obj-$(CONFIG_MTD_CFI_SSTSTD) += cfi_cmdset_0701.o
20 obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o
21 obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o
22 obj-$(CONFIG_MTD_GEN_PROBE) += gen_probe.o
23 diff -Nur linux-2.4.30/drivers/mtd/chips/cfi_cmdset_0701.c linux-2.4.30.openwrt/drivers/mtd/chips/cfi_cmdset_0701.c
24 --- linux-2.4.30/drivers/mtd/chips/cfi_cmdset_0701.c 1970-01-01 01:00:00.000000000 +0100
25 +++ linux-2.4.30.openwrt/drivers/mtd/chips/cfi_cmdset_0701.c 2005-06-28 11:26:26.000000000 +0200
28 + * Common Flash Interface support:
29 + * SST Standard Vendor Command Set (ID 0x0701)
31 + * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
33 + * 2_by_8 routines added by Simon Munton
37 + * $Id: cfi_cmdset_0701.c,v 1.1 2005/03/16 13:50:00 wbx Exp $
41 +#include <linux/module.h>
42 +#include <linux/types.h>
43 +#include <linux/kernel.h>
44 +#include <linux/sched.h>
46 +#include <asm/byteorder.h>
48 +#include <linux/errno.h>
49 +#include <linux/slab.h>
50 +#include <linux/delay.h>
51 +#include <linux/interrupt.h>
52 +#include <linux/mtd/map.h>
53 +#include <linux/mtd/cfi.h>
55 +static int cfi_sststd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
56 +static int cfi_sststd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
57 +static int cfi_sststd_erase_onesize(struct mtd_info *, struct erase_info *);
58 +static int cfi_sststd_erase_varsize(struct mtd_info *, struct erase_info *);
59 +static void cfi_sststd_sync (struct mtd_info *);
60 +static int cfi_sststd_suspend (struct mtd_info *);
61 +static void cfi_sststd_resume (struct mtd_info *);
63 +static void cfi_sststd_destroy(struct mtd_info *);
65 +struct mtd_info *cfi_cmdset_0701(struct map_info *, int);
66 +static struct mtd_info *cfi_sststd_setup (struct map_info *);
69 +static struct mtd_chip_driver cfi_sststd_chipdrv = {
70 + probe: NULL, /* Not usable directly */
71 + destroy: cfi_sststd_destroy,
72 + name: "cfi_cmdset_0701",
76 +struct mtd_info *cfi_cmdset_0701(struct map_info *map, int primary)
78 + struct cfi_private *cfi = map->fldrv_priv;
79 + int ofs_factor = cfi->interleave * cfi->device_type;
82 + __u32 base = cfi->chips[0].start;
84 + if (cfi->cfi_mode==1){
85 + __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
87 + cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
88 + cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
89 + cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
91 + major = cfi_read_query(map, base + (adr+3)*ofs_factor);
92 + minor = cfi_read_query(map, base + (adr+4)*ofs_factor);
94 + printk(" SST Query Table v%c.%c at 0x%4.4X\n",
96 + cfi_send_gen_cmd(0xf0, 0x5555, base, map, cfi, cfi->device_type, NULL);
98 + cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
99 + cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
100 + cfi_send_gen_cmd(0x90, 0x5555, base, map, cfi, cfi->device_type, NULL);
101 + cfi->mfr = cfi_read_query(map, base);
102 + cfi->id = cfi_read_query(map, base + ofs_factor);
104 + cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
105 + cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
106 + cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
108 + switch (cfi->device_type) {
109 + case CFI_DEVICETYPE_X16:
110 + cfi->addr_unlock1 = 0x5555;
111 + cfi->addr_unlock2 = 0x2AAA;
114 + printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0701 device type %d\n", cfi->device_type);
119 + for (i=0; i< cfi->numchips; i++) {
120 + cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
121 + cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
122 + cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
125 + map->fldrv = &cfi_sststd_chipdrv;
128 + cfi_send_gen_cmd(0xf0, 0x5555, base, map, cfi, cfi->device_type, NULL);
129 + return cfi_sststd_setup(map);
132 +static struct mtd_info *cfi_sststd_setup(struct map_info *map)
134 + struct cfi_private *cfi = map->fldrv_priv;
135 + struct mtd_info *mtd;
136 + unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
138 + mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
139 + printk("number of %s chips: %d\n", (cfi->cfi_mode)?"JEDEC":"CFI",cfi->numchips);
142 + printk("Failed to allocate memory for MTD device\n");
143 + kfree(cfi->cmdset_priv);
147 + memset(mtd, 0, sizeof(*mtd));
149 + mtd->type = MTD_NORFLASH;
150 + /* Also select the correct geometry setup too */
151 + mtd->size = devsize * cfi->numchips;
153 + if (cfi->cfiq->NumEraseRegions == 1) {
154 + /* No need to muck about with multiple erase sizes */
155 + mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave;
157 + unsigned long offset = 0;
160 + mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
161 + mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL);
162 + if (!mtd->eraseregions) {
163 + printk("Failed to allocate memory for MTD erase region info\n");
164 + kfree(cfi->cmdset_priv);
168 + for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
169 + unsigned long ernum, ersize;
170 + ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
171 + ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
173 + if (mtd->erasesize < ersize) {
174 + mtd->erasesize = ersize;
176 + for (j=0; j<cfi->numchips; j++) {
177 + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
178 + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
179 + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
181 + offset += (ersize * ernum);
185 + for (i=0; i<mtd->numeraseregions;i++){
186 + printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
187 + i,mtd->eraseregions[i].offset,
188 + mtd->eraseregions[i].erasesize,
189 + mtd->eraseregions[i].numblocks);
193 + switch (CFIDEV_BUSWIDTH)
198 + if (mtd->numeraseregions > 1)
199 + mtd->erase = cfi_sststd_erase_varsize;
201 + mtd->erase = cfi_sststd_erase_onesize;
202 + mtd->read = cfi_sststd_read;
203 + mtd->write = cfi_sststd_write;
207 + printk("Unsupported buswidth\n");
209 + kfree(cfi->cmdset_priv);
213 + mtd->sync = cfi_sststd_sync;
214 + mtd->suspend = cfi_sststd_suspend;
215 + mtd->resume = cfi_sststd_resume;
216 + mtd->flags = MTD_CAP_NORFLASH;
217 + map->fldrv = &cfi_sststd_chipdrv;
218 + mtd->name = map->name;
223 +static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
225 + DECLARE_WAITQUEUE(wait, current);
226 + unsigned long timeo = jiffies + HZ;
229 + cfi_spin_lock(chip->mutex);
231 + if (chip->state != FL_READY){
232 + printk("Waiting for chip to read, status = %d\n", chip->state);
233 + set_current_state(TASK_UNINTERRUPTIBLE);
234 + add_wait_queue(&chip->wq, &wait);
236 + cfi_spin_unlock(chip->mutex);
239 + remove_wait_queue(&chip->wq, &wait);
240 + timeo = jiffies + HZ;
245 + adr += chip->start;
247 + chip->state = FL_READY;
249 + map->copy_from(map, buf, adr, len);
251 + wake_up(&chip->wq);
252 + cfi_spin_unlock(chip->mutex);
257 +static int cfi_sststd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
259 + struct map_info *map = mtd->priv;
260 + struct cfi_private *cfi = map->fldrv_priv;
265 + /* ofs: offset within the first chip that the first read should start */
267 + chipnum = (from >> cfi->chipshift);
268 + ofs = from - (chipnum << cfi->chipshift);
274 + unsigned long thislen;
276 + if (chipnum >= cfi->numchips)
279 + if ((len + ofs -1) >> cfi->chipshift)
280 + thislen = (1<<cfi->chipshift) - ofs;
284 + ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
288 + *retlen += thislen;
298 +static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast)
300 + unsigned long timeo = jiffies + HZ;
301 + unsigned int Last[4];
302 + unsigned long Count = 0;
303 + struct cfi_private *cfi = map->fldrv_priv;
304 + DECLARE_WAITQUEUE(wait, current);
308 + cfi_spin_lock(chip->mutex);
310 + if (chip->state != FL_READY){
311 + printk("Waiting for chip to write, status = %d\n", chip->state);
312 + set_current_state(TASK_UNINTERRUPTIBLE);
313 + add_wait_queue(&chip->wq, &wait);
315 + cfi_spin_unlock(chip->mutex);
318 + remove_wait_queue(&chip->wq, &wait);
319 + printk("Wake up to write:\n");
320 + timeo = jiffies + HZ;
325 + chip->state = FL_WRITING;
327 + adr += chip->start;
329 + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
330 + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
331 + cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
333 + cfi_write(map, datum, adr);
335 + cfi_spin_unlock(chip->mutex);
336 + cfi_udelay(chip->word_write_time);
337 + cfi_spin_lock(chip->mutex);
339 + Last[0] = cfi_read(map, adr);
340 + // printk("Last[0] is %x\n", Last[0]);
341 + Last[1] = cfi_read(map, adr);
342 + // printk("Last[1] is %x\n", Last[1]);
343 + Last[2] = cfi_read(map, adr);
344 + // printk("Last[2] is %x\n", Last[2]);
346 + for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && Count < 10000; Count++){
347 + cfi_spin_unlock(chip->mutex);
349 + cfi_spin_lock(chip->mutex);
351 + Last[Count % 4] = cfi_read(map, adr);
352 + // printk("Last[%d%%4] is %x\n", Count, Last[Count%4]);
355 + if (Last[(Count - 1) % 4] != datum){
356 + printk("Last[%ld] is %x, datum is %x\n",(Count - 1) % 4,Last[(Count - 1) % 4],datum);
357 + cfi_send_gen_cmd(0xF0, 0, chip->start, map, cfi, cfi->device_type, NULL);
362 + chip->state = FL_READY;
363 + wake_up(&chip->wq);
364 + cfi_spin_unlock(chip->mutex);
369 +static int cfi_sststd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
371 + struct map_info *map = mtd->priv;
372 + struct cfi_private *cfi = map->fldrv_priv;
375 + unsigned long ofs, chipstart;
381 + chipnum = to >> cfi->chipshift;
382 + ofs = to - (chipnum << cfi->chipshift);
383 + chipstart = cfi->chips[chipnum].start;
385 + /* If it's not bus-aligned, do the first byte write */
386 + if (ofs & (CFIDEV_BUSWIDTH-1)) {
387 + unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
388 + int i = ofs - bus_ofs;
393 + map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
394 + while (len && i < CFIDEV_BUSWIDTH)
395 + tmp_buf[i++] = buf[n++], len--;
397 + if (cfi_buswidth_is_2()) {
398 + datum = *(__u16*)tmp_buf;
399 + } else if (cfi_buswidth_is_4()) {
400 + datum = *(__u32*)tmp_buf;
402 + return -EINVAL; /* should never happen, but be safe */
405 + ret = do_write_oneword(map, &cfi->chips[chipnum],
406 + bus_ofs, datum, 0);
414 + if (ofs >> cfi->chipshift) {
417 + if (chipnum == cfi->numchips)
422 + /* We are now aligned, write as much as possible */
423 + while(len >= CFIDEV_BUSWIDTH) {
426 + if (cfi_buswidth_is_1()) {
427 + datum = *(__u8*)buf;
428 + } else if (cfi_buswidth_is_2()) {
429 + datum = *(__u16*)buf;
430 + } else if (cfi_buswidth_is_4()) {
431 + datum = *(__u32*)buf;
435 + ret = do_write_oneword(map, &cfi->chips[chipnum],
436 + ofs, datum, cfi->fast_prog);
441 + ofs += CFIDEV_BUSWIDTH;
442 + buf += CFIDEV_BUSWIDTH;
443 + (*retlen) += CFIDEV_BUSWIDTH;
444 + len -= CFIDEV_BUSWIDTH;
446 + if (ofs >> cfi->chipshift) {
449 + if (chipnum == cfi->numchips)
451 + chipstart = cfi->chips[chipnum].start;
455 + if (len & (CFIDEV_BUSWIDTH-1)) {
460 + map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
462 + tmp_buf[i++] = buf[n++];
464 + if (cfi_buswidth_is_2()) {
465 + datum = *(__u16*)tmp_buf;
466 + } else if (cfi_buswidth_is_4()) {
467 + datum = *(__u32*)tmp_buf;
469 + return -EINVAL; /* should never happen, but be safe */
472 + ret = do_write_oneword(map, &cfi->chips[chipnum],
483 +static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
485 + unsigned int status;
486 + unsigned long timeo = jiffies + HZ;
487 + struct cfi_private *cfi = map->fldrv_priv;
488 + unsigned int rdy_mask;
489 + DECLARE_WAITQUEUE(wait, current);
492 + cfi_spin_lock(chip->mutex);
494 + if (chip->state != FL_READY){
495 + set_current_state(TASK_UNINTERRUPTIBLE);
496 + add_wait_queue(&chip->wq, &wait);
498 + cfi_spin_unlock(chip->mutex);
501 + remove_wait_queue(&chip->wq, &wait);
502 + timeo = jiffies + HZ;
507 + chip->state = FL_ERASING;
509 + adr += chip->start;
511 + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
512 + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
513 + cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
514 + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
515 + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
516 + cfi_write(map, CMD(0x30), adr);
518 + timeo = jiffies + (HZ*20);
520 + cfi_spin_unlock(chip->mutex);
521 + schedule_timeout(HZ);
522 + cfi_spin_lock(chip->mutex);
524 + rdy_mask = CMD(0x80);
526 + /* Once the state machine's known to be working I'll do that */
528 + while ( ( (status = cfi_read(map,adr)) & rdy_mask ) != rdy_mask ) {
531 + if (chip->state != FL_ERASING) {
532 + /* Someone's suspended the erase. Sleep */
533 + set_current_state(TASK_UNINTERRUPTIBLE);
534 + add_wait_queue(&chip->wq, &wait);
536 + cfi_spin_unlock(chip->mutex);
537 + printk("erase suspended. Sleeping\n");
540 + remove_wait_queue(&chip->wq, &wait);
541 + timeo = jiffies + (HZ*2);
542 + cfi_spin_lock(chip->mutex);
546 + /* OK Still waiting */
547 + if (time_after(jiffies, timeo)) {
548 + chip->state = FL_READY;
549 + cfi_spin_unlock(chip->mutex);
550 + printk("waiting for erase to complete timed out.");
555 + /* Latency issues. Drop the lock, wait a while and retry */
556 + cfi_spin_unlock(chip->mutex);
559 + if ( 0 && !(z % 100 ))
560 + printk("chip not ready yet after erase. looping\n");
564 + cfi_spin_lock(chip->mutex);
568 + /* Done and happy. */
570 + chip->state = FL_READY;
571 + wake_up(&chip->wq);
572 + cfi_spin_unlock(chip->mutex);
576 +static int cfi_sststd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
578 + struct map_info *map = mtd->priv;
579 + struct cfi_private *cfi = map->fldrv_priv;
580 + unsigned long adr, len;
581 + int chipnum, ret = 0;
583 + struct mtd_erase_region_info *regions = mtd->eraseregions;
585 + if (instr->addr > mtd->size)
588 + if ((instr->len + instr->addr) > mtd->size)
591 + /* Check that both start and end of the requested erase are
592 + * aligned with the erasesize at the appropriate addresses.
597 + /* Skip all erase regions which are ended before the start of
598 + the requested erase. Actually, to save on the calculations,
599 + we skip to the first erase region which starts after the
600 + start of the requested erase, and then go back one.
603 + while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
607 + /* OK, now i is pointing at the erase region in which this
608 + erase request starts. Check the start of the requested
609 + erase range is aligned with the erase size which is in
613 + if (instr->addr & (regions[i].erasesize-1))
616 + /* Remember the erase region we start on */
619 + /* Next, check that the end of the requested erase is aligned
620 + * with the erase region at that address.
623 + while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset)
626 + /* As before, drop back one to point at the region in which
627 + the address actually falls
631 + if ((instr->addr + instr->len) & (regions[i].erasesize-1))
634 + chipnum = instr->addr >> cfi->chipshift;
635 + adr = instr->addr - (chipnum << cfi->chipshift);
641 + ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
646 + adr += regions[i].erasesize;
647 + len -= regions[i].erasesize;
649 + if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
652 + if (adr >> cfi->chipshift) {
656 + if (chipnum >= cfi->numchips)
661 + instr->state = MTD_ERASE_DONE;
662 + if (instr->callback)
663 + instr->callback(instr);
668 +static int cfi_sststd_erase_onesize(struct mtd_info *mtd, struct erase_info *instr)
670 + struct map_info *map = mtd->priv;
671 + struct cfi_private *cfi = map->fldrv_priv;
672 + unsigned long adr, len;
673 + int chipnum, ret = 0;
675 + if (instr->addr & (mtd->erasesize - 1))
678 + if (instr->len & (mtd->erasesize -1))
681 + if ((instr->len + instr->addr) > mtd->size)
684 + chipnum = instr->addr >> cfi->chipshift;
685 + adr = instr->addr - (chipnum << cfi->chipshift);
689 + ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
694 + adr += mtd->erasesize;
695 + len -= mtd->erasesize;
697 + if (adr >> cfi->chipshift) {
701 + if (chipnum >= cfi->numchips)
706 + instr->state = MTD_ERASE_DONE;
707 + if (instr->callback)
708 + instr->callback(instr);
713 +static void cfi_sststd_sync (struct mtd_info *mtd)
715 + struct map_info *map = mtd->priv;
716 + struct cfi_private *cfi = map->fldrv_priv;
718 + struct flchip *chip;
720 + DECLARE_WAITQUEUE(wait, current);
722 + for (i=0; !ret && i<cfi->numchips; i++) {
723 + chip = &cfi->chips[i];
726 + cfi_spin_lock(chip->mutex);
728 + switch(chip->state) {
732 + case FL_JEDEC_QUERY:
733 + chip->oldstate = chip->state;
734 + chip->state = FL_SYNCING;
735 + /* No need to wake_up() on this state change -
736 + * as the whole point is that nobody can do anything
737 + * with the chip now anyway.
740 + cfi_spin_unlock(chip->mutex);
744 + /* Not an idle state */
745 + add_wait_queue(&chip->wq, &wait);
747 + cfi_spin_unlock(chip->mutex);
751 + remove_wait_queue(&chip->wq, &wait);
757 + /* Unlock the chips again */
759 + for (i--; i >=0; i--) {
760 + chip = &cfi->chips[i];
762 + cfi_spin_lock(chip->mutex);
764 + if (chip->state == FL_SYNCING) {
765 + chip->state = chip->oldstate;
766 + wake_up(&chip->wq);
768 + cfi_spin_unlock(chip->mutex);
773 +static int cfi_sststd_suspend(struct mtd_info *mtd)
775 + struct map_info *map = mtd->priv;
776 + struct cfi_private *cfi = map->fldrv_priv;
778 + struct flchip *chip;
780 +//printk("suspend\n");
782 + for (i=0; !ret && i<cfi->numchips; i++) {
783 + chip = &cfi->chips[i];
785 + cfi_spin_lock(chip->mutex);
787 + switch(chip->state) {
791 + case FL_JEDEC_QUERY:
792 + chip->oldstate = chip->state;
793 + chip->state = FL_PM_SUSPENDED;
794 + /* No need to wake_up() on this state change -
795 + * as the whole point is that nobody can do anything
796 + * with the chip now anyway.
798 + case FL_PM_SUSPENDED:
805 + cfi_spin_unlock(chip->mutex);
808 + /* Unlock the chips again */
811 + for (i--; i >=0; i--) {
812 + chip = &cfi->chips[i];
814 + cfi_spin_lock(chip->mutex);
816 + if (chip->state == FL_PM_SUSPENDED) {
817 + chip->state = chip->oldstate;
818 + wake_up(&chip->wq);
820 + cfi_spin_unlock(chip->mutex);
827 +static void cfi_sststd_resume(struct mtd_info *mtd)
829 + struct map_info *map = mtd->priv;
830 + struct cfi_private *cfi = map->fldrv_priv;
832 + struct flchip *chip;
833 +//printk("resume\n");
835 + for (i=0; i<cfi->numchips; i++) {
837 + chip = &cfi->chips[i];
839 + cfi_spin_lock(chip->mutex);
841 + if (chip->state == FL_PM_SUSPENDED) {
842 + chip->state = FL_READY;
843 + cfi_write(map, CMD(0xF0), chip->start);
844 + wake_up(&chip->wq);
847 + printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n");
849 + cfi_spin_unlock(chip->mutex);
853 +static void cfi_sststd_destroy(struct mtd_info *mtd)
855 + struct map_info *map = mtd->priv;
856 + struct cfi_private *cfi = map->fldrv_priv;
857 + kfree(cfi->cmdset_priv);
861 +#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
862 +#define cfi_sststd_init init_module
863 +#define cfi_sststd_exit cleanup_module
866 +static char im_name[]="cfi_cmdset_0701";
868 +mod_init_t cfi_sststd_init(void)
870 + inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0701);
874 +mod_exit_t cfi_sststd_exit(void)
876 + inter_module_unregister(im_name);
879 +module_init(cfi_sststd_init);
880 +module_exit(cfi_sststd_exit);
882 diff -Nur linux-2.4.30/drivers/mtd/chips/cfi_probe.c linux-2.4.30.openwrt/drivers/mtd/chips/cfi_probe.c
883 --- linux-2.4.30/drivers/mtd/chips/cfi_probe.c 2003-06-13 16:51:34.000000000 +0200
884 +++ linux-2.4.30.openwrt/drivers/mtd/chips/cfi_probe.c 2005-06-28 11:26:26.000000000 +0200
886 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
887 cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
889 - if (!qry_present(map,base,cfi))
891 + if (!qry_present(map,base,cfi)) {
892 + /* rather broken SST cfi probe (requires SST unlock) */
893 + cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
894 + cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
895 + cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
896 + cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
897 + if (!qry_present(map,base,cfi))
901 if (!cfi->numchips) {
902 /* This is the first time we're called. Set up the CFI
903 diff -Nur linux-2.4.30/drivers/mtd/chips/gen_probe.c linux-2.4.30.openwrt/drivers/mtd/chips/gen_probe.c
904 --- linux-2.4.30/drivers/mtd/chips/gen_probe.c 2003-08-25 13:44:42.000000000 +0200
905 +++ linux-2.4.30.openwrt/drivers/mtd/chips/gen_probe.c 2005-06-28 11:29:23.000000000 +0200
906 @@ -328,13 +328,18 @@
907 return cfi_cmdset_0001(map, primary);
909 #ifdef CONFIG_MTD_CFI_AMDSTD
912 return cfi_cmdset_0002(map, primary);
914 #ifdef CONFIG_MTD_CFI_STAA
917 return cfi_cmdset_0020(map, primary);
919 +#ifdef CONFIG_MTD_CFI_SSTSTD
921 + return cfi_cmdset_0701(map, primary);
925 return cfi_cmdset_unknown(map, primary);