Lines Matching +full:cfi +full:- +full:flash

2  * Common Flash Interface support:
9 * - completely revamped method functions so they are aware and
10 * independent of the flash geometry (buswidth, interleave, etc.)
11 * - scalability vs code size is completely set at compile-time
12 * (see include/linux/mtd/cfi.h for selection)
13 * - optimized write buffer method
15 * - reworked lock/unlock/erase support for var size flash
17 * - auto unlock sectors on resume for auto locking flash on power up
36 #include <linux/mtd/cfi.h>
123 printk(" Extended Query version %c.%c\n", extp->MajorVersion, extp->MinorVersion); in cfi_tell_features()
124 printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); in cfi_tell_features()
125 printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); in cfi_tell_features()
126 printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); in cfi_tell_features()
127 printk(" - Suspend Program: %s\n", extp->FeatureSupport&4?"supported":"unsupported"); in cfi_tell_features()
128 printk(" - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported"); in cfi_tell_features()
129 printk(" - Queued Erase: %s\n", extp->FeatureSupport&16?"supported":"unsupported"); in cfi_tell_features()
130 printk(" - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported"); in cfi_tell_features()
131 printk(" - Protection Bits: %s\n", extp->FeatureSupport&64?"supported":"unsupported"); in cfi_tell_features()
132 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); in cfi_tell_features()
133 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); in cfi_tell_features()
134 printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); in cfi_tell_features()
135 …printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported"… in cfi_tell_features()
137 if (extp->FeatureSupport & (1<<i)) in cfi_tell_features()
138 printk(" - Unknown Bit %X: supported\n", i); in cfi_tell_features()
141 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); in cfi_tell_features()
142 …printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsuppor… in cfi_tell_features()
144 if (extp->SuspendCmdSupport & (1<<i)) in cfi_tell_features()
145 printk(" - Unknown Bit %X: supported\n", i); in cfi_tell_features()
148 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); in cfi_tell_features()
149 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); in cfi_tell_features()
150 printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); in cfi_tell_features()
152 if (extp->BlkStatusRegMask & (1<<i)) in cfi_tell_features()
153 printk(" - Unknown Bit %X Active: yes\n",i); in cfi_tell_features()
155 printk(" - EFA Lock Bit: %s\n", extp->BlkStatusRegMask&16?"yes":"no"); in cfi_tell_features()
156 printk(" - EFA Lock-Down Bit: %s\n", extp->BlkStatusRegMask&32?"yes":"no"); in cfi_tell_features()
158 if (extp->BlkStatusRegMask & (1<<i)) in cfi_tell_features()
159 printk(" - Unknown Bit %X Active: yes\n",i); in cfi_tell_features()
163 extp->VccOptimal >> 4, extp->VccOptimal & 0xf); in cfi_tell_features()
164 if (extp->VppOptimal) in cfi_tell_features()
166 extp->VppOptimal >> 4, extp->VppOptimal & 0xf); in cfi_tell_features()
173 struct map_info *map = mtd->priv; in fixup_convert_atmel_pri()
174 struct cfi_private *cfi = map->fldrv_priv; in fixup_convert_atmel_pri() local
175 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in fixup_convert_atmel_pri()
180 extp->FeatureSupport = cpu_to_le32(extp->FeatureSupport); in fixup_convert_atmel_pri()
181 extp->BlkStatusRegMask = cpu_to_le16(extp->BlkStatusRegMask); in fixup_convert_atmel_pri()
182 extp->ProtRegAddr = cpu_to_le16(extp->ProtRegAddr); in fixup_convert_atmel_pri()
185 memset((char *)extp + 5, 0, sizeof(*extp) - 5); in fixup_convert_atmel_pri()
204 extp->FeatureSupport = features; in fixup_convert_atmel_pri()
207 cfi->cfiq->BufWriteTimeoutTyp = 0; in fixup_convert_atmel_pri()
208 cfi->cfiq->BufWriteTimeoutMax = 0; in fixup_convert_atmel_pri()
213 struct map_info *map = mtd->priv; in fixup_at49bv640dx_lock()
214 struct cfi_private *cfi = map->fldrv_priv; in fixup_at49bv640dx_lock() local
215 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; in fixup_at49bv640dx_lock()
217 cfip->FeatureSupport |= (1 << 5); in fixup_at49bv640dx_lock()
218 mtd->flags |= MTD_POWERUP_LOCK; in fixup_at49bv640dx_lock()
222 /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
225 struct map_info *map = mtd->priv; in fixup_intel_strataflash()
226 struct cfi_private *cfi = map->fldrv_priv; in fixup_intel_strataflash() local
227 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in fixup_intel_strataflash()
231 extp->SuspendCmdSupport &= ~1; in fixup_intel_strataflash()
238 struct map_info *map = mtd->priv; in fixup_no_write_suspend()
239 struct cfi_private *cfi = map->fldrv_priv; in fixup_no_write_suspend() local
240 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; in fixup_no_write_suspend()
242 if (cfip && (cfip->FeatureSupport&4)) { in fixup_no_write_suspend()
243 cfip->FeatureSupport &= ~4; in fixup_no_write_suspend()
251 struct map_info *map = mtd->priv; in fixup_st_m28w320ct()
252 struct cfi_private *cfi = map->fldrv_priv; in fixup_st_m28w320ct() local
254 cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ in fixup_st_m28w320ct()
255 cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ in fixup_st_m28w320ct()
260 struct map_info *map = mtd->priv; in fixup_st_m28w320cb()
261 struct cfi_private *cfi = map->fldrv_priv; in fixup_st_m28w320cb() local
264 cfi->cfiq->EraseRegionInfo[1] = in fixup_st_m28w320cb()
265 (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; in fixup_st_m28w320cb()
268 static int is_LH28F640BF(struct cfi_private *cfi) in is_LH28F640BF() argument
271 if (cfi->mfr == CFI_MFR_SHARP && ( in is_LH28F640BF()
272 cfi->id == LH28F640BFHE_PTTL90 || cfi->id == LH28F640BFHE_PBTL90 || in is_LH28F640BF()
273 cfi->id == LH28F640BFHE_PTTL70A || cfi->id == LH28F640BFHE_PBTL70A)) in is_LH28F640BF()
280 struct map_info *map = mtd->priv; in fixup_LH28F640BF()
281 struct cfi_private *cfi = map->fldrv_priv; in fixup_LH28F640BF() local
282 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in fixup_LH28F640BF()
285 * to a single partition (PCR = 0x000): PCR is embedded into A0-A15. */ in fixup_LH28F640BF()
286 if (is_LH28F640BF(cfi)) { in fixup_LH28F640BF()
294 extp->FeatureSupport &= ~512; in fixup_LH28F640BF()
300 struct map_info *map = mtd->priv; in fixup_use_point()
301 if (!mtd->_point && map_is_linear(map)) { in fixup_use_point()
302 mtd->_point = cfi_intelext_point; in fixup_use_point()
303 mtd->_unpoint = cfi_intelext_unpoint; in fixup_use_point()
309 struct map_info *map = mtd->priv; in fixup_use_write_buffers()
310 struct cfi_private *cfi = map->fldrv_priv; in fixup_use_write_buffers() local
311 if (cfi->cfiq->BufWriteTimeoutTyp) { in fixup_use_write_buffers()
313 mtd->_write = cfi_intelext_write_buffers; in fixup_use_write_buffers()
314 mtd->_writev = cfi_intelext_writev; in fixup_use_write_buffers()
319 * Some chips power-up with all sectors locked by default.
323 struct map_info *map = mtd->priv; in fixup_unlock_powerup_lock()
324 struct cfi_private *cfi = map->fldrv_priv; in fixup_unlock_powerup_lock() local
325 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; in fixup_unlock_powerup_lock()
327 if (cfip->FeatureSupport&32) { in fixup_unlock_powerup_lock()
328 printk(KERN_INFO "Using auto-unlock on power-up/resume\n" ); in fixup_unlock_powerup_lock()
329 mtd->flags |= MTD_POWERUP_LOCK; in fixup_unlock_powerup_lock()
363 /* The CFI vendor ids and the JEDEC vendor IDs appear
372 static void cfi_fixup_major_minor(struct cfi_private *cfi, in cfi_fixup_major_minor() argument
375 if (cfi->mfr == CFI_MFR_INTEL && in cfi_fixup_major_minor()
376 cfi->id == PF38F4476 && extp->MinorVersion == '3') in cfi_fixup_major_minor()
377 extp->MinorVersion = '1'; in cfi_fixup_major_minor()
380 static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip) in cfi_is_micron_28F00AP30() argument
386 if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30) in cfi_is_micron_28F00AP30()
394 struct cfi_private *cfi = map->fldrv_priv; in read_pri_intelext() local
404 cfi_fixup_major_minor(cfi, extp); in read_pri_intelext()
406 if (extp->MajorVersion != '1' || in read_pri_intelext()
407 (extp->MinorVersion < '0' || extp->MinorVersion > '5')) { in read_pri_intelext()
409 "version %c.%c.\n", extp->MajorVersion, in read_pri_intelext()
410 extp->MinorVersion); in read_pri_intelext()
416 extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport); in read_pri_intelext()
417 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); in read_pri_intelext()
418 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); in read_pri_intelext()
420 if (extp->MinorVersion >= '0') { in read_pri_intelext()
424 if (extp->NumProtectionFields) in read_pri_intelext()
425 extra_size += (extp->NumProtectionFields - 1) * in read_pri_intelext()
429 if (extp->MinorVersion >= '1') { in read_pri_intelext()
434 extra_size += extp->extra[extra_size - 1]; in read_pri_intelext()
437 if (extp->MinorVersion >= '3') { in read_pri_intelext()
440 /* Number of hardware-partitions */ in read_pri_intelext()
444 nb_parts = extp->extra[extra_size - 1]; in read_pri_intelext()
446 /* skip the sizeof(partregion) field in CFI 1.4 */ in read_pri_intelext()
447 if (extp->MinorVersion >= '4') in read_pri_intelext()
452 rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size]; in read_pri_intelext()
456 rinfo->NumIdentPartitions=le16_to_cpu(rinfo->NumIdentPartitions); in read_pri_intelext()
457 extra_size += (rinfo->NumBlockTypes - 1) in read_pri_intelext()
461 if (extp->MinorVersion >= '4') in read_pri_intelext()
483 struct cfi_private *cfi = map->fldrv_priv; in cfi_cmdset_0001() local
490 mtd->priv = map; in cfi_cmdset_0001()
491 mtd->type = MTD_NORFLASH; in cfi_cmdset_0001()
494 mtd->_erase = cfi_intelext_erase_varsize; in cfi_cmdset_0001()
495 mtd->_read = cfi_intelext_read; in cfi_cmdset_0001()
496 mtd->_write = cfi_intelext_write_words; in cfi_cmdset_0001()
497 mtd->_sync = cfi_intelext_sync; in cfi_cmdset_0001()
498 mtd->_lock = cfi_intelext_lock; in cfi_cmdset_0001()
499 mtd->_unlock = cfi_intelext_unlock; in cfi_cmdset_0001()
500 mtd->_is_locked = cfi_intelext_is_locked; in cfi_cmdset_0001()
501 mtd->_suspend = cfi_intelext_suspend; in cfi_cmdset_0001()
502 mtd->_resume = cfi_intelext_resume; in cfi_cmdset_0001()
503 mtd->flags = MTD_CAP_NORFLASH; in cfi_cmdset_0001()
504 mtd->name = map->name; in cfi_cmdset_0001()
505 mtd->writesize = 1; in cfi_cmdset_0001()
506 mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; in cfi_cmdset_0001()
508 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; in cfi_cmdset_0001()
510 if (cfi->cfi_mode == CFI_MODE_CFI) { in cfi_cmdset_0001()
512 * It's a real CFI chip, not one for which the probe in cfi_cmdset_0001()
513 * routine faked a CFI structure. So we read the feature in cfi_cmdset_0001()
516 __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; in cfi_cmdset_0001()
526 cfi->cmdset_priv = extp; in cfi_cmdset_0001()
535 if(extp->SuspendCmdSupport & 1) { in cfi_cmdset_0001()
539 else if (cfi->cfi_mode == CFI_MODE_JEDEC) { in cfi_cmdset_0001()
546 for (i=0; i< cfi->numchips; i++) { in cfi_cmdset_0001()
547 if (cfi->cfiq->WordWriteTimeoutTyp) in cfi_cmdset_0001()
548 cfi->chips[i].word_write_time = in cfi_cmdset_0001()
549 1<<cfi->cfiq->WordWriteTimeoutTyp; in cfi_cmdset_0001()
551 cfi->chips[i].word_write_time = 50000; in cfi_cmdset_0001()
553 if (cfi->cfiq->BufWriteTimeoutTyp) in cfi_cmdset_0001()
554 cfi->chips[i].buffer_write_time = in cfi_cmdset_0001()
555 1<<cfi->cfiq->BufWriteTimeoutTyp; in cfi_cmdset_0001()
558 if (cfi->cfiq->BlockEraseTimeoutTyp) in cfi_cmdset_0001()
559 cfi->chips[i].erase_time = in cfi_cmdset_0001()
560 1000<<cfi->cfiq->BlockEraseTimeoutTyp; in cfi_cmdset_0001()
562 cfi->chips[i].erase_time = 2000000; in cfi_cmdset_0001()
564 if (cfi->cfiq->WordWriteTimeoutTyp && in cfi_cmdset_0001()
565 cfi->cfiq->WordWriteTimeoutMax) in cfi_cmdset_0001()
566 cfi->chips[i].word_write_time_max = in cfi_cmdset_0001()
567 1<<(cfi->cfiq->WordWriteTimeoutTyp + in cfi_cmdset_0001()
568 cfi->cfiq->WordWriteTimeoutMax); in cfi_cmdset_0001()
570 cfi->chips[i].word_write_time_max = 50000 * 8; in cfi_cmdset_0001()
572 if (cfi->cfiq->BufWriteTimeoutTyp && in cfi_cmdset_0001()
573 cfi->cfiq->BufWriteTimeoutMax) in cfi_cmdset_0001()
574 cfi->chips[i].buffer_write_time_max = in cfi_cmdset_0001()
575 1<<(cfi->cfiq->BufWriteTimeoutTyp + in cfi_cmdset_0001()
576 cfi->cfiq->BufWriteTimeoutMax); in cfi_cmdset_0001()
578 if (cfi->cfiq->BlockEraseTimeoutTyp && in cfi_cmdset_0001()
579 cfi->cfiq->BlockEraseTimeoutMax) in cfi_cmdset_0001()
580 cfi->chips[i].erase_time_max = in cfi_cmdset_0001()
581 1000<<(cfi->cfiq->BlockEraseTimeoutTyp + in cfi_cmdset_0001()
582 cfi->cfiq->BlockEraseTimeoutMax); in cfi_cmdset_0001()
584 cfi->chips[i].erase_time_max = 2000000 * 8; in cfi_cmdset_0001()
586 cfi->chips[i].ref_point_counter = 0; in cfi_cmdset_0001()
587 init_waitqueue_head(&(cfi->chips[i].wq)); in cfi_cmdset_0001()
590 map->fldrv = &cfi_intelext_chipdrv; in cfi_cmdset_0001()
602 struct map_info *map = mtd->priv; in cfi_intelext_setup()
603 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_setup() local
606 unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave; in cfi_intelext_setup()
608 //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips); in cfi_intelext_setup()
610 mtd->size = devsize * cfi->numchips; in cfi_intelext_setup()
612 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; in cfi_intelext_setup()
613 mtd->eraseregions = kcalloc(mtd->numeraseregions, in cfi_intelext_setup()
616 if (!mtd->eraseregions) in cfi_intelext_setup()
619 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { in cfi_intelext_setup()
621 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; in cfi_intelext_setup()
622 ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; in cfi_intelext_setup()
624 if (mtd->erasesize < ersize) { in cfi_intelext_setup()
625 mtd->erasesize = ersize; in cfi_intelext_setup()
627 for (j=0; j<cfi->numchips; j++) { in cfi_intelext_setup()
628 mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset; in cfi_intelext_setup()
629 mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; in cfi_intelext_setup()
630 mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; in cfi_intelext_setup()
631 mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap = kmalloc(ernum / 8 + 1, GFP_KERNEL); in cfi_intelext_setup()
632 if (!mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap) in cfi_intelext_setup()
644 for (i=0; i<mtd->numeraseregions;i++){ in cfi_intelext_setup()
646 i,(unsigned long long)mtd->eraseregions[i].offset, in cfi_intelext_setup()
647 mtd->eraseregions[i].erasesize, in cfi_intelext_setup()
648 mtd->eraseregions[i].numblocks); in cfi_intelext_setup()
652 mtd->_read_fact_prot_reg = cfi_intelext_read_fact_prot_reg; in cfi_intelext_setup()
653 mtd->_read_user_prot_reg = cfi_intelext_read_user_prot_reg; in cfi_intelext_setup()
654 mtd->_write_user_prot_reg = cfi_intelext_write_user_prot_reg; in cfi_intelext_setup()
655 mtd->_lock_user_prot_reg = cfi_intelext_lock_user_prot_reg; in cfi_intelext_setup()
656 mtd->_get_fact_prot_info = cfi_intelext_get_fact_prot_info; in cfi_intelext_setup()
657 mtd->_get_user_prot_info = cfi_intelext_get_user_prot_info; in cfi_intelext_setup()
662 if (cfi_intelext_partition_fixup(mtd, &cfi) != 0) in cfi_intelext_setup()
666 register_reboot_notifier(&mtd->reboot_notifier); in cfi_intelext_setup()
670 if (mtd->eraseregions) in cfi_intelext_setup()
671 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) in cfi_intelext_setup()
672 for (j=0; j<cfi->numchips; j++) in cfi_intelext_setup()
673 kfree(mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap); in cfi_intelext_setup()
674 kfree(mtd->eraseregions); in cfi_intelext_setup()
676 kfree(cfi->cmdset_priv); in cfi_intelext_setup()
683 struct map_info *map = mtd->priv; in cfi_intelext_partition_fixup()
684 struct cfi_private *cfi = *pcfi; in cfi_intelext_partition_fixup() local
685 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in cfi_intelext_partition_fixup()
688 * Probing of multi-partition flash chips. in cfi_intelext_partition_fixup()
696 * if someone feels motivated enough. --nico in cfi_intelext_partition_fixup()
698 if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3' in cfi_intelext_partition_fixup()
699 && extp->FeatureSupport & (1 << 9)) { in cfi_intelext_partition_fixup()
707 if (extp->NumProtectionFields) in cfi_intelext_partition_fixup()
708 offs = (extp->NumProtectionFields - 1) * in cfi_intelext_partition_fixup()
712 offs += extp->extra[offs+1]+2; in cfi_intelext_partition_fixup()
715 numregions = extp->extra[offs]; in cfi_intelext_partition_fixup()
718 /* skip the sizeof(partregion) field in CFI 1.4 */ in cfi_intelext_partition_fixup()
719 if (extp->MinorVersion >= '4') in cfi_intelext_partition_fixup()
726 rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[offs]; in cfi_intelext_partition_fixup()
727 numparts += rinfo->NumIdentPartitions; in cfi_intelext_partition_fixup()
729 + (rinfo->NumBlockTypes - 1) * in cfi_intelext_partition_fixup()
737 if (extp->MinorVersion >= '4') { in cfi_intelext_partition_fixup()
739 prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs]; in cfi_intelext_partition_fixup()
740 mtd->writesize = cfi->interleave << prinfo->ProgRegShift; in cfi_intelext_partition_fixup()
741 mtd->flags &= ~MTD_BIT_WRITEABLE; in cfi_intelext_partition_fixup()
743 map->name, mtd->writesize, in cfi_intelext_partition_fixup()
744 cfi->interleave * prinfo->ControlValid, in cfi_intelext_partition_fixup()
745 cfi->interleave * prinfo->ControlInvalid); in cfi_intelext_partition_fixup()
753 partshift = cfi->chipshift - __ffs(numparts); in cfi_intelext_partition_fixup()
755 if ((1 << partshift) < mtd->erasesize) { in cfi_intelext_partition_fixup()
759 return -EINVAL; in cfi_intelext_partition_fixup()
762 numvirtchips = cfi->numchips * numparts; in cfi_intelext_partition_fixup()
766 return -ENOMEM; in cfi_intelext_partition_fixup()
767 shared = kmalloc_array(cfi->numchips, in cfi_intelext_partition_fixup()
772 return -ENOMEM; in cfi_intelext_partition_fixup()
774 memcpy(newcfi, cfi, sizeof(struct cfi_private)); in cfi_intelext_partition_fixup()
775 newcfi->numchips = numvirtchips; in cfi_intelext_partition_fixup()
776 newcfi->chipshift = partshift; in cfi_intelext_partition_fixup()
778 chip = &newcfi->chips[0]; in cfi_intelext_partition_fixup()
779 for (i = 0; i < cfi->numchips; i++) { in cfi_intelext_partition_fixup()
783 *chip = cfi->chips[i]; in cfi_intelext_partition_fixup()
784 chip->start += j << partshift; in cfi_intelext_partition_fixup()
785 chip->priv = &shared[i]; in cfi_intelext_partition_fixup()
788 init_waitqueue_head(&chip->wq); in cfi_intelext_partition_fixup()
789 mutex_init(&chip->mutex); in cfi_intelext_partition_fixup()
795 "--> %d partitions of %d KiB\n", in cfi_intelext_partition_fixup()
796 map->name, cfi->numchips, cfi->interleave, in cfi_intelext_partition_fixup()
797 newcfi->numchips, 1<<(newcfi->chipshift-10)); in cfi_intelext_partition_fixup()
799 map->fldrv_priv = newcfi; in cfi_intelext_partition_fixup()
801 kfree(cfi); in cfi_intelext_partition_fixup()
813 struct cfi_private *cfi = map->fldrv_priv; in chip_ready() local
815 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; in chip_ready()
819 if (mode == FL_SYNCING && chip->oldstate != FL_READY) in chip_ready()
822 switch (chip->state) { in chip_ready()
832 if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS)) in chip_ready()
835 mutex_unlock(&chip->mutex); in chip_ready()
837 mutex_lock(&chip->mutex); in chip_ready()
839 return -EAGAIN; in chip_ready()
849 !(cfip->FeatureSupport & 2) || in chip_ready()
851 (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1)))) in chip_ready()
855 if ((adr & chip->in_progress_block_mask) == in chip_ready()
856 chip->in_progress_block_addr) in chip_ready()
860 if (cfi_is_micron_28F00AP30(cfi, chip) && in chip_ready()
861 (chip->in_progress_block_mask == ~(0x8000-1))) in chip_ready()
865 map_write(map, CMD(0xB0), chip->in_progress_block_addr); in chip_ready()
867 /* If the flash has finished erasing, then 'erase suspend' in chip_ready()
868 * appears to make some (28F320) flash devices switch to in chip_ready()
870 * mode so we get the right data. --rmk in chip_ready()
872 map_write(map, CMD(0x70), chip->in_progress_block_addr); in chip_ready()
873 chip->oldstate = FL_ERASING; in chip_ready()
874 chip->state = FL_ERASE_SUSPENDING; in chip_ready()
875 chip->erase_suspended = 1; in chip_ready()
877 status = map_read(map, chip->in_progress_block_addr); in chip_ready()
886 "suspended: status = 0x%lx\n", map->name, status.x[0]); in chip_ready()
887 return -EIO; in chip_ready()
890 mutex_unlock(&chip->mutex); in chip_ready()
892 mutex_lock(&chip->mutex); in chip_ready()
896 chip->state = FL_STATUS; in chip_ready()
901 (mode != FL_WRITING || !cfip || !(cfip->SuspendCmdSupport&1))) in chip_ready()
903 chip->oldstate = chip->state; in chip_ready()
904 chip->state = FL_READY; in chip_ready()
909 return -EIO; in chip_ready()
912 if (mode == FL_READY && chip->oldstate == FL_READY) in chip_ready()
918 add_wait_queue(&chip->wq, &wait); in chip_ready()
919 mutex_unlock(&chip->mutex); in chip_ready()
921 remove_wait_queue(&chip->wq, &wait); in chip_ready()
922 mutex_lock(&chip->mutex); in chip_ready()
923 return -EAGAIN; in chip_ready()
933 if (chip->priv && in get_chip()
935 || mode == FL_SHUTDOWN) && chip->state != FL_SYNCING) { in get_chip()
944 * - any write operation must own shared->writing. in get_chip()
946 * - any erase operation must own _both_ shared->writing and in get_chip()
947 * shared->erasing. in get_chip()
949 * - contention arbitration is handled in the owner's context. in get_chip()
954 struct flchip_shared *shared = chip->priv; in get_chip()
956 mutex_lock(&shared->lock); in get_chip()
957 contender = shared->writing; in get_chip()
968 ret = mutex_trylock(&contender->mutex); in get_chip()
969 mutex_unlock(&shared->lock); in get_chip()
972 mutex_unlock(&chip->mutex); in get_chip()
973 ret = chip_ready(map, contender, contender->start, mode); in get_chip()
974 mutex_lock(&chip->mutex); in get_chip()
976 if (ret == -EAGAIN) { in get_chip()
977 mutex_unlock(&contender->mutex); in get_chip()
981 mutex_unlock(&contender->mutex); in get_chip()
984 mutex_lock(&shared->lock); in get_chip()
988 if (chip->state == FL_SYNCING) { in get_chip()
989 put_chip(map, contender, contender->start); in get_chip()
990 mutex_unlock(&contender->mutex); in get_chip()
993 mutex_unlock(&contender->mutex); in get_chip()
998 if (mode == FL_ERASING && shared->erasing in get_chip()
999 && shared->erasing->oldstate == FL_ERASING) { in get_chip()
1000 mutex_unlock(&shared->lock); in get_chip()
1002 add_wait_queue(&chip->wq, &wait); in get_chip()
1003 mutex_unlock(&chip->mutex); in get_chip()
1005 remove_wait_queue(&chip->wq, &wait); in get_chip()
1006 mutex_lock(&chip->mutex); in get_chip()
1011 shared->writing = chip; in get_chip()
1013 shared->erasing = chip; in get_chip()
1014 mutex_unlock(&shared->lock); in get_chip()
1017 if (ret == -EAGAIN) in get_chip()
1025 struct cfi_private *cfi = map->fldrv_priv; in put_chip() local
1027 if (chip->priv) { in put_chip()
1028 struct flchip_shared *shared = chip->priv; in put_chip()
1029 mutex_lock(&shared->lock); in put_chip()
1030 if (shared->writing == chip && chip->oldstate == FL_READY) { in put_chip()
1032 shared->writing = shared->erasing; in put_chip()
1033 if (shared->writing && shared->writing != chip) { in put_chip()
1035 struct flchip *loaner = shared->writing; in put_chip()
1036 mutex_lock(&loaner->mutex); in put_chip()
1037 mutex_unlock(&shared->lock); in put_chip()
1038 mutex_unlock(&chip->mutex); in put_chip()
1039 put_chip(map, loaner, loaner->start); in put_chip()
1040 mutex_lock(&chip->mutex); in put_chip()
1041 mutex_unlock(&loaner->mutex); in put_chip()
1042 wake_up(&chip->wq); in put_chip()
1045 shared->erasing = NULL; in put_chip()
1046 shared->writing = NULL; in put_chip()
1047 } else if (shared->erasing == chip && shared->writing != chip) { in put_chip()
1055 mutex_unlock(&shared->lock); in put_chip()
1056 wake_up(&chip->wq); in put_chip()
1059 mutex_unlock(&shared->lock); in put_chip()
1062 switch(chip->oldstate) { in put_chip()
1066 one in READY mode. That's bad, and caused -EROFS in put_chip()
1073 map_write(map, CMD(0xd0), chip->in_progress_block_addr); in put_chip()
1074 map_write(map, CMD(0x70), chip->in_progress_block_addr); in put_chip()
1075 chip->oldstate = FL_READY; in put_chip()
1076 chip->state = FL_ERASING; in put_chip()
1080 chip->state = chip->oldstate; in put_chip()
1081 chip->oldstate = FL_READY; in put_chip()
1089 printk(KERN_ERR "%s: put_chip() called with oldstate %d!!\n", map->name, chip->oldstate); in put_chip()
1091 wake_up(&chip->wq); in put_chip()
1097 * No interrupt what so ever can be serviced while the flash isn't in array
1099 * enclosing any code path where the flash is known not to be in array mode.
1103 * didn't emit calls to its own support functions). Also configuring MTD CFI
1118 struct cfi_private *cfi = map->fldrv_priv; in xip_enable() local
1119 if (chip->state != FL_POINT && chip->state != FL_READY) { in xip_enable()
1121 chip->state = FL_READY; in xip_enable()
1129 * When a delay is required for the flash operation to complete, the
1132 * interrupt pending then the flash erase or write operation is suspended,
1135 * the call to schedule() and the suspended flash operation is resumed for
1145 struct cfi_private *cfi = map->fldrv_priv; in xip_wait_for_operation() local
1146 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; in xip_wait_for_operation()
1160 ((chip->state == FL_ERASING && (cfip->FeatureSupport&2)) || in xip_wait_for_operation()
1161 (chip->state == FL_WRITING && (cfip->FeatureSupport&4))) && in xip_wait_for_operation()
1162 (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) { in xip_wait_for_operation()
1173 usec -= done; in xip_wait_for_operation()
1185 return -EIO; in xip_wait_for_operation()
1191 oldstate = chip->state; in xip_wait_for_operation()
1196 chip->erase_suspended = 1; in xip_wait_for_operation()
1201 chip->write_suspended = 1; in xip_wait_for_operation()
1203 chip->state = newstate; in xip_wait_for_operation()
1208 mutex_unlock(&chip->mutex); in xip_wait_for_operation()
1218 mutex_lock(&chip->mutex); in xip_wait_for_operation()
1219 while (chip->state != newstate) { in xip_wait_for_operation()
1222 add_wait_queue(&chip->wq, &wait); in xip_wait_for_operation()
1223 mutex_unlock(&chip->mutex); in xip_wait_for_operation()
1225 remove_wait_queue(&chip->wq, &wait); in xip_wait_for_operation()
1226 mutex_lock(&chip->mutex); in xip_wait_for_operation()
1234 chip->state = oldstate; in xip_wait_for_operation()
1249 return (done >= usec) ? -ETIME : 0; in xip_wait_for_operation()
1254 * the flash is actively programming or erasing since we have to poll for
1256 * a XIP setup so do it before the actual flash operation in this case
1277 struct cfi_private *cfi = map->fldrv_priv; in inval_cache_and_wait_for_operation() local
1279 int chip_state = chip->state; in inval_cache_and_wait_for_operation()
1282 mutex_unlock(&chip->mutex); in inval_cache_and_wait_for_operation()
1285 mutex_lock(&chip->mutex); in inval_cache_and_wait_for_operation()
1294 if (chip->state != chip_state) { in inval_cache_and_wait_for_operation()
1298 add_wait_queue(&chip->wq, &wait); in inval_cache_and_wait_for_operation()
1299 mutex_unlock(&chip->mutex); in inval_cache_and_wait_for_operation()
1301 remove_wait_queue(&chip->wq, &wait); in inval_cache_and_wait_for_operation()
1302 mutex_lock(&chip->mutex); in inval_cache_and_wait_for_operation()
1310 if (chip->erase_suspended && chip_state == FL_ERASING) { in inval_cache_and_wait_for_operation()
1313 chip->erase_suspended = 0; in inval_cache_and_wait_for_operation()
1315 if (chip->write_suspended && chip_state == FL_WRITING) { in inval_cache_and_wait_for_operation()
1318 chip->write_suspended = 0; in inval_cache_and_wait_for_operation()
1322 chip->state = FL_STATUS; in inval_cache_and_wait_for_operation()
1323 return -ETIME; in inval_cache_and_wait_for_operation()
1327 mutex_unlock(&chip->mutex); in inval_cache_and_wait_for_operation()
1335 timeo -= sleep_time; in inval_cache_and_wait_for_operation()
1340 timeo--; in inval_cache_and_wait_for_operation()
1342 mutex_lock(&chip->mutex); in inval_cache_and_wait_for_operation()
1346 chip->state = FL_STATUS; in inval_cache_and_wait_for_operation()
1359 struct cfi_private *cfi = map->fldrv_priv; in do_point_onechip() local
1362 adr += chip->start; in do_point_onechip()
1365 cmd_addr = adr & ~(map_bankwidth(map)-1); in do_point_onechip()
1367 mutex_lock(&chip->mutex); in do_point_onechip()
1372 if (chip->state != FL_POINT && chip->state != FL_READY) in do_point_onechip()
1375 chip->state = FL_POINT; in do_point_onechip()
1376 chip->ref_point_counter++; in do_point_onechip()
1378 mutex_unlock(&chip->mutex); in do_point_onechip()
1386 struct map_info *map = mtd->priv; in cfi_intelext_point()
1387 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_point() local
1392 if (!map->virt) in cfi_intelext_point()
1393 return -EINVAL; in cfi_intelext_point()
1398 chipnum = (from >> cfi->chipshift); in cfi_intelext_point()
1399 ofs = from - (chipnum << cfi->chipshift); in cfi_intelext_point()
1401 *virt = map->virt + cfi->chips[chipnum].start + ofs; in cfi_intelext_point()
1403 *phys = map->phys + cfi->chips[chipnum].start + ofs; in cfi_intelext_point()
1408 if (chipnum >= cfi->numchips) in cfi_intelext_point()
1413 last_end = cfi->chips[chipnum].start; in cfi_intelext_point()
1414 else if (cfi->chips[chipnum].start != last_end) in cfi_intelext_point()
1417 if ((len + ofs -1) >> cfi->chipshift) in cfi_intelext_point()
1418 thislen = (1<<cfi->chipshift) - ofs; in cfi_intelext_point()
1422 ret = do_point_onechip(map, &cfi->chips[chipnum], ofs, thislen); in cfi_intelext_point()
1427 len -= thislen; in cfi_intelext_point()
1430 last_end += 1 << cfi->chipshift; in cfi_intelext_point()
1438 struct map_info *map = mtd->priv; in cfi_intelext_unpoint()
1439 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_unpoint() local
1446 chipnum = (from >> cfi->chipshift); in cfi_intelext_unpoint()
1447 ofs = from - (chipnum << cfi->chipshift); in cfi_intelext_unpoint()
1453 chip = &cfi->chips[chipnum]; in cfi_intelext_unpoint()
1454 if (chipnum >= cfi->numchips) in cfi_intelext_unpoint()
1457 if ((len + ofs -1) >> cfi->chipshift) in cfi_intelext_unpoint()
1458 thislen = (1<<cfi->chipshift) - ofs; in cfi_intelext_unpoint()
1462 mutex_lock(&chip->mutex); in cfi_intelext_unpoint()
1463 if (chip->state == FL_POINT) { in cfi_intelext_unpoint()
1464 chip->ref_point_counter--; in cfi_intelext_unpoint()
1465 if(chip->ref_point_counter == 0) in cfi_intelext_unpoint()
1466 chip->state = FL_READY; in cfi_intelext_unpoint()
1468 printk(KERN_ERR "%s: Error: unpoint called on non pointed region\n", map->name); in cfi_intelext_unpoint()
1469 err = -EINVAL; in cfi_intelext_unpoint()
1472 put_chip(map, chip, chip->start); in cfi_intelext_unpoint()
1473 mutex_unlock(&chip->mutex); in cfi_intelext_unpoint()
1475 len -= thislen; in cfi_intelext_unpoint()
1486 struct cfi_private *cfi = map->fldrv_priv; in do_read_onechip() local
1489 adr += chip->start; in do_read_onechip()
1492 cmd_addr = adr & ~(map_bankwidth(map)-1); in do_read_onechip()
1494 mutex_lock(&chip->mutex); in do_read_onechip()
1497 mutex_unlock(&chip->mutex); in do_read_onechip()
1501 if (chip->state != FL_POINT && chip->state != FL_READY) { in do_read_onechip()
1504 chip->state = FL_READY; in do_read_onechip()
1511 mutex_unlock(&chip->mutex); in do_read_onechip()
1517 struct map_info *map = mtd->priv; in cfi_intelext_read()
1518 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_read() local
1524 chipnum = (from >> cfi->chipshift); in cfi_intelext_read()
1525 ofs = from - (chipnum << cfi->chipshift); in cfi_intelext_read()
1530 if (chipnum >= cfi->numchips) in cfi_intelext_read()
1533 if ((len + ofs -1) >> cfi->chipshift) in cfi_intelext_read()
1534 thislen = (1<<cfi->chipshift) - ofs; in cfi_intelext_read()
1538 ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf); in cfi_intelext_read()
1543 len -= thislen; in cfi_intelext_read()
1555 struct cfi_private *cfi = map->fldrv_priv; in do_write_oneword() local
1559 adr += chip->start; in do_write_oneword()
1563 write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0x40) : CMD(0x41); in do_write_oneword()
1569 return -EINVAL; in do_write_oneword()
1572 mutex_lock(&chip->mutex); in do_write_oneword()
1575 mutex_unlock(&chip->mutex); in do_write_oneword()
1584 chip->state = mode; in do_write_oneword()
1588 chip->word_write_time, in do_write_oneword()
1589 chip->word_write_time_max); in do_write_oneword()
1592 printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); in do_write_oneword()
1607 ret = -EROFS; in do_write_oneword()
1609 printk(KERN_ERR "%s: word write error (bad VPP)\n", map->name); in do_write_oneword()
1610 ret = -EIO; in do_write_oneword()
1612 printk(KERN_ERR "%s: word write error (status 0x%lx)\n", map->name, chipstatus); in do_write_oneword()
1613 ret = -EINVAL; in do_write_oneword()
1622 mutex_unlock(&chip->mutex); in do_write_oneword()
1629 struct map_info *map = mtd->priv; in cfi_intelext_write_words()
1630 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_write_words() local
1635 chipnum = to >> cfi->chipshift; in cfi_intelext_write_words()
1636 ofs = to - (chipnum << cfi->chipshift); in cfi_intelext_write_words()
1638 /* If it's not bus-aligned, do the first byte write */ in cfi_intelext_write_words()
1639 if (ofs & (map_bankwidth(map)-1)) { in cfi_intelext_write_words()
1640 unsigned long bus_ofs = ofs & ~(map_bankwidth(map)-1); in cfi_intelext_write_words()
1641 int gap = ofs - bus_ofs; in cfi_intelext_write_words()
1645 n = min_t(int, len, map_bankwidth(map)-gap); in cfi_intelext_write_words()
1649 ret = do_write_oneword(map, &cfi->chips[chipnum], in cfi_intelext_write_words()
1654 len -= n; in cfi_intelext_write_words()
1659 if (ofs >> cfi->chipshift) { in cfi_intelext_write_words()
1662 if (chipnum == cfi->numchips) in cfi_intelext_write_words()
1670 ret = do_write_oneword(map, &cfi->chips[chipnum], in cfi_intelext_write_words()
1678 len -= map_bankwidth(map); in cfi_intelext_write_words()
1680 if (ofs >> cfi->chipshift) { in cfi_intelext_write_words()
1683 if (chipnum == cfi->numchips) in cfi_intelext_write_words()
1688 if (len & (map_bankwidth(map)-1)) { in cfi_intelext_write_words()
1694 ret = do_write_oneword(map, &cfi->chips[chipnum], in cfi_intelext_write_words()
1710 struct cfi_private *cfi = map->fldrv_priv; in do_write_buffer() local
1719 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; in do_write_buffer()
1720 adr += chip->start; in do_write_buffer()
1722 cmd_adr = adr & ~(wbufsize-1); in do_write_buffer()
1727 if (is_LH28F640BF(cfi)) in do_write_buffer()
1731 write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0xe8) : CMD(0xe9); in do_write_buffer()
1733 mutex_lock(&chip->mutex); in do_write_buffer()
1736 mutex_unlock(&chip->mutex); in do_write_buffer()
1748 if (chip->state != FL_STATUS) { in do_write_buffer()
1750 chip->state = FL_STATUS; in do_write_buffer()
1761 chip->state = FL_WRITING_TO_BUFFER; in do_write_buffer()
1768 chip->state = FL_STATUS; in do_write_buffer()
1774 map->name, Xstatus.x[0], status.x[0]); in do_write_buffer()
1779 word_gap = (-adr & (map_bankwidth(map)-1)); in do_write_buffer()
1780 words = DIV_ROUND_UP(len - word_gap, map_bankwidth(map)); in do_write_buffer()
1782 words--; in do_write_buffer()
1784 word_gap = map_bankwidth(map) - word_gap; in do_write_buffer()
1785 adr -= word_gap; in do_write_buffer()
1796 int n = map_bankwidth(map) - word_gap; in do_write_buffer()
1797 if (n > vec->iov_len - vec_seek) in do_write_buffer()
1798 n = vec->iov_len - vec_seek; in do_write_buffer()
1806 vec->iov_base + vec_seek, in do_write_buffer()
1809 len -= n; in do_write_buffer()
1818 if (vec_seek == vec->iov_len) { in do_write_buffer()
1828 chip->state = FL_WRITING; in do_write_buffer()
1832 chip->buffer_write_time, in do_write_buffer()
1833 chip->buffer_write_time_max); in do_write_buffer()
1836 chip->state = FL_STATUS; in do_write_buffer()
1838 printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name); in do_write_buffer()
1853 ret = -EROFS; in do_write_buffer()
1855 printk(KERN_ERR "%s: buffer write error (bad VPP)\n", map->name); in do_write_buffer()
1856 ret = -EIO; in do_write_buffer()
1858 printk(KERN_ERR "%s: buffer write error (status 0x%lx)\n", map->name, chipstatus); in do_write_buffer()
1859 ret = -EINVAL; in do_write_buffer()
1868 mutex_unlock(&chip->mutex); in do_write_buffer()
1875 struct map_info *map = mtd->priv; in cfi_intelext_writev()
1876 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_writev() local
1877 int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; in cfi_intelext_writev()
1889 chipnum = to >> cfi->chipshift; in cfi_intelext_writev()
1890 ofs = to - (chipnum << cfi->chipshift); in cfi_intelext_writev()
1895 int size = wbufsize - (ofs & (wbufsize-1)); in cfi_intelext_writev()
1899 ret = do_write_buffer(map, &cfi->chips[chipnum], in cfi_intelext_writev()
1906 len -= size; in cfi_intelext_writev()
1908 if (ofs >> cfi->chipshift) { in cfi_intelext_writev()
1911 if (chipnum == cfi->numchips) in cfi_intelext_writev()
1938 struct cfi_private *cfi = map->fldrv_priv; in do_erase_oneblock() local
1943 adr += chip->start; in do_erase_oneblock()
1946 mutex_lock(&chip->mutex); in do_erase_oneblock()
1949 mutex_unlock(&chip->mutex); in do_erase_oneblock()
1963 chip->state = FL_ERASING; in do_erase_oneblock()
1964 chip->erase_suspended = 0; in do_erase_oneblock()
1965 chip->in_progress_block_addr = adr; in do_erase_oneblock()
1966 chip->in_progress_block_mask = ~(len - 1); in do_erase_oneblock()
1970 chip->erase_time, in do_erase_oneblock()
1971 chip->erase_time_max); in do_erase_oneblock()
1974 chip->state = FL_STATUS; in do_erase_oneblock()
1976 printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name); in do_erase_oneblock()
1982 chip->state = FL_STATUS; in do_erase_oneblock()
1995 …printk(KERN_ERR "%s: block erase error: (bad command sequence, status 0x%lx)\n", map->name, chipst… in do_erase_oneblock()
1996 ret = -EINVAL; in do_erase_oneblock()
1999 ret = -EROFS; in do_erase_oneblock()
2002 printk(KERN_ERR "%s: block erase error: (bad VPP)\n", map->name); in do_erase_oneblock()
2003 ret = -EIO; in do_erase_oneblock()
2004 } else if (chipstatus & 0x20 && retries--) { in do_erase_oneblock()
2008 mutex_unlock(&chip->mutex); in do_erase_oneblock()
2011 … printk(KERN_ERR "%s: block erase failed at 0x%08lx (status 0x%lx)\n", map->name, adr, chipstatus); in do_erase_oneblock()
2012 ret = -EIO; in do_erase_oneblock()
2021 mutex_unlock(&chip->mutex); in do_erase_oneblock()
2027 return cfi_varsize_frob(mtd, do_erase_oneblock, instr->addr, in cfi_intelext_erase_varsize()
2028 instr->len, NULL); in cfi_intelext_erase_varsize()
2033 struct map_info *map = mtd->priv; in cfi_intelext_sync()
2034 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_sync() local
2039 for (i=0; !ret && i<cfi->numchips; i++) { in cfi_intelext_sync()
2040 chip = &cfi->chips[i]; in cfi_intelext_sync()
2042 mutex_lock(&chip->mutex); in cfi_intelext_sync()
2043 ret = get_chip(map, chip, chip->start, FL_SYNCING); in cfi_intelext_sync()
2046 chip->oldstate = chip->state; in cfi_intelext_sync()
2047 chip->state = FL_SYNCING; in cfi_intelext_sync()
2048 /* No need to wake_up() on this state change - in cfi_intelext_sync()
2053 mutex_unlock(&chip->mutex); in cfi_intelext_sync()
2058 for (i--; i >=0; i--) { in cfi_intelext_sync()
2059 chip = &cfi->chips[i]; in cfi_intelext_sync()
2061 mutex_lock(&chip->mutex); in cfi_intelext_sync()
2063 if (chip->state == FL_SYNCING) { in cfi_intelext_sync()
2064 chip->state = chip->oldstate; in cfi_intelext_sync()
2065 chip->oldstate = FL_READY; in cfi_intelext_sync()
2066 wake_up(&chip->wq); in cfi_intelext_sync()
2068 mutex_unlock(&chip->mutex); in cfi_intelext_sync()
2077 struct cfi_private *cfi = map->fldrv_priv; in do_getlockstatus_oneblock() local
2078 int status, ofs_factor = cfi->interleave * cfi->device_type; in do_getlockstatus_oneblock()
2080 adr += chip->start; in do_getlockstatus_oneblock()
2083 chip->state = FL_JEDEC_QUERY; in do_getlockstatus_oneblock()
2107 struct cfi_private *cfi = map->fldrv_priv; in do_xxlock_oneblock() local
2108 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in do_xxlock_oneblock()
2112 adr += chip->start; in do_xxlock_oneblock()
2114 mutex_lock(&chip->mutex); in do_xxlock_oneblock()
2117 mutex_unlock(&chip->mutex); in do_xxlock_oneblock()
2127 chip->state = FL_LOCKING; in do_xxlock_oneblock()
2130 chip->state = FL_UNLOCKING; in do_xxlock_oneblock()
2142 * See "Clear Block Lock-Bits Time" on page 40 in in do_xxlock_oneblock()
2146 mdelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1500 : 0; in do_xxlock_oneblock()
2151 chip->state = FL_STATUS; in do_xxlock_oneblock()
2153 printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name); in do_xxlock_oneblock()
2160 mutex_unlock(&chip->mutex); in do_xxlock_oneblock()
2229 struct cfi_private *cfi = map->fldrv_priv; in do_otp_read() local
2232 mutex_lock(&chip->mutex); in do_otp_read()
2233 ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY); in do_otp_read()
2235 mutex_unlock(&chip->mutex); in do_otp_read()
2240 INVALIDATE_CACHED_RANGE(map, chip->start + offset, size); in do_otp_read()
2242 xip_disable(map, chip, chip->start); in do_otp_read()
2243 if (chip->state != FL_JEDEC_QUERY) { in do_otp_read()
2244 map_write(map, CMD(0x90), chip->start); in do_otp_read()
2245 chip->state = FL_JEDEC_QUERY; in do_otp_read()
2247 map_copy_from(map, buf, chip->start + offset, size); in do_otp_read()
2248 xip_enable(map, chip, chip->start); in do_otp_read()
2251 INVALIDATE_CACHED_RANGE(map, chip->start + offset, size); in do_otp_read()
2253 put_chip(map, chip, chip->start); in do_otp_read()
2254 mutex_unlock(&chip->mutex); in do_otp_read()
2265 unsigned long bus_ofs = offset & ~(map_bankwidth(map)-1); in do_otp_write()
2266 int gap = offset - bus_ofs; in do_otp_write()
2267 int n = min_t(int, size, map_bankwidth(map)-gap); in do_otp_write()
2277 size -= n; in do_otp_write()
2287 struct cfi_private *cfi = map->fldrv_priv; in do_otp_lock() local
2292 return -EXDEV; in do_otp_lock()
2303 struct map_info *map = mtd->priv; in cfi_intelext_otp_walk()
2304 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_otp_walk() local
2305 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in cfi_intelext_otp_walk()
2316 if (!extp || !(extp->FeatureSupport & 64) || !extp->NumProtectionFields) in cfi_intelext_otp_walk()
2317 return -ENODATA; in cfi_intelext_otp_walk()
2320 devsize = (1 << cfi->cfiq->DevSize) * cfi->interleave; in cfi_intelext_otp_walk()
2321 chip_step = devsize >> cfi->chipshift; in cfi_intelext_otp_walk()
2325 For example: Intel 28F256L18T (T means top-parameter device) */ in cfi_intelext_otp_walk()
2326 if (cfi->mfr == CFI_MFR_INTEL) { in cfi_intelext_otp_walk()
2327 switch (cfi->id) { in cfi_intelext_otp_walk()
2331 chip_num = chip_step - 1; in cfi_intelext_otp_walk()
2335 for ( ; chip_num < cfi->numchips; chip_num += chip_step) { in cfi_intelext_otp_walk()
2336 chip = &cfi->chips[chip_num]; in cfi_intelext_otp_walk()
2337 otp = (struct cfi_intelext_otpinfo *)&extp->extra[0]; in cfi_intelext_otp_walk()
2341 reg_prot_offset = extp->ProtRegAddr; in cfi_intelext_otp_walk()
2343 reg_fact_size = 1 << extp->FactProtRegSize; in cfi_intelext_otp_walk()
2345 reg_user_size = 1 << extp->UserProtRegSize; in cfi_intelext_otp_walk()
2348 /* flash geometry fixup */ in cfi_intelext_otp_walk()
2350 data_offset *= cfi->interleave * cfi->device_type; in cfi_intelext_otp_walk()
2351 reg_prot_offset *= cfi->interleave * cfi->device_type; in cfi_intelext_otp_walk()
2352 reg_fact_size *= cfi->interleave; in cfi_intelext_otp_walk()
2353 reg_user_size *= cfi->interleave; in cfi_intelext_otp_walk()
2375 len -= sizeof(struct otp_info); in cfi_intelext_otp_walk()
2377 return -ENOSPC; in cfi_intelext_otp_walk()
2386 otpinfo->start = from; in cfi_intelext_otp_walk()
2387 otpinfo->length = groupsize; in cfi_intelext_otp_walk()
2388 otpinfo->locked = in cfi_intelext_otp_walk()
2395 from -= groupsize; in cfi_intelext_otp_walk()
2400 size -= from; in cfi_intelext_otp_walk()
2410 len -= size; in cfi_intelext_otp_walk()
2415 groups--; in cfi_intelext_otp_walk()
2419 if (++field == extp->NumProtectionFields) in cfi_intelext_otp_walk()
2421 reg_prot_offset = otp->ProtRegAddr; in cfi_intelext_otp_walk()
2422 reg_fact_groups = otp->FactGroups; in cfi_intelext_otp_walk()
2423 reg_fact_size = 1 << otp->FactProtRegSize; in cfi_intelext_otp_walk()
2424 reg_user_groups = otp->UserGroups; in cfi_intelext_otp_walk()
2425 reg_user_size = 1 << otp->UserProtRegSize; in cfi_intelext_otp_walk()
2489 for (i = 0; i < mtd->numeraseregions; i++) { in cfi_intelext_save_locks()
2490 region = &mtd->eraseregions[i]; in cfi_intelext_save_locks()
2491 if (!region->lockmap) in cfi_intelext_save_locks()
2494 for (block = 0; block < region->numblocks; block++){ in cfi_intelext_save_locks()
2495 len = region->erasesize; in cfi_intelext_save_locks()
2496 adr = region->offset + block * len; in cfi_intelext_save_locks()
2501 set_bit(block, region->lockmap); in cfi_intelext_save_locks()
2503 clear_bit(block, region->lockmap); in cfi_intelext_save_locks()
2510 struct map_info *map = mtd->priv; in cfi_intelext_suspend()
2511 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_suspend() local
2512 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in cfi_intelext_suspend()
2517 if ((mtd->flags & MTD_POWERUP_LOCK) in cfi_intelext_suspend()
2518 && extp && (extp->FeatureSupport & (1 << 5))) in cfi_intelext_suspend()
2521 for (i=0; !ret && i<cfi->numchips; i++) { in cfi_intelext_suspend()
2522 chip = &cfi->chips[i]; in cfi_intelext_suspend()
2524 mutex_lock(&chip->mutex); in cfi_intelext_suspend()
2526 switch (chip->state) { in cfi_intelext_suspend()
2531 if (chip->oldstate == FL_READY) { in cfi_intelext_suspend()
2533 map_write(map, CMD(0xFF), cfi->chips[i].start); in cfi_intelext_suspend()
2534 chip->oldstate = chip->state; in cfi_intelext_suspend()
2535 chip->state = FL_PM_SUSPENDED; in cfi_intelext_suspend()
2536 /* No need to wake_up() on this state change - in cfi_intelext_suspend()
2542 …printk(KERN_NOTICE "Flash device refused suspend due to pending operation (oldstate %d)\n", chip->… in cfi_intelext_suspend()
2543 ret = -EAGAIN; in cfi_intelext_suspend()
2548 allowed to. Or should we return -EAGAIN, because the upper layers in cfi_intelext_suspend()
2551 …printk(KERN_NOTICE "Flash device refused suspend due to active operation (state %d)\n", chip->stat… in cfi_intelext_suspend()
2552 ret = -EAGAIN; in cfi_intelext_suspend()
2557 mutex_unlock(&chip->mutex); in cfi_intelext_suspend()
2563 for (i--; i >=0; i--) { in cfi_intelext_suspend()
2564 chip = &cfi->chips[i]; in cfi_intelext_suspend()
2566 mutex_lock(&chip->mutex); in cfi_intelext_suspend()
2568 if (chip->state == FL_PM_SUSPENDED) { in cfi_intelext_suspend()
2572 chip->state = chip->oldstate; in cfi_intelext_suspend()
2573 chip->oldstate = FL_READY; in cfi_intelext_suspend()
2574 wake_up(&chip->wq); in cfi_intelext_suspend()
2576 mutex_unlock(&chip->mutex); in cfi_intelext_suspend()
2590 for (i = 0; i < mtd->numeraseregions; i++) { in cfi_intelext_restore_locks()
2591 region = &mtd->eraseregions[i]; in cfi_intelext_restore_locks()
2592 if (!region->lockmap) in cfi_intelext_restore_locks()
2595 for_each_clear_bit(block, region->lockmap, region->numblocks) { in cfi_intelext_restore_locks()
2596 len = region->erasesize; in cfi_intelext_restore_locks()
2597 adr = region->offset + block * len; in cfi_intelext_restore_locks()
2605 struct map_info *map = mtd->priv; in cfi_intelext_resume()
2606 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_resume() local
2607 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in cfi_intelext_resume()
2611 for (i=0; i<cfi->numchips; i++) { in cfi_intelext_resume()
2613 chip = &cfi->chips[i]; in cfi_intelext_resume()
2615 mutex_lock(&chip->mutex); in cfi_intelext_resume()
2618 if (chip->state == FL_PM_SUSPENDED) { in cfi_intelext_resume()
2621 map_write(map, CMD(0xFF), cfi->chips[i].start); in cfi_intelext_resume()
2622 chip->oldstate = chip->state = FL_READY; in cfi_intelext_resume()
2623 wake_up(&chip->wq); in cfi_intelext_resume()
2626 mutex_unlock(&chip->mutex); in cfi_intelext_resume()
2629 if ((mtd->flags & MTD_POWERUP_LOCK) in cfi_intelext_resume()
2630 && extp && (extp->FeatureSupport & (1 << 5))) in cfi_intelext_resume()
2636 struct map_info *map = mtd->priv; in cfi_intelext_reset()
2637 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_reset() local
2640 for (i=0; i < cfi->numchips; i++) { in cfi_intelext_reset()
2641 struct flchip *chip = &cfi->chips[i]; in cfi_intelext_reset()
2645 flash is accessible for soft reboot. */ in cfi_intelext_reset()
2646 mutex_lock(&chip->mutex); in cfi_intelext_reset()
2647 ret = get_chip(map, chip, chip->start, FL_SHUTDOWN); in cfi_intelext_reset()
2649 map_write(map, CMD(0xff), chip->start); in cfi_intelext_reset()
2650 chip->state = FL_SHUTDOWN; in cfi_intelext_reset()
2651 put_chip(map, chip, chip->start); in cfi_intelext_reset()
2653 mutex_unlock(&chip->mutex); in cfi_intelext_reset()
2671 struct map_info *map = mtd->priv; in cfi_intelext_destroy()
2672 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_destroy() local
2676 unregister_reboot_notifier(&mtd->reboot_notifier); in cfi_intelext_destroy()
2677 kfree(cfi->cmdset_priv); in cfi_intelext_destroy()
2678 kfree(cfi->cfiq); in cfi_intelext_destroy()
2679 kfree(cfi->chips[0].priv); in cfi_intelext_destroy()
2680 kfree(cfi); in cfi_intelext_destroy()
2681 for (i = 0; i < mtd->numeraseregions; i++) { in cfi_intelext_destroy()
2682 region = &mtd->eraseregions[i]; in cfi_intelext_destroy()
2683 kfree(region->lockmap); in cfi_intelext_destroy()
2685 kfree(mtd->eraseregions); in cfi_intelext_destroy()
2690 MODULE_DESCRIPTION("MTD chip driver for Intel/Sharp flash chips");