1 Index: linux-2.4.35.4/drivers/mtd/chips/Config.in
2 ===================================================================
3 --- linux-2.4.35.4.orig/drivers/mtd/chips/Config.in 2007-12-15 05:19:42.454840402 +0100
4 +++ linux-2.4.35.4/drivers/mtd/chips/Config.in 2007-12-15 05:19:50.035272385 +0100
6 dep_tristate ' Support for Intel/Sharp flash chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_GEN_PROBE
7 dep_tristate ' Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_GEN_PROBE
8 dep_tristate ' Support for ST (Advanced Architecture) flash chips' CONFIG_MTD_CFI_STAA $CONFIG_MTD_GEN_PROBE
9 +dep_tristate ' Support for SST flash chips' CONFIG_MTD_CFI_SSTSTD $CONFIG_MTD_GEN_PROBE
11 dep_tristate ' Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
12 dep_tristate ' Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD
13 Index: linux-2.4.35.4/drivers/mtd/chips/Makefile
14 ===================================================================
15 --- linux-2.4.35.4.orig/drivers/mtd/chips/Makefile 2007-12-15 05:19:42.462840857 +0100
16 +++ linux-2.4.35.4/drivers/mtd/chips/Makefile 2007-12-15 05:19:50.039272613 +0100
18 obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
19 obj-$(CONFIG_MTD_CFI) += cfi_probe.o
20 obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
21 +obj-$(CONFIG_MTD_CFI_SSTSTD) += cfi_cmdset_0701.o
22 obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o
23 obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o
24 obj-$(CONFIG_MTD_GEN_PROBE) += gen_probe.o
25 Index: linux-2.4.35.4/drivers/mtd/chips/cfi_cmdset_0701.c
26 ===================================================================
27 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
28 +++ linux-2.4.35.4/drivers/mtd/chips/cfi_cmdset_0701.c 2007-12-15 05:19:50.047273069 +0100
31 + * Common Flash Interface support:
32 + * SST Standard Vendor Command Set (ID 0x0701)
34 + * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
36 + * 2_by_8 routines added by Simon Munton
40 + * $Id: cfi_cmdset_0701.c,v 1.1 2005/03/16 13:50:00 wbx Exp $
44 +#include <linux/module.h>
45 +#include <linux/types.h>
46 +#include <linux/kernel.h>
47 +#include <linux/sched.h>
49 +#include <asm/byteorder.h>
51 +#include <linux/errno.h>
52 +#include <linux/slab.h>
53 +#include <linux/delay.h>
54 +#include <linux/interrupt.h>
55 +#include <linux/mtd/map.h>
56 +#include <linux/mtd/cfi.h>
58 +static int cfi_sststd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
59 +static int cfi_sststd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
60 +static int cfi_sststd_erase_onesize(struct mtd_info *, struct erase_info *);
61 +static int cfi_sststd_erase_varsize(struct mtd_info *, struct erase_info *);
62 +static void cfi_sststd_sync (struct mtd_info *);
63 +static int cfi_sststd_suspend (struct mtd_info *);
64 +static void cfi_sststd_resume (struct mtd_info *);
66 +static void cfi_sststd_destroy(struct mtd_info *);
68 +struct mtd_info *cfi_cmdset_0701(struct map_info *, int);
69 +static struct mtd_info *cfi_sststd_setup (struct map_info *);
72 +static struct mtd_chip_driver cfi_sststd_chipdrv = {
73 + probe: NULL, /* Not usable directly */
74 + destroy: cfi_sststd_destroy,
75 + name: "cfi_cmdset_0701",
79 +struct mtd_info *cfi_cmdset_0701(struct map_info *map, int primary)
81 + struct cfi_private *cfi = map->fldrv_priv;
82 + int ofs_factor = cfi->interleave * cfi->device_type;
85 + __u32 base = cfi->chips[0].start;
87 + if (cfi->cfi_mode==1){
88 + __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
90 + cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
91 + cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
92 + cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
94 + major = cfi_read_query(map, base + (adr+3)*ofs_factor);
95 + minor = cfi_read_query(map, base + (adr+4)*ofs_factor);
97 + printk(" SST Query Table v%c.%c at 0x%4.4X\n",
99 + cfi_send_gen_cmd(0xf0, 0x5555, base, map, cfi, cfi->device_type, NULL);
101 + cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
102 + cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
103 + cfi_send_gen_cmd(0x90, 0x5555, base, map, cfi, cfi->device_type, NULL);
104 + cfi->mfr = cfi_read_query(map, base);
105 + cfi->id = cfi_read_query(map, base + ofs_factor);
107 + cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
108 + cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
109 + cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
111 + switch (cfi->device_type) {
112 + case CFI_DEVICETYPE_X16:
113 + cfi->addr_unlock1 = 0x5555;
114 + cfi->addr_unlock2 = 0x2AAA;
117 + printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0701 device type %d\n", cfi->device_type);
122 + for (i=0; i< cfi->numchips; i++) {
123 + cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
124 + cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
125 + cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
128 + map->fldrv = &cfi_sststd_chipdrv;
131 + cfi_send_gen_cmd(0xf0, 0x5555, base, map, cfi, cfi->device_type, NULL);
132 + return cfi_sststd_setup(map);
135 +static struct mtd_info *cfi_sststd_setup(struct map_info *map)
137 + struct cfi_private *cfi = map->fldrv_priv;
138 + struct mtd_info *mtd;
139 + unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
141 + mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
142 + printk("number of %s chips: %d\n", (cfi->cfi_mode)?"JEDEC":"CFI",cfi->numchips);
145 + printk("Failed to allocate memory for MTD device\n");
146 + kfree(cfi->cmdset_priv);
150 + memset(mtd, 0, sizeof(*mtd));
152 + mtd->type = MTD_NORFLASH;
153 + /* Also select the correct geometry setup too */
154 + mtd->size = devsize * cfi->numchips;
156 + if (cfi->cfiq->NumEraseRegions == 1) {
157 + /* No need to muck about with multiple erase sizes */
158 + mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave;
160 + unsigned long offset = 0;
163 + mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
164 + mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL);
165 + if (!mtd->eraseregions) {
166 + printk("Failed to allocate memory for MTD erase region info\n");
167 + kfree(cfi->cmdset_priv);
171 + for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
172 + unsigned long ernum, ersize;
173 + ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
174 + ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
176 + if (mtd->erasesize < ersize) {
177 + mtd->erasesize = ersize;
179 + for (j=0; j<cfi->numchips; j++) {
180 + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
181 + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
182 + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
184 + offset += (ersize * ernum);
188 + for (i=0; i<mtd->numeraseregions;i++){
189 + printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
190 + i,mtd->eraseregions[i].offset,
191 + mtd->eraseregions[i].erasesize,
192 + mtd->eraseregions[i].numblocks);
196 + switch (CFIDEV_BUSWIDTH)
201 + if (mtd->numeraseregions > 1)
202 + mtd->erase = cfi_sststd_erase_varsize;
204 + mtd->erase = cfi_sststd_erase_onesize;
205 + mtd->read = cfi_sststd_read;
206 + mtd->write = cfi_sststd_write;
210 + printk("Unsupported buswidth\n");
212 + kfree(cfi->cmdset_priv);
216 + mtd->sync = cfi_sststd_sync;
217 + mtd->suspend = cfi_sststd_suspend;
218 + mtd->resume = cfi_sststd_resume;
219 + mtd->flags = MTD_CAP_NORFLASH;
220 + map->fldrv = &cfi_sststd_chipdrv;
221 + mtd->name = map->name;
226 +static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
228 + DECLARE_WAITQUEUE(wait, current);
229 + unsigned long timeo = jiffies + HZ;
232 + cfi_spin_lock(chip->mutex);
234 + if (chip->state != FL_READY){
235 + printk("Waiting for chip to read, status = %d\n", chip->state);
236 + set_current_state(TASK_UNINTERRUPTIBLE);
237 + add_wait_queue(&chip->wq, &wait);
239 + cfi_spin_unlock(chip->mutex);
242 + remove_wait_queue(&chip->wq, &wait);
243 + timeo = jiffies + HZ;
248 + adr += chip->start;
250 + chip->state = FL_READY;
252 + map->copy_from(map, buf, adr, len);
254 + wake_up(&chip->wq);
255 + cfi_spin_unlock(chip->mutex);
260 +static int cfi_sststd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
262 + struct map_info *map = mtd->priv;
263 + struct cfi_private *cfi = map->fldrv_priv;
268 + /* ofs: offset within the first chip that the first read should start */
270 + chipnum = (from >> cfi->chipshift);
271 + ofs = from - (chipnum << cfi->chipshift);
277 + unsigned long thislen;
279 + if (chipnum >= cfi->numchips)
282 + if ((len + ofs -1) >> cfi->chipshift)
283 + thislen = (1<<cfi->chipshift) - ofs;
287 + ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
291 + *retlen += thislen;
301 +static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast)
303 + unsigned long timeo = jiffies + HZ;
304 + unsigned int Last[4];
305 + unsigned long Count = 0;
306 + struct cfi_private *cfi = map->fldrv_priv;
307 + DECLARE_WAITQUEUE(wait, current);
311 + cfi_spin_lock(chip->mutex);
313 + if (chip->state != FL_READY){
314 + printk("Waiting for chip to write, status = %d\n", chip->state);
315 + set_current_state(TASK_UNINTERRUPTIBLE);
316 + add_wait_queue(&chip->wq, &wait);
318 + cfi_spin_unlock(chip->mutex);
321 + remove_wait_queue(&chip->wq, &wait);
322 + printk("Wake up to write:\n");
323 + timeo = jiffies + HZ;
328 + chip->state = FL_WRITING;
330 + adr += chip->start;
332 + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
333 + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
334 + cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
336 + cfi_write(map, datum, adr);
338 + cfi_spin_unlock(chip->mutex);
339 + cfi_udelay(chip->word_write_time);
340 + cfi_spin_lock(chip->mutex);
342 + Last[0] = cfi_read(map, adr);
343 + // printk("Last[0] is %x\n", Last[0]);
344 + Last[1] = cfi_read(map, adr);
345 + // printk("Last[1] is %x\n", Last[1]);
346 + Last[2] = cfi_read(map, adr);
347 + // printk("Last[2] is %x\n", Last[2]);
349 + for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && Count < 10000; Count++){
350 + cfi_spin_unlock(chip->mutex);
352 + cfi_spin_lock(chip->mutex);
354 + Last[Count % 4] = cfi_read(map, adr);
355 + // printk("Last[%d%%4] is %x\n", Count, Last[Count%4]);
358 + if (Last[(Count - 1) % 4] != datum){
359 + printk("Last[%ld] is %x, datum is %x\n",(Count - 1) % 4,Last[(Count - 1) % 4],datum);
360 + cfi_send_gen_cmd(0xF0, 0, chip->start, map, cfi, cfi->device_type, NULL);
365 + chip->state = FL_READY;
366 + wake_up(&chip->wq);
367 + cfi_spin_unlock(chip->mutex);
372 +static int cfi_sststd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
374 + struct map_info *map = mtd->priv;
375 + struct cfi_private *cfi = map->fldrv_priv;
378 + unsigned long ofs, chipstart;
384 + chipnum = to >> cfi->chipshift;
385 + ofs = to - (chipnum << cfi->chipshift);
386 + chipstart = cfi->chips[chipnum].start;
388 + /* If it's not bus-aligned, do the first byte write */
389 + if (ofs & (CFIDEV_BUSWIDTH-1)) {
390 + unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
391 + int i = ofs - bus_ofs;
396 + map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
397 + while (len && i < CFIDEV_BUSWIDTH)
398 + tmp_buf[i++] = buf[n++], len--;
400 + if (cfi_buswidth_is_2()) {
401 + datum = *(__u16*)tmp_buf;
402 + } else if (cfi_buswidth_is_4()) {
403 + datum = *(__u32*)tmp_buf;
405 + return -EINVAL; /* should never happen, but be safe */
408 + ret = do_write_oneword(map, &cfi->chips[chipnum],
409 + bus_ofs, datum, 0);
417 + if (ofs >> cfi->chipshift) {
420 + if (chipnum == cfi->numchips)
425 + /* We are now aligned, write as much as possible */
426 + while(len >= CFIDEV_BUSWIDTH) {
429 + if (cfi_buswidth_is_1()) {
430 + datum = *(__u8*)buf;
431 + } else if (cfi_buswidth_is_2()) {
432 + datum = *(__u16*)buf;
433 + } else if (cfi_buswidth_is_4()) {
434 + datum = *(__u32*)buf;
438 + ret = do_write_oneword(map, &cfi->chips[chipnum],
439 + ofs, datum, cfi->fast_prog);
444 + ofs += CFIDEV_BUSWIDTH;
445 + buf += CFIDEV_BUSWIDTH;
446 + (*retlen) += CFIDEV_BUSWIDTH;
447 + len -= CFIDEV_BUSWIDTH;
449 + if (ofs >> cfi->chipshift) {
452 + if (chipnum == cfi->numchips)
454 + chipstart = cfi->chips[chipnum].start;
458 + if (len & (CFIDEV_BUSWIDTH-1)) {
463 + map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
465 + tmp_buf[i++] = buf[n++];
467 + if (cfi_buswidth_is_2()) {
468 + datum = *(__u16*)tmp_buf;
469 + } else if (cfi_buswidth_is_4()) {
470 + datum = *(__u32*)tmp_buf;
472 + return -EINVAL; /* should never happen, but be safe */
475 + ret = do_write_oneword(map, &cfi->chips[chipnum],
486 +static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
488 + unsigned int status;
489 + unsigned long timeo = jiffies + HZ;
490 + struct cfi_private *cfi = map->fldrv_priv;
491 + unsigned int rdy_mask;
492 + DECLARE_WAITQUEUE(wait, current);
495 + cfi_spin_lock(chip->mutex);
497 + if (chip->state != FL_READY){
498 + set_current_state(TASK_UNINTERRUPTIBLE);
499 + add_wait_queue(&chip->wq, &wait);
501 + cfi_spin_unlock(chip->mutex);
504 + remove_wait_queue(&chip->wq, &wait);
505 + timeo = jiffies + HZ;
510 + chip->state = FL_ERASING;
512 + adr += chip->start;
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_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
517 + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
518 + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
519 + cfi_write(map, CMD(0x30), adr);
521 + timeo = jiffies + (HZ*20);
523 + cfi_spin_unlock(chip->mutex);
524 + schedule_timeout(HZ);
525 + cfi_spin_lock(chip->mutex);
527 + rdy_mask = CMD(0x80);
529 + /* Once the state machine's known to be working I'll do that */
531 + while ( ( (status = cfi_read(map,adr)) & rdy_mask ) != rdy_mask ) {
534 + if (chip->state != FL_ERASING) {
535 + /* Someone's suspended the erase. Sleep */
536 + set_current_state(TASK_UNINTERRUPTIBLE);
537 + add_wait_queue(&chip->wq, &wait);
539 + cfi_spin_unlock(chip->mutex);
540 + printk("erase suspended. Sleeping\n");
543 + remove_wait_queue(&chip->wq, &wait);
544 + timeo = jiffies + (HZ*2);
545 + cfi_spin_lock(chip->mutex);
549 + /* OK Still waiting */
550 + if (time_after(jiffies, timeo)) {
551 + chip->state = FL_READY;
552 + cfi_spin_unlock(chip->mutex);
553 + printk("waiting for erase to complete timed out.");
558 + /* Latency issues. Drop the lock, wait a while and retry */
559 + cfi_spin_unlock(chip->mutex);
562 + if ( 0 && !(z % 100 ))
563 + printk("chip not ready yet after erase. looping\n");
567 + cfi_spin_lock(chip->mutex);
571 + /* Done and happy. */
573 + chip->state = FL_READY;
574 + wake_up(&chip->wq);
575 + cfi_spin_unlock(chip->mutex);
579 +static int cfi_sststd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
581 + struct map_info *map = mtd->priv;
582 + struct cfi_private *cfi = map->fldrv_priv;
583 + unsigned long adr, len;
584 + int chipnum, ret = 0;
586 + struct mtd_erase_region_info *regions = mtd->eraseregions;
588 + if (instr->addr > mtd->size)
591 + if ((instr->len + instr->addr) > mtd->size)
594 + /* Check that both start and end of the requested erase are
595 + * aligned with the erasesize at the appropriate addresses.
600 + /* Skip all erase regions which are ended before the start of
601 + the requested erase. Actually, to save on the calculations,
602 + we skip to the first erase region which starts after the
603 + start of the requested erase, and then go back one.
606 + while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
610 + /* OK, now i is pointing at the erase region in which this
611 + erase request starts. Check the start of the requested
612 + erase range is aligned with the erase size which is in
616 + if (instr->addr & (regions[i].erasesize-1))
619 + /* Remember the erase region we start on */
622 + /* Next, check that the end of the requested erase is aligned
623 + * with the erase region at that address.
626 + while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset)
629 + /* As before, drop back one to point at the region in which
630 + the address actually falls
634 + if ((instr->addr + instr->len) & (regions[i].erasesize-1))
637 + chipnum = instr->addr >> cfi->chipshift;
638 + adr = instr->addr - (chipnum << cfi->chipshift);
644 + ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
649 + adr += regions[i].erasesize;
650 + len -= regions[i].erasesize;
652 + if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
655 + if (adr >> cfi->chipshift) {
659 + if (chipnum >= cfi->numchips)
664 + instr->state = MTD_ERASE_DONE;
665 + if (instr->callback)
666 + instr->callback(instr);
671 +static int cfi_sststd_erase_onesize(struct mtd_info *mtd, struct erase_info *instr)
673 + struct map_info *map = mtd->priv;
674 + struct cfi_private *cfi = map->fldrv_priv;
675 + unsigned long adr, len;
676 + int chipnum, ret = 0;
678 + if (instr->addr & (mtd->erasesize - 1))
681 + if (instr->len & (mtd->erasesize -1))
684 + if ((instr->len + instr->addr) > mtd->size)
687 + chipnum = instr->addr >> cfi->chipshift;
688 + adr = instr->addr - (chipnum << cfi->chipshift);
692 + ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
697 + adr += mtd->erasesize;
698 + len -= mtd->erasesize;
700 + if (adr >> cfi->chipshift) {
704 + if (chipnum >= cfi->numchips)
709 + instr->state = MTD_ERASE_DONE;
710 + if (instr->callback)
711 + instr->callback(instr);
716 +static void cfi_sststd_sync (struct mtd_info *mtd)
718 + struct map_info *map = mtd->priv;
719 + struct cfi_private *cfi = map->fldrv_priv;
721 + struct flchip *chip;
723 + DECLARE_WAITQUEUE(wait, current);
725 + for (i=0; !ret && i<cfi->numchips; i++) {
726 + chip = &cfi->chips[i];
729 + cfi_spin_lock(chip->mutex);
731 + switch(chip->state) {
735 + case FL_JEDEC_QUERY:
736 + chip->oldstate = chip->state;
737 + chip->state = FL_SYNCING;
738 + /* No need to wake_up() on this state change -
739 + * as the whole point is that nobody can do anything
740 + * with the chip now anyway.
743 + cfi_spin_unlock(chip->mutex);
747 + /* Not an idle state */
748 + add_wait_queue(&chip->wq, &wait);
750 + cfi_spin_unlock(chip->mutex);
754 + remove_wait_queue(&chip->wq, &wait);
760 + /* Unlock the chips again */
762 + for (i--; i >=0; i--) {
763 + chip = &cfi->chips[i];
765 + cfi_spin_lock(chip->mutex);
767 + if (chip->state == FL_SYNCING) {
768 + chip->state = chip->oldstate;
769 + wake_up(&chip->wq);
771 + cfi_spin_unlock(chip->mutex);
776 +static int cfi_sststd_suspend(struct mtd_info *mtd)
778 + struct map_info *map = mtd->priv;
779 + struct cfi_private *cfi = map->fldrv_priv;
781 + struct flchip *chip;
783 +//printk("suspend\n");
785 + for (i=0; !ret && i<cfi->numchips; i++) {
786 + chip = &cfi->chips[i];
788 + cfi_spin_lock(chip->mutex);
790 + switch(chip->state) {
794 + case FL_JEDEC_QUERY:
795 + chip->oldstate = chip->state;
796 + chip->state = FL_PM_SUSPENDED;
797 + /* No need to wake_up() on this state change -
798 + * as the whole point is that nobody can do anything
799 + * with the chip now anyway.
801 + case FL_PM_SUSPENDED:
808 + cfi_spin_unlock(chip->mutex);
811 + /* Unlock the chips again */
814 + for (i--; i >=0; i--) {
815 + chip = &cfi->chips[i];
817 + cfi_spin_lock(chip->mutex);
819 + if (chip->state == FL_PM_SUSPENDED) {
820 + chip->state = chip->oldstate;
821 + wake_up(&chip->wq);
823 + cfi_spin_unlock(chip->mutex);
830 +static void cfi_sststd_resume(struct mtd_info *mtd)
832 + struct map_info *map = mtd->priv;
833 + struct cfi_private *cfi = map->fldrv_priv;
835 + struct flchip *chip;
836 +//printk("resume\n");
838 + for (i=0; i<cfi->numchips; i++) {
840 + chip = &cfi->chips[i];
842 + cfi_spin_lock(chip->mutex);
844 + if (chip->state == FL_PM_SUSPENDED) {
845 + chip->state = FL_READY;
846 + cfi_write(map, CMD(0xF0), chip->start);
847 + wake_up(&chip->wq);
850 + printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n");
852 + cfi_spin_unlock(chip->mutex);
856 +static void cfi_sststd_destroy(struct mtd_info *mtd)
858 + struct map_info *map = mtd->priv;
859 + struct cfi_private *cfi = map->fldrv_priv;
860 + kfree(cfi->cmdset_priv);
864 +#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
865 +#define cfi_sststd_init init_module
866 +#define cfi_sststd_exit cleanup_module
869 +static char im_name[]="cfi_cmdset_0701";
871 +mod_init_t cfi_sststd_init(void)
873 + inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0701);
877 +mod_exit_t cfi_sststd_exit(void)
879 + inter_module_unregister(im_name);
882 +module_init(cfi_sststd_init);
883 +module_exit(cfi_sststd_exit);
885 Index: linux-2.4.35.4/drivers/mtd/chips/cfi_probe.c
886 ===================================================================
887 --- linux-2.4.35.4.orig/drivers/mtd/chips/cfi_probe.c 2007-12-15 05:19:42.474841541 +0100
888 +++ linux-2.4.35.4/drivers/mtd/chips/cfi_probe.c 2007-12-15 05:19:50.051273298 +0100
890 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
891 cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
893 - if (!qry_present(map,base,cfi))
895 + if (!qry_present(map,base,cfi)) {
896 + /* rather broken SST cfi probe (requires SST unlock) */
897 + cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
898 + cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
899 + cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
900 + cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
901 + if (!qry_present(map,base,cfi))
905 if (!cfi->numchips) {
906 /* This is the first time we're called. Set up the CFI
907 Index: linux-2.4.35.4/drivers/mtd/chips/gen_probe.c
908 ===================================================================
909 --- linux-2.4.35.4.orig/drivers/mtd/chips/gen_probe.c 2007-12-15 05:19:42.482841997 +0100
910 +++ linux-2.4.35.4/drivers/mtd/chips/gen_probe.c 2007-12-15 05:19:50.055273524 +0100
911 @@ -328,13 +328,18 @@
912 return cfi_cmdset_0001(map, primary);
914 #ifdef CONFIG_MTD_CFI_AMDSTD
917 return cfi_cmdset_0002(map, primary);
919 #ifdef CONFIG_MTD_CFI_STAA
922 return cfi_cmdset_0020(map, primary);
924 +#ifdef CONFIG_MTD_CFI_SSTSTD
926 + return cfi_cmdset_0701(map, primary);
930 return cfi_cmdset_unknown(map, primary);