Lines Matching +full:interleave +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0
10 * - completely revamped method functions so they are aware and
11 * independent of the flash geometry (buswidth, interleave, etc.)
12 * - scalability vs code size is completely set at compile-time
14 * - optimized write buffer method
16 * - reworked lock/unlock/erase support for var size flash
18 * - auto unlock sectors on resume for auto locking flash on power up
42 // debugging, turns off buffer write mode if set to 1
99 static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
100 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
124 printk(" Extended Query version %c.%c\n", extp->MajorVersion, extp->MinorVersion); in cfi_tell_features()
125 printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); in cfi_tell_features()
126 printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); in cfi_tell_features()
127 printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); in cfi_tell_features()
128 printk(" - Suspend Program: %s\n", extp->FeatureSupport&4?"supported":"unsupported"); in cfi_tell_features()
129 printk(" - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported"); in cfi_tell_features()
130 printk(" - Queued Erase: %s\n", extp->FeatureSupport&16?"supported":"unsupported"); in cfi_tell_features()
131 printk(" - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported"); in cfi_tell_features()
132 printk(" - Protection Bits: %s\n", extp->FeatureSupport&64?"supported":"unsupported"); in cfi_tell_features()
133 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); in cfi_tell_features()
134 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); in cfi_tell_features()
135 printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); in cfi_tell_features()
136 …printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported"… in cfi_tell_features()
138 if (extp->FeatureSupport & (1<<i)) in cfi_tell_features()
139 printk(" - Unknown Bit %X: supported\n", i); in cfi_tell_features()
142 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); in cfi_tell_features()
143 …printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsuppor… in cfi_tell_features()
145 if (extp->SuspendCmdSupport & (1<<i)) in cfi_tell_features()
146 printk(" - Unknown Bit %X: supported\n", i); in cfi_tell_features()
149 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); in cfi_tell_features()
150 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); in cfi_tell_features()
151 printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); in cfi_tell_features()
153 if (extp->BlkStatusRegMask & (1<<i)) in cfi_tell_features()
154 printk(" - Unknown Bit %X Active: yes\n",i); in cfi_tell_features()
156 printk(" - EFA Lock Bit: %s\n", extp->BlkStatusRegMask&16?"yes":"no"); in cfi_tell_features()
157 printk(" - EFA Lock-Down Bit: %s\n", extp->BlkStatusRegMask&32?"yes":"no"); in cfi_tell_features()
159 if (extp->BlkStatusRegMask & (1<<i)) in cfi_tell_features()
160 printk(" - Unknown Bit %X Active: yes\n",i); in cfi_tell_features()
164 extp->VccOptimal >> 4, extp->VccOptimal & 0xf); in cfi_tell_features()
165 if (extp->VppOptimal) in cfi_tell_features()
167 extp->VppOptimal >> 4, extp->VppOptimal & 0xf); in cfi_tell_features()
174 struct map_info *map = mtd->priv; in fixup_convert_atmel_pri()
175 struct cfi_private *cfi = map->fldrv_priv; in fixup_convert_atmel_pri()
176 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in fixup_convert_atmel_pri()
181 extp->FeatureSupport = cpu_to_le32(extp->FeatureSupport); in fixup_convert_atmel_pri()
182 extp->BlkStatusRegMask = cpu_to_le16(extp->BlkStatusRegMask); in fixup_convert_atmel_pri()
183 extp->ProtRegAddr = cpu_to_le16(extp->ProtRegAddr); in fixup_convert_atmel_pri()
186 memset((char *)extp + 5, 0, sizeof(*extp) - 5); in fixup_convert_atmel_pri()
198 if (atmel_pri.Features & 0x20) /* page mode read supported */ in fixup_convert_atmel_pri()
205 extp->FeatureSupport = features; in fixup_convert_atmel_pri()
207 /* burst write mode not supported */ in fixup_convert_atmel_pri()
208 cfi->cfiq->BufWriteTimeoutTyp = 0; in fixup_convert_atmel_pri()
209 cfi->cfiq->BufWriteTimeoutMax = 0; in fixup_convert_atmel_pri()
214 struct map_info *map = mtd->priv; in fixup_at49bv640dx_lock()
215 struct cfi_private *cfi = map->fldrv_priv; in fixup_at49bv640dx_lock()
216 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; in fixup_at49bv640dx_lock()
218 cfip->FeatureSupport |= (1 << 5); in fixup_at49bv640dx_lock()
219 mtd->flags |= MTD_POWERUP_LOCK; in fixup_at49bv640dx_lock()
226 struct map_info *map = mtd->priv; in fixup_intel_strataflash()
227 struct cfi_private *cfi = map->fldrv_priv; in fixup_intel_strataflash()
228 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in fixup_intel_strataflash()
232 extp->SuspendCmdSupport &= ~1; in fixup_intel_strataflash()
239 struct map_info *map = mtd->priv; in fixup_no_write_suspend()
240 struct cfi_private *cfi = map->fldrv_priv; in fixup_no_write_suspend()
241 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; in fixup_no_write_suspend()
243 if (cfip && (cfip->FeatureSupport&4)) { in fixup_no_write_suspend()
244 cfip->FeatureSupport &= ~4; in fixup_no_write_suspend()
252 struct map_info *map = mtd->priv; in fixup_st_m28w320ct()
253 struct cfi_private *cfi = map->fldrv_priv; in fixup_st_m28w320ct()
255 cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ in fixup_st_m28w320ct()
256 cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ in fixup_st_m28w320ct()
261 struct map_info *map = mtd->priv; in fixup_st_m28w320cb()
262 struct cfi_private *cfi = map->fldrv_priv; in fixup_st_m28w320cb()
265 cfi->cfiq->EraseRegionInfo[1] = in fixup_st_m28w320cb()
266 (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; in fixup_st_m28w320cb()
272 if (cfi->mfr == CFI_MFR_SHARP && ( in is_LH28F640BF()
273 cfi->id == LH28F640BFHE_PTTL90 || cfi->id == LH28F640BFHE_PBTL90 || in is_LH28F640BF()
274 cfi->id == LH28F640BFHE_PTTL70A || cfi->id == LH28F640BFHE_PBTL70A)) in is_LH28F640BF()
281 struct map_info *map = mtd->priv; in fixup_LH28F640BF()
282 struct cfi_private *cfi = map->fldrv_priv; in fixup_LH28F640BF()
283 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in fixup_LH28F640BF()
286 * to a single partition (PCR = 0x000): PCR is embedded into A0-A15. */ in fixup_LH28F640BF()
295 extp->FeatureSupport &= ~512; in fixup_LH28F640BF()
301 struct map_info *map = mtd->priv; in fixup_use_point()
302 if (!mtd->_point && map_is_linear(map)) { in fixup_use_point()
303 mtd->_point = cfi_intelext_point; in fixup_use_point()
304 mtd->_unpoint = cfi_intelext_unpoint; in fixup_use_point()
310 struct map_info *map = mtd->priv; in fixup_use_write_buffers()
311 struct cfi_private *cfi = map->fldrv_priv; in fixup_use_write_buffers()
312 if (cfi->cfiq->BufWriteTimeoutTyp) { in fixup_use_write_buffers()
314 mtd->_write = cfi_intelext_write_buffers; in fixup_use_write_buffers()
315 mtd->_writev = cfi_intelext_writev; in fixup_use_write_buffers()
320 * Some chips power-up with all sectors locked by default.
324 struct map_info *map = mtd->priv; in fixup_unlock_powerup_lock()
325 struct cfi_private *cfi = map->fldrv_priv; in fixup_unlock_powerup_lock()
326 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; in fixup_unlock_powerup_lock()
328 if (cfip->FeatureSupport&32) { in fixup_unlock_powerup_lock()
329 printk(KERN_INFO "Using auto-unlock on power-up/resume\n" ); in fixup_unlock_powerup_lock()
330 mtd->flags |= MTD_POWERUP_LOCK; in fixup_unlock_powerup_lock()
376 if (cfi->mfr == CFI_MFR_INTEL && in cfi_fixup_major_minor()
377 cfi->id == PF38F4476 && extp->MinorVersion == '3') in cfi_fixup_major_minor()
378 extp->MinorVersion = '1'; in cfi_fixup_major_minor()
387 if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30) in cfi_is_micron_28F00AP30()
395 struct cfi_private *cfi = map->fldrv_priv; in read_pri_intelext()
407 if (extp->MajorVersion != '1' || in read_pri_intelext()
408 (extp->MinorVersion < '0' || extp->MinorVersion > '5')) { in read_pri_intelext()
410 "version %c.%c.\n", extp->MajorVersion, in read_pri_intelext()
411 extp->MinorVersion); in read_pri_intelext()
417 extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport); in read_pri_intelext()
418 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); in read_pri_intelext()
419 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); in read_pri_intelext()
421 if (extp->MinorVersion >= '0') { in read_pri_intelext()
425 if (extp->NumProtectionFields) { in read_pri_intelext()
427 (struct cfi_intelext_otpinfo *)&extp->extra[0]; in read_pri_intelext()
429 extra_size += (extp->NumProtectionFields - 1) * in read_pri_intelext()
436 for (i = 0; i < extp->NumProtectionFields - 1; i++) { in read_pri_intelext()
437 otp->ProtRegAddr = le32_to_cpu(otp->ProtRegAddr); in read_pri_intelext()
438 otp->FactGroups = le16_to_cpu(otp->FactGroups); in read_pri_intelext()
439 otp->UserGroups = le16_to_cpu(otp->UserGroups); in read_pri_intelext()
446 if (extp->MinorVersion >= '1') { in read_pri_intelext()
451 extra_size += extp->extra[extra_size - 1]; in read_pri_intelext()
454 if (extp->MinorVersion >= '3') { in read_pri_intelext()
457 /* Number of hardware-partitions */ in read_pri_intelext()
461 nb_parts = extp->extra[extra_size - 1]; in read_pri_intelext()
464 if (extp->MinorVersion >= '4') in read_pri_intelext()
469 rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size]; in read_pri_intelext()
473 rinfo->NumIdentPartitions=le16_to_cpu(rinfo->NumIdentPartitions); in read_pri_intelext()
474 extra_size += (rinfo->NumBlockTypes - 1) in read_pri_intelext()
478 if (extp->MinorVersion >= '4') in read_pri_intelext()
500 struct cfi_private *cfi = map->fldrv_priv; in cfi_cmdset_0001()
507 mtd->priv = map; in cfi_cmdset_0001()
508 mtd->type = MTD_NORFLASH; in cfi_cmdset_0001()
511 mtd->_erase = cfi_intelext_erase_varsize; in cfi_cmdset_0001()
512 mtd->_read = cfi_intelext_read; in cfi_cmdset_0001()
513 mtd->_write = cfi_intelext_write_words; in cfi_cmdset_0001()
514 mtd->_sync = cfi_intelext_sync; in cfi_cmdset_0001()
515 mtd->_lock = cfi_intelext_lock; in cfi_cmdset_0001()
516 mtd->_unlock = cfi_intelext_unlock; in cfi_cmdset_0001()
517 mtd->_is_locked = cfi_intelext_is_locked; in cfi_cmdset_0001()
518 mtd->_suspend = cfi_intelext_suspend; in cfi_cmdset_0001()
519 mtd->_resume = cfi_intelext_resume; in cfi_cmdset_0001()
520 mtd->flags = MTD_CAP_NORFLASH; in cfi_cmdset_0001()
521 mtd->name = map->name; in cfi_cmdset_0001()
522 mtd->writesize = 1; in cfi_cmdset_0001()
523 mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; in cfi_cmdset_0001()
525 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; in cfi_cmdset_0001()
527 if (cfi->cfi_mode == CFI_MODE_CFI) { in cfi_cmdset_0001()
533 __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; in cfi_cmdset_0001()
543 cfi->cmdset_priv = extp; in cfi_cmdset_0001()
552 if(extp->SuspendCmdSupport & 1) { in cfi_cmdset_0001()
556 else if (cfi->cfi_mode == CFI_MODE_JEDEC) { in cfi_cmdset_0001()
563 for (i=0; i< cfi->numchips; i++) { in cfi_cmdset_0001()
564 if (cfi->cfiq->WordWriteTimeoutTyp) in cfi_cmdset_0001()
565 cfi->chips[i].word_write_time = in cfi_cmdset_0001()
566 1<<cfi->cfiq->WordWriteTimeoutTyp; in cfi_cmdset_0001()
568 cfi->chips[i].word_write_time = 50000; in cfi_cmdset_0001()
570 if (cfi->cfiq->BufWriteTimeoutTyp) in cfi_cmdset_0001()
571 cfi->chips[i].buffer_write_time = in cfi_cmdset_0001()
572 1<<cfi->cfiq->BufWriteTimeoutTyp; in cfi_cmdset_0001()
575 if (cfi->cfiq->BlockEraseTimeoutTyp) in cfi_cmdset_0001()
576 cfi->chips[i].erase_time = in cfi_cmdset_0001()
577 1000<<cfi->cfiq->BlockEraseTimeoutTyp; in cfi_cmdset_0001()
579 cfi->chips[i].erase_time = 2000000; in cfi_cmdset_0001()
581 if (cfi->cfiq->WordWriteTimeoutTyp && in cfi_cmdset_0001()
582 cfi->cfiq->WordWriteTimeoutMax) in cfi_cmdset_0001()
583 cfi->chips[i].word_write_time_max = in cfi_cmdset_0001()
584 1<<(cfi->cfiq->WordWriteTimeoutTyp + in cfi_cmdset_0001()
585 cfi->cfiq->WordWriteTimeoutMax); in cfi_cmdset_0001()
587 cfi->chips[i].word_write_time_max = 50000 * 8; in cfi_cmdset_0001()
589 if (cfi->cfiq->BufWriteTimeoutTyp && in cfi_cmdset_0001()
590 cfi->cfiq->BufWriteTimeoutMax) in cfi_cmdset_0001()
591 cfi->chips[i].buffer_write_time_max = in cfi_cmdset_0001()
592 1<<(cfi->cfiq->BufWriteTimeoutTyp + in cfi_cmdset_0001()
593 cfi->cfiq->BufWriteTimeoutMax); in cfi_cmdset_0001()
595 if (cfi->cfiq->BlockEraseTimeoutTyp && in cfi_cmdset_0001()
596 cfi->cfiq->BlockEraseTimeoutMax) in cfi_cmdset_0001()
597 cfi->chips[i].erase_time_max = in cfi_cmdset_0001()
598 1000<<(cfi->cfiq->BlockEraseTimeoutTyp + in cfi_cmdset_0001()
599 cfi->cfiq->BlockEraseTimeoutMax); in cfi_cmdset_0001()
601 cfi->chips[i].erase_time_max = 2000000 * 8; in cfi_cmdset_0001()
603 cfi->chips[i].ref_point_counter = 0; in cfi_cmdset_0001()
604 init_waitqueue_head(&(cfi->chips[i].wq)); in cfi_cmdset_0001()
607 map->fldrv = &cfi_intelext_chipdrv; in cfi_cmdset_0001()
619 struct map_info *map = mtd->priv; in cfi_intelext_setup()
620 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_setup()
623 unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave; in cfi_intelext_setup()
625 //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips); in cfi_intelext_setup()
627 mtd->size = devsize * cfi->numchips; in cfi_intelext_setup()
629 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; in cfi_intelext_setup()
630 mtd->eraseregions = kcalloc(mtd->numeraseregions, in cfi_intelext_setup()
633 if (!mtd->eraseregions) in cfi_intelext_setup()
636 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { in cfi_intelext_setup()
638 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; in cfi_intelext_setup()
639 ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; in cfi_intelext_setup()
641 if (mtd->erasesize < ersize) { in cfi_intelext_setup()
642 mtd->erasesize = ersize; in cfi_intelext_setup()
644 for (j=0; j<cfi->numchips; j++) { in cfi_intelext_setup()
645 mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset; in cfi_intelext_setup()
646 mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; in cfi_intelext_setup()
647 mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; in cfi_intelext_setup()
648 mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap = kmalloc(ernum / 8 + 1, GFP_KERNEL); in cfi_intelext_setup()
649 if (!mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap) in cfi_intelext_setup()
661 for (i=0; i<mtd->numeraseregions;i++){ in cfi_intelext_setup()
663 i,(unsigned long long)mtd->eraseregions[i].offset, in cfi_intelext_setup()
664 mtd->eraseregions[i].erasesize, in cfi_intelext_setup()
665 mtd->eraseregions[i].numblocks); in cfi_intelext_setup()
669 mtd->_read_fact_prot_reg = cfi_intelext_read_fact_prot_reg; in cfi_intelext_setup()
670 mtd->_read_user_prot_reg = cfi_intelext_read_user_prot_reg; in cfi_intelext_setup()
671 mtd->_write_user_prot_reg = cfi_intelext_write_user_prot_reg; in cfi_intelext_setup()
672 mtd->_lock_user_prot_reg = cfi_intelext_lock_user_prot_reg; in cfi_intelext_setup()
673 mtd->_get_fact_prot_info = cfi_intelext_get_fact_prot_info; in cfi_intelext_setup()
674 mtd->_get_user_prot_info = cfi_intelext_get_user_prot_info; in cfi_intelext_setup()
683 register_reboot_notifier(&mtd->reboot_notifier); in cfi_intelext_setup()
687 if (mtd->eraseregions) in cfi_intelext_setup()
688 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) in cfi_intelext_setup()
689 for (j=0; j<cfi->numchips; j++) in cfi_intelext_setup()
690 kfree(mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap); in cfi_intelext_setup()
691 kfree(mtd->eraseregions); in cfi_intelext_setup()
693 kfree(cfi->cmdset_priv); in cfi_intelext_setup()
700 struct map_info *map = mtd->priv; in cfi_intelext_partition_fixup()
702 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in cfi_intelext_partition_fixup()
705 * Probing of multi-partition flash chips. in cfi_intelext_partition_fixup()
713 * if someone feels motivated enough. --nico in cfi_intelext_partition_fixup()
715 if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3' in cfi_intelext_partition_fixup()
716 && extp->FeatureSupport & (1 << 9)) { in cfi_intelext_partition_fixup()
724 if (extp->NumProtectionFields) in cfi_intelext_partition_fixup()
725 offs = (extp->NumProtectionFields - 1) * in cfi_intelext_partition_fixup()
729 offs += extp->extra[offs+1]+2; in cfi_intelext_partition_fixup()
732 numregions = extp->extra[offs]; in cfi_intelext_partition_fixup()
736 if (extp->MinorVersion >= '4') in cfi_intelext_partition_fixup()
743 rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[offs]; in cfi_intelext_partition_fixup()
744 numparts += rinfo->NumIdentPartitions; in cfi_intelext_partition_fixup()
746 + (rinfo->NumBlockTypes - 1) * in cfi_intelext_partition_fixup()
754 if (extp->MinorVersion >= '4') { in cfi_intelext_partition_fixup()
756 prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs]; in cfi_intelext_partition_fixup()
757 mtd->writesize = cfi->interleave << prinfo->ProgRegShift; in cfi_intelext_partition_fixup()
758 mtd->flags &= ~MTD_BIT_WRITEABLE; in cfi_intelext_partition_fixup()
760 map->name, mtd->writesize, in cfi_intelext_partition_fixup()
761 cfi->interleave * prinfo->ControlValid, in cfi_intelext_partition_fixup()
762 cfi->interleave * prinfo->ControlInvalid); in cfi_intelext_partition_fixup()
770 partshift = cfi->chipshift - __ffs(numparts); in cfi_intelext_partition_fixup()
772 if ((1 << partshift) < mtd->erasesize) { in cfi_intelext_partition_fixup()
776 return -EINVAL; in cfi_intelext_partition_fixup()
779 numvirtchips = cfi->numchips * numparts; in cfi_intelext_partition_fixup()
783 return -ENOMEM; in cfi_intelext_partition_fixup()
784 shared = kmalloc_array(cfi->numchips, in cfi_intelext_partition_fixup()
789 return -ENOMEM; in cfi_intelext_partition_fixup()
792 newcfi->numchips = numvirtchips; in cfi_intelext_partition_fixup()
793 newcfi->chipshift = partshift; in cfi_intelext_partition_fixup()
795 chip = &newcfi->chips[0]; in cfi_intelext_partition_fixup()
796 for (i = 0; i < cfi->numchips; i++) { in cfi_intelext_partition_fixup()
800 *chip = cfi->chips[i]; in cfi_intelext_partition_fixup()
801 chip->start += j << partshift; in cfi_intelext_partition_fixup()
802 chip->priv = &shared[i]; in cfi_intelext_partition_fixup()
805 init_waitqueue_head(&chip->wq); in cfi_intelext_partition_fixup()
806 mutex_init(&chip->mutex); in cfi_intelext_partition_fixup()
812 "--> %d partitions of %d KiB\n", in cfi_intelext_partition_fixup()
813 map->name, cfi->numchips, cfi->interleave, in cfi_intelext_partition_fixup()
814 newcfi->numchips, 1<<(newcfi->chipshift-10)); in cfi_intelext_partition_fixup()
816 map->fldrv_priv = newcfi; in cfi_intelext_partition_fixup()
827 static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode) in chip_ready() argument
830 struct cfi_private *cfi = map->fldrv_priv; in chip_ready()
832 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; in chip_ready()
836 if (mode == FL_SYNCING && chip->oldstate != FL_READY) in chip_ready()
839 switch (chip->state) { in chip_ready()
849 if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS)) in chip_ready()
852 mutex_unlock(&chip->mutex); in chip_ready()
854 mutex_lock(&chip->mutex); in chip_ready()
856 return -EAGAIN; in chip_ready()
866 !(cfip->FeatureSupport & 2) || in chip_ready()
867 !(mode == FL_READY || mode == FL_POINT || in chip_ready()
868 (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1)))) in chip_ready()
872 if ((adr & chip->in_progress_block_mask) == in chip_ready()
873 chip->in_progress_block_addr) in chip_ready()
878 (chip->in_progress_block_mask == ~(0x8000-1))) in chip_ready()
882 map_write(map, CMD(0xB0), chip->in_progress_block_addr); in chip_ready()
886 * 'read' mode. Make sure that we switch to 'read status' in chip_ready()
887 * mode so we get the right data. --rmk in chip_ready()
889 map_write(map, CMD(0x70), chip->in_progress_block_addr); in chip_ready()
890 chip->oldstate = FL_ERASING; in chip_ready()
891 chip->state = FL_ERASE_SUSPENDING; in chip_ready()
892 chip->erase_suspended = 1; in chip_ready()
894 status = map_read(map, chip->in_progress_block_addr); in chip_ready()
900 * Make sure we're in 'read status' mode if it had finished */ in chip_ready()
903 "suspended: status = 0x%lx\n", map->name, status.x[0]); in chip_ready()
904 return -EIO; in chip_ready()
907 mutex_unlock(&chip->mutex); in chip_ready()
909 mutex_lock(&chip->mutex); in chip_ready()
913 chip->state = FL_STATUS; in chip_ready()
917 if (mode != FL_READY && mode != FL_POINT && in chip_ready()
918 (mode != FL_WRITING || !cfip || !(cfip->SuspendCmdSupport&1))) in chip_ready()
920 chip->oldstate = chip->state; in chip_ready()
921 chip->state = FL_READY; in chip_ready()
926 return -EIO; in chip_ready()
929 if (mode == FL_READY && chip->oldstate == FL_READY) in chip_ready()
935 add_wait_queue(&chip->wq, &wait); in chip_ready()
936 mutex_unlock(&chip->mutex); in chip_ready()
938 remove_wait_queue(&chip->wq, &wait); in chip_ready()
939 mutex_lock(&chip->mutex); in chip_ready()
940 return -EAGAIN; in chip_ready()
944 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) in get_chip() argument
950 if (chip->priv && in get_chip()
951 (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE in get_chip()
952 || mode == FL_SHUTDOWN) && chip->state != FL_SYNCING) { in get_chip()
961 * - any write operation must own shared->writing. in get_chip()
963 * - any erase operation must own _both_ shared->writing and in get_chip()
964 * shared->erasing. in get_chip()
966 * - contention arbitration is handled in the owner's context. in get_chip()
971 struct flchip_shared *shared = chip->priv; in get_chip()
973 mutex_lock(&shared->lock); in get_chip()
974 contender = shared->writing; in get_chip()
985 ret = mutex_trylock(&contender->mutex); in get_chip()
986 mutex_unlock(&shared->lock); in get_chip()
989 mutex_unlock(&chip->mutex); in get_chip()
990 ret = chip_ready(map, contender, contender->start, mode); in get_chip()
991 mutex_lock(&chip->mutex); in get_chip()
993 if (ret == -EAGAIN) { in get_chip()
994 mutex_unlock(&contender->mutex); in get_chip()
998 mutex_unlock(&contender->mutex); in get_chip()
1001 mutex_lock(&shared->lock); in get_chip()
1005 if (chip->state == FL_SYNCING) { in get_chip()
1006 put_chip(map, contender, contender->start); in get_chip()
1007 mutex_unlock(&contender->mutex); in get_chip()
1010 mutex_unlock(&contender->mutex); in get_chip()
1015 if (mode == FL_ERASING && shared->erasing in get_chip()
1016 && shared->erasing->oldstate == FL_ERASING) { in get_chip()
1017 mutex_unlock(&shared->lock); in get_chip()
1019 add_wait_queue(&chip->wq, &wait); in get_chip()
1020 mutex_unlock(&chip->mutex); in get_chip()
1022 remove_wait_queue(&chip->wq, &wait); in get_chip()
1023 mutex_lock(&chip->mutex); in get_chip()
1028 shared->writing = chip; in get_chip()
1029 if (mode == FL_ERASING) in get_chip()
1030 shared->erasing = chip; in get_chip()
1031 mutex_unlock(&shared->lock); in get_chip()
1033 ret = chip_ready(map, chip, adr, mode); in get_chip()
1034 if (ret == -EAGAIN) in get_chip()
1042 struct cfi_private *cfi = map->fldrv_priv; in put_chip()
1044 if (chip->priv) { in put_chip()
1045 struct flchip_shared *shared = chip->priv; in put_chip()
1046 mutex_lock(&shared->lock); in put_chip()
1047 if (shared->writing == chip && chip->oldstate == FL_READY) { in put_chip()
1049 shared->writing = shared->erasing; in put_chip()
1050 if (shared->writing && shared->writing != chip) { in put_chip()
1052 struct flchip *loaner = shared->writing; in put_chip()
1053 mutex_lock(&loaner->mutex); in put_chip()
1054 mutex_unlock(&shared->lock); in put_chip()
1055 mutex_unlock(&chip->mutex); in put_chip()
1056 put_chip(map, loaner, loaner->start); in put_chip()
1057 mutex_lock(&chip->mutex); in put_chip()
1058 mutex_unlock(&loaner->mutex); in put_chip()
1059 wake_up(&chip->wq); in put_chip()
1062 shared->erasing = NULL; in put_chip()
1063 shared->writing = NULL; in put_chip()
1064 } else if (shared->erasing == chip && shared->writing != chip) { in put_chip()
1072 mutex_unlock(&shared->lock); in put_chip()
1073 wake_up(&chip->wq); in put_chip()
1076 mutex_unlock(&shared->lock); in put_chip()
1079 switch(chip->oldstate) { in put_chip()
1083 one in READY mode. That's bad, and caused -EROFS in put_chip()
1090 map_write(map, CMD(0xd0), chip->in_progress_block_addr); in put_chip()
1091 map_write(map, CMD(0x70), chip->in_progress_block_addr); in put_chip()
1092 chip->oldstate = FL_READY; in put_chip()
1093 chip->state = FL_ERASING; in put_chip()
1097 chip->state = chip->oldstate; in put_chip()
1098 chip->oldstate = FL_READY; in put_chip()
1106 printk(KERN_ERR "%s: put_chip() called with oldstate %d!!\n", map->name, chip->oldstate); in put_chip()
1108 wake_up(&chip->wq); in put_chip()
1115 * mode. This is ensured by the xip_disable() and xip_enable() functions
1116 * enclosing any code path where the flash is known not to be in array mode.
1121 * support to a single buswidth and a single interleave is also recommended.
1135 struct cfi_private *cfi = map->fldrv_priv; in xip_enable()
1136 if (chip->state != FL_POINT && chip->state != FL_READY) { in xip_enable()
1138 chip->state = FL_READY; in xip_enable()
1150 * array mode restored and interrupts unmasked. Task scheduling might also
1162 struct cfi_private *cfi = map->fldrv_priv; in xip_wait_for_operation()
1163 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; in xip_wait_for_operation()
1177 ((chip->state == FL_ERASING && (cfip->FeatureSupport&2)) || in xip_wait_for_operation()
1178 (chip->state == FL_WRITING && (cfip->FeatureSupport&4))) && in xip_wait_for_operation()
1179 (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) { in xip_wait_for_operation()
1190 usec -= done; in xip_wait_for_operation()
1202 return -EIO; in xip_wait_for_operation()
1208 oldstate = chip->state; in xip_wait_for_operation()
1213 chip->erase_suspended = 1; in xip_wait_for_operation()
1218 chip->write_suspended = 1; in xip_wait_for_operation()
1220 chip->state = newstate; in xip_wait_for_operation()
1225 mutex_unlock(&chip->mutex); in xip_wait_for_operation()
1235 mutex_lock(&chip->mutex); in xip_wait_for_operation()
1236 while (chip->state != newstate) { in xip_wait_for_operation()
1239 add_wait_queue(&chip->wq, &wait); in xip_wait_for_operation()
1240 mutex_unlock(&chip->mutex); in xip_wait_for_operation()
1242 remove_wait_queue(&chip->wq, &wait); in xip_wait_for_operation()
1243 mutex_lock(&chip->mutex); in xip_wait_for_operation()
1251 chip->state = oldstate; in xip_wait_for_operation()
1266 return (done >= usec) ? -ETIME : 0; in xip_wait_for_operation()
1294 struct cfi_private *cfi = map->fldrv_priv; in inval_cache_and_wait_for_operation()
1296 int chip_state = chip->state; in inval_cache_and_wait_for_operation()
1299 mutex_unlock(&chip->mutex); in inval_cache_and_wait_for_operation()
1302 mutex_lock(&chip->mutex); in inval_cache_and_wait_for_operation()
1311 if (chip->state != chip_state) { in inval_cache_and_wait_for_operation()
1315 add_wait_queue(&chip->wq, &wait); in inval_cache_and_wait_for_operation()
1316 mutex_unlock(&chip->mutex); in inval_cache_and_wait_for_operation()
1318 remove_wait_queue(&chip->wq, &wait); in inval_cache_and_wait_for_operation()
1319 mutex_lock(&chip->mutex); in inval_cache_and_wait_for_operation()
1327 if (chip->erase_suspended && chip_state == FL_ERASING) { in inval_cache_and_wait_for_operation()
1330 chip->erase_suspended = 0; in inval_cache_and_wait_for_operation()
1332 if (chip->write_suspended && chip_state == FL_WRITING) { in inval_cache_and_wait_for_operation()
1335 chip->write_suspended = 0; in inval_cache_and_wait_for_operation()
1339 chip->state = FL_STATUS; in inval_cache_and_wait_for_operation()
1340 return -ETIME; in inval_cache_and_wait_for_operation()
1344 mutex_unlock(&chip->mutex); in inval_cache_and_wait_for_operation()
1352 timeo -= sleep_time; in inval_cache_and_wait_for_operation()
1357 timeo--; in inval_cache_and_wait_for_operation()
1359 mutex_lock(&chip->mutex); in inval_cache_and_wait_for_operation()
1363 chip->state = FL_STATUS; in inval_cache_and_wait_for_operation()
1376 struct cfi_private *cfi = map->fldrv_priv; in do_point_onechip()
1379 adr += chip->start; in do_point_onechip()
1382 cmd_addr = adr & ~(map_bankwidth(map)-1); in do_point_onechip()
1384 mutex_lock(&chip->mutex); in do_point_onechip()
1389 if (chip->state != FL_POINT && chip->state != FL_READY) in do_point_onechip()
1392 chip->state = FL_POINT; in do_point_onechip()
1393 chip->ref_point_counter++; in do_point_onechip()
1395 mutex_unlock(&chip->mutex); in do_point_onechip()
1403 struct map_info *map = mtd->priv; in cfi_intelext_point()
1404 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_point()
1409 if (!map->virt) in cfi_intelext_point()
1410 return -EINVAL; in cfi_intelext_point()
1415 chipnum = (from >> cfi->chipshift); in cfi_intelext_point()
1416 ofs = from - (chipnum << cfi->chipshift); in cfi_intelext_point()
1418 *virt = map->virt + cfi->chips[chipnum].start + ofs; in cfi_intelext_point()
1420 *phys = map->phys + cfi->chips[chipnum].start + ofs; in cfi_intelext_point()
1425 if (chipnum >= cfi->numchips) in cfi_intelext_point()
1430 last_end = cfi->chips[chipnum].start; in cfi_intelext_point()
1431 else if (cfi->chips[chipnum].start != last_end) in cfi_intelext_point()
1434 if ((len + ofs -1) >> cfi->chipshift) in cfi_intelext_point()
1435 thislen = (1<<cfi->chipshift) - ofs; in cfi_intelext_point()
1439 ret = do_point_onechip(map, &cfi->chips[chipnum], ofs, thislen); in cfi_intelext_point()
1444 len -= thislen; in cfi_intelext_point()
1447 last_end += 1 << cfi->chipshift; in cfi_intelext_point()
1455 struct map_info *map = mtd->priv; in cfi_intelext_unpoint()
1456 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_unpoint()
1463 chipnum = (from >> cfi->chipshift); in cfi_intelext_unpoint()
1464 ofs = from - (chipnum << cfi->chipshift); in cfi_intelext_unpoint()
1470 chip = &cfi->chips[chipnum]; in cfi_intelext_unpoint()
1471 if (chipnum >= cfi->numchips) in cfi_intelext_unpoint()
1474 if ((len + ofs -1) >> cfi->chipshift) in cfi_intelext_unpoint()
1475 thislen = (1<<cfi->chipshift) - ofs; in cfi_intelext_unpoint()
1479 mutex_lock(&chip->mutex); in cfi_intelext_unpoint()
1480 if (chip->state == FL_POINT) { in cfi_intelext_unpoint()
1481 chip->ref_point_counter--; in cfi_intelext_unpoint()
1482 if(chip->ref_point_counter == 0) in cfi_intelext_unpoint()
1483 chip->state = FL_READY; in cfi_intelext_unpoint()
1485 printk(KERN_ERR "%s: Error: unpoint called on non pointed region\n", map->name); in cfi_intelext_unpoint()
1486 err = -EINVAL; in cfi_intelext_unpoint()
1489 put_chip(map, chip, chip->start); in cfi_intelext_unpoint()
1490 mutex_unlock(&chip->mutex); in cfi_intelext_unpoint()
1492 len -= thislen; in cfi_intelext_unpoint()
1503 struct cfi_private *cfi = map->fldrv_priv; in do_read_onechip()
1506 adr += chip->start; in do_read_onechip()
1509 cmd_addr = adr & ~(map_bankwidth(map)-1); in do_read_onechip()
1511 mutex_lock(&chip->mutex); in do_read_onechip()
1514 mutex_unlock(&chip->mutex); in do_read_onechip()
1518 if (chip->state != FL_POINT && chip->state != FL_READY) { in do_read_onechip()
1521 chip->state = FL_READY; in do_read_onechip()
1528 mutex_unlock(&chip->mutex); in do_read_onechip()
1534 struct map_info *map = mtd->priv; in cfi_intelext_read()
1535 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_read()
1541 chipnum = (from >> cfi->chipshift); in cfi_intelext_read()
1542 ofs = from - (chipnum << cfi->chipshift); in cfi_intelext_read()
1547 if (chipnum >= cfi->numchips) in cfi_intelext_read()
1550 if ((len + ofs -1) >> cfi->chipshift) in cfi_intelext_read()
1551 thislen = (1<<cfi->chipshift) - ofs; in cfi_intelext_read()
1555 ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf); in cfi_intelext_read()
1560 len -= thislen; in cfi_intelext_read()
1570 unsigned long adr, map_word datum, int mode) in do_write_oneword() argument
1572 struct cfi_private *cfi = map->fldrv_priv; in do_write_oneword()
1576 adr += chip->start; in do_write_oneword()
1578 switch (mode) { in do_write_oneword()
1580 write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0x40) : CMD(0x41); in do_write_oneword()
1586 return -EINVAL; in do_write_oneword()
1589 mutex_lock(&chip->mutex); in do_write_oneword()
1590 ret = get_chip(map, chip, adr, mode); in do_write_oneword()
1592 mutex_unlock(&chip->mutex); in do_write_oneword()
1601 chip->state = mode; in do_write_oneword()
1605 chip->word_write_time, in do_write_oneword()
1606 chip->word_write_time_max); in do_write_oneword()
1609 printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); in do_write_oneword()
1624 ret = -EROFS; in do_write_oneword()
1626 printk(KERN_ERR "%s: word write error (bad VPP)\n", map->name); in do_write_oneword()
1627 ret = -EIO; in do_write_oneword()
1629 printk(KERN_ERR "%s: word write error (status 0x%lx)\n", map->name, chipstatus); in do_write_oneword()
1630 ret = -EINVAL; in do_write_oneword()
1639 mutex_unlock(&chip->mutex); in do_write_oneword()
1646 struct map_info *map = mtd->priv; in cfi_intelext_write_words()
1647 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_write_words()
1652 chipnum = to >> cfi->chipshift; in cfi_intelext_write_words()
1653 ofs = to - (chipnum << cfi->chipshift); in cfi_intelext_write_words()
1655 /* If it's not bus-aligned, do the first byte write */ in cfi_intelext_write_words()
1656 if (ofs & (map_bankwidth(map)-1)) { in cfi_intelext_write_words()
1657 unsigned long bus_ofs = ofs & ~(map_bankwidth(map)-1); in cfi_intelext_write_words()
1658 int gap = ofs - bus_ofs; in cfi_intelext_write_words()
1662 n = min_t(int, len, map_bankwidth(map)-gap); in cfi_intelext_write_words()
1666 ret = do_write_oneword(map, &cfi->chips[chipnum], in cfi_intelext_write_words()
1671 len -= n; in cfi_intelext_write_words()
1676 if (ofs >> cfi->chipshift) { in cfi_intelext_write_words()
1679 if (chipnum == cfi->numchips) in cfi_intelext_write_words()
1687 ret = do_write_oneword(map, &cfi->chips[chipnum], in cfi_intelext_write_words()
1695 len -= map_bankwidth(map); in cfi_intelext_write_words()
1697 if (ofs >> cfi->chipshift) { in cfi_intelext_write_words()
1700 if (chipnum == cfi->numchips) in cfi_intelext_write_words()
1705 if (len & (map_bankwidth(map)-1)) { in cfi_intelext_write_words()
1711 ret = do_write_oneword(map, &cfi->chips[chipnum], in cfi_intelext_write_words()
1727 struct cfi_private *cfi = map->fldrv_priv; in do_write_buffer()
1736 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; in do_write_buffer()
1737 adr += chip->start; in do_write_buffer()
1739 cmd_adr = adr & ~(wbufsize-1); in do_write_buffer()
1747 /* Let's determine this according to the interleave only once */ in do_write_buffer()
1748 write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0xe8) : CMD(0xe9); in do_write_buffer()
1750 mutex_lock(&chip->mutex); in do_write_buffer()
1753 mutex_unlock(&chip->mutex); in do_write_buffer()
1765 if (chip->state != FL_STATUS) { in do_write_buffer()
1767 chip->state = FL_STATUS; in do_write_buffer()
1778 chip->state = FL_WRITING_TO_BUFFER; in do_write_buffer()
1785 chip->state = FL_STATUS; in do_write_buffer()
1791 map->name, Xstatus.x[0], status.x[0]); in do_write_buffer()
1796 word_gap = (-adr & (map_bankwidth(map)-1)); in do_write_buffer()
1797 words = DIV_ROUND_UP(len - word_gap, map_bankwidth(map)); in do_write_buffer()
1799 words--; in do_write_buffer()
1801 word_gap = map_bankwidth(map) - word_gap; in do_write_buffer()
1802 adr -= word_gap; in do_write_buffer()
1813 int n = map_bankwidth(map) - word_gap; in do_write_buffer()
1814 if (n > vec->iov_len - vec_seek) in do_write_buffer()
1815 n = vec->iov_len - vec_seek; in do_write_buffer()
1823 vec->iov_base + vec_seek, in do_write_buffer()
1826 len -= n; in do_write_buffer()
1835 if (vec_seek == vec->iov_len) { in do_write_buffer()
1845 chip->state = FL_WRITING; in do_write_buffer()
1849 chip->buffer_write_time, in do_write_buffer()
1850 chip->buffer_write_time_max); in do_write_buffer()
1853 chip->state = FL_STATUS; in do_write_buffer()
1855 printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name); in do_write_buffer()
1870 ret = -EROFS; in do_write_buffer()
1872 printk(KERN_ERR "%s: buffer write error (bad VPP)\n", map->name); in do_write_buffer()
1873 ret = -EIO; in do_write_buffer()
1875 printk(KERN_ERR "%s: buffer write error (status 0x%lx)\n", map->name, chipstatus); in do_write_buffer()
1876 ret = -EINVAL; in do_write_buffer()
1885 mutex_unlock(&chip->mutex); in do_write_buffer()
1892 struct map_info *map = mtd->priv; in cfi_intelext_writev()
1893 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_writev()
1894 int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; in cfi_intelext_writev()
1906 chipnum = to >> cfi->chipshift; in cfi_intelext_writev()
1907 ofs = to - (chipnum << cfi->chipshift); in cfi_intelext_writev()
1912 int size = wbufsize - (ofs & (wbufsize-1)); in cfi_intelext_writev()
1916 ret = do_write_buffer(map, &cfi->chips[chipnum], in cfi_intelext_writev()
1923 len -= size; in cfi_intelext_writev()
1925 if (ofs >> cfi->chipshift) { in cfi_intelext_writev()
1928 if (chipnum == cfi->numchips) in cfi_intelext_writev()
1955 struct cfi_private *cfi = map->fldrv_priv; in do_erase_oneblock()
1960 adr += chip->start; in do_erase_oneblock()
1963 mutex_lock(&chip->mutex); in do_erase_oneblock()
1966 mutex_unlock(&chip->mutex); in do_erase_oneblock()
1980 chip->state = FL_ERASING; in do_erase_oneblock()
1981 chip->erase_suspended = 0; in do_erase_oneblock()
1982 chip->in_progress_block_addr = adr; in do_erase_oneblock()
1983 chip->in_progress_block_mask = ~(len - 1); in do_erase_oneblock()
1987 chip->erase_time, in do_erase_oneblock()
1988 chip->erase_time_max); in do_erase_oneblock()
1991 chip->state = FL_STATUS; in do_erase_oneblock()
1993 printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name); in do_erase_oneblock()
1999 chip->state = FL_STATUS; in do_erase_oneblock()
2012 …printk(KERN_ERR "%s: block erase error: (bad command sequence, status 0x%lx)\n", map->name, chipst… in do_erase_oneblock()
2013 ret = -EINVAL; in do_erase_oneblock()
2016 ret = -EROFS; in do_erase_oneblock()
2019 printk(KERN_ERR "%s: block erase error: (bad VPP)\n", map->name); in do_erase_oneblock()
2020 ret = -EIO; in do_erase_oneblock()
2021 } else if (chipstatus & 0x20 && retries--) { in do_erase_oneblock()
2025 mutex_unlock(&chip->mutex); in do_erase_oneblock()
2028 … printk(KERN_ERR "%s: block erase failed at 0x%08lx (status 0x%lx)\n", map->name, adr, chipstatus); in do_erase_oneblock()
2029 ret = -EIO; in do_erase_oneblock()
2038 mutex_unlock(&chip->mutex); in do_erase_oneblock()
2044 return cfi_varsize_frob(mtd, do_erase_oneblock, instr->addr, in cfi_intelext_erase_varsize()
2045 instr->len, NULL); in cfi_intelext_erase_varsize()
2050 struct map_info *map = mtd->priv; in cfi_intelext_sync()
2051 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_sync()
2056 for (i=0; !ret && i<cfi->numchips; i++) { in cfi_intelext_sync()
2057 chip = &cfi->chips[i]; in cfi_intelext_sync()
2059 mutex_lock(&chip->mutex); in cfi_intelext_sync()
2060 ret = get_chip(map, chip, chip->start, FL_SYNCING); in cfi_intelext_sync()
2063 chip->oldstate = chip->state; in cfi_intelext_sync()
2064 chip->state = FL_SYNCING; in cfi_intelext_sync()
2065 /* No need to wake_up() on this state change - in cfi_intelext_sync()
2070 mutex_unlock(&chip->mutex); in cfi_intelext_sync()
2075 for (i--; i >=0; i--) { in cfi_intelext_sync()
2076 chip = &cfi->chips[i]; in cfi_intelext_sync()
2078 mutex_lock(&chip->mutex); in cfi_intelext_sync()
2080 if (chip->state == FL_SYNCING) { in cfi_intelext_sync()
2081 chip->state = chip->oldstate; in cfi_intelext_sync()
2082 chip->oldstate = FL_READY; in cfi_intelext_sync()
2083 wake_up(&chip->wq); in cfi_intelext_sync()
2085 mutex_unlock(&chip->mutex); in cfi_intelext_sync()
2094 struct cfi_private *cfi = map->fldrv_priv; in do_getlockstatus_oneblock()
2095 int status, ofs_factor = cfi->interleave * cfi->device_type; in do_getlockstatus_oneblock()
2097 adr += chip->start; in do_getlockstatus_oneblock()
2100 chip->state = FL_JEDEC_QUERY; in do_getlockstatus_oneblock()
2124 struct cfi_private *cfi = map->fldrv_priv; in do_xxlock_oneblock()
2125 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in do_xxlock_oneblock()
2129 adr += chip->start; in do_xxlock_oneblock()
2131 mutex_lock(&chip->mutex); in do_xxlock_oneblock()
2134 mutex_unlock(&chip->mutex); in do_xxlock_oneblock()
2144 chip->state = FL_LOCKING; in do_xxlock_oneblock()
2147 chip->state = FL_UNLOCKING; in do_xxlock_oneblock()
2159 * See "Clear Block Lock-Bits Time" on page 40 in in do_xxlock_oneblock()
2163 mdelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1500 : 0; in do_xxlock_oneblock()
2168 chip->state = FL_STATUS; in do_xxlock_oneblock()
2170 printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name); in do_xxlock_oneblock()
2177 mutex_unlock(&chip->mutex); in do_xxlock_oneblock()
2246 struct cfi_private *cfi = map->fldrv_priv; in do_otp_read()
2249 mutex_lock(&chip->mutex); in do_otp_read()
2250 ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY); in do_otp_read()
2252 mutex_unlock(&chip->mutex); in do_otp_read()
2256 /* let's ensure we're not reading back cached data from array mode */ in do_otp_read()
2257 INVALIDATE_CACHED_RANGE(map, chip->start + offset, size); in do_otp_read()
2259 xip_disable(map, chip, chip->start); in do_otp_read()
2260 if (chip->state != FL_JEDEC_QUERY) { in do_otp_read()
2261 map_write(map, CMD(0x90), chip->start); in do_otp_read()
2262 chip->state = FL_JEDEC_QUERY; in do_otp_read()
2264 map_copy_from(map, buf, chip->start + offset, size); in do_otp_read()
2265 xip_enable(map, chip, chip->start); in do_otp_read()
2268 INVALIDATE_CACHED_RANGE(map, chip->start + offset, size); in do_otp_read()
2270 put_chip(map, chip, chip->start); in do_otp_read()
2271 mutex_unlock(&chip->mutex); in do_otp_read()
2282 unsigned long bus_ofs = offset & ~(map_bankwidth(map)-1); in do_otp_write()
2283 int gap = offset - bus_ofs; in do_otp_write()
2284 int n = min_t(int, size, map_bankwidth(map)-gap); in do_otp_write()
2294 size -= n; in do_otp_write()
2304 struct cfi_private *cfi = map->fldrv_priv; in do_otp_lock()
2309 return -EXDEV; in do_otp_lock()
2320 struct map_info *map = mtd->priv; in cfi_intelext_otp_walk()
2321 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_otp_walk()
2322 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in cfi_intelext_otp_walk()
2333 if (!extp || !(extp->FeatureSupport & 64) || !extp->NumProtectionFields) in cfi_intelext_otp_walk()
2334 return -ENODATA; in cfi_intelext_otp_walk()
2337 devsize = (1 << cfi->cfiq->DevSize) * cfi->interleave; in cfi_intelext_otp_walk()
2338 chip_step = devsize >> cfi->chipshift; in cfi_intelext_otp_walk()
2342 For example: Intel 28F256L18T (T means top-parameter device) */ in cfi_intelext_otp_walk()
2343 if (cfi->mfr == CFI_MFR_INTEL) { in cfi_intelext_otp_walk()
2344 switch (cfi->id) { in cfi_intelext_otp_walk()
2348 chip_num = chip_step - 1; in cfi_intelext_otp_walk()
2352 for ( ; chip_num < cfi->numchips; chip_num += chip_step) { in cfi_intelext_otp_walk()
2353 chip = &cfi->chips[chip_num]; in cfi_intelext_otp_walk()
2354 otp = (struct cfi_intelext_otpinfo *)&extp->extra[0]; in cfi_intelext_otp_walk()
2358 reg_prot_offset = extp->ProtRegAddr; in cfi_intelext_otp_walk()
2360 reg_fact_size = 1 << extp->FactProtRegSize; in cfi_intelext_otp_walk()
2362 reg_user_size = 1 << extp->UserProtRegSize; in cfi_intelext_otp_walk()
2367 data_offset *= cfi->interleave * cfi->device_type; in cfi_intelext_otp_walk()
2368 reg_prot_offset *= cfi->interleave * cfi->device_type; in cfi_intelext_otp_walk()
2369 reg_fact_size *= cfi->interleave; in cfi_intelext_otp_walk()
2370 reg_user_size *= cfi->interleave; in cfi_intelext_otp_walk()
2392 len -= sizeof(struct otp_info); in cfi_intelext_otp_walk()
2394 return -ENOSPC; in cfi_intelext_otp_walk()
2403 otpinfo->start = from; in cfi_intelext_otp_walk()
2404 otpinfo->length = groupsize; in cfi_intelext_otp_walk()
2405 otpinfo->locked = in cfi_intelext_otp_walk()
2412 from -= groupsize; in cfi_intelext_otp_walk()
2417 size -= from; in cfi_intelext_otp_walk()
2427 len -= size; in cfi_intelext_otp_walk()
2432 groups--; in cfi_intelext_otp_walk()
2436 if (++field == extp->NumProtectionFields) in cfi_intelext_otp_walk()
2438 reg_prot_offset = otp->ProtRegAddr; in cfi_intelext_otp_walk()
2439 reg_fact_groups = otp->FactGroups; in cfi_intelext_otp_walk()
2440 reg_fact_size = 1 << otp->FactProtRegSize; in cfi_intelext_otp_walk()
2441 reg_user_groups = otp->UserGroups; in cfi_intelext_otp_walk()
2442 reg_user_size = 1 << otp->UserProtRegSize; in cfi_intelext_otp_walk()
2506 for (i = 0; i < mtd->numeraseregions; i++) { in cfi_intelext_save_locks()
2507 region = &mtd->eraseregions[i]; in cfi_intelext_save_locks()
2508 if (!region->lockmap) in cfi_intelext_save_locks()
2511 for (block = 0; block < region->numblocks; block++){ in cfi_intelext_save_locks()
2512 len = region->erasesize; in cfi_intelext_save_locks()
2513 adr = region->offset + block * len; in cfi_intelext_save_locks()
2518 set_bit(block, region->lockmap); in cfi_intelext_save_locks()
2520 clear_bit(block, region->lockmap); in cfi_intelext_save_locks()
2527 struct map_info *map = mtd->priv; in cfi_intelext_suspend()
2528 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_suspend()
2529 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in cfi_intelext_suspend()
2534 if ((mtd->flags & MTD_POWERUP_LOCK) in cfi_intelext_suspend()
2535 && extp && (extp->FeatureSupport & (1 << 5))) in cfi_intelext_suspend()
2538 for (i=0; !ret && i<cfi->numchips; i++) { in cfi_intelext_suspend()
2539 chip = &cfi->chips[i]; in cfi_intelext_suspend()
2541 mutex_lock(&chip->mutex); in cfi_intelext_suspend()
2543 switch (chip->state) { in cfi_intelext_suspend()
2548 if (chip->oldstate == FL_READY) { in cfi_intelext_suspend()
2550 map_write(map, CMD(0xFF), cfi->chips[i].start); in cfi_intelext_suspend()
2551 chip->oldstate = chip->state; in cfi_intelext_suspend()
2552 chip->state = FL_PM_SUSPENDED; in cfi_intelext_suspend()
2553 /* No need to wake_up() on this state change - in cfi_intelext_suspend()
2559 …RN_NOTICE "Flash device refused suspend due to pending operation (oldstate %d)\n", chip->oldstate); in cfi_intelext_suspend()
2560 ret = -EAGAIN; in cfi_intelext_suspend()
2565 allowed to. Or should we return -EAGAIN, because the upper layers in cfi_intelext_suspend()
2568 …printk(KERN_NOTICE "Flash device refused suspend due to active operation (state %d)\n", chip->stat… in cfi_intelext_suspend()
2569 ret = -EAGAIN; in cfi_intelext_suspend()
2574 mutex_unlock(&chip->mutex); in cfi_intelext_suspend()
2580 for (i--; i >=0; i--) { in cfi_intelext_suspend()
2581 chip = &cfi->chips[i]; in cfi_intelext_suspend()
2583 mutex_lock(&chip->mutex); in cfi_intelext_suspend()
2585 if (chip->state == FL_PM_SUSPENDED) { in cfi_intelext_suspend()
2589 chip->state = chip->oldstate; in cfi_intelext_suspend()
2590 chip->oldstate = FL_READY; in cfi_intelext_suspend()
2591 wake_up(&chip->wq); in cfi_intelext_suspend()
2593 mutex_unlock(&chip->mutex); in cfi_intelext_suspend()
2607 for (i = 0; i < mtd->numeraseregions; i++) { in cfi_intelext_restore_locks()
2608 region = &mtd->eraseregions[i]; in cfi_intelext_restore_locks()
2609 if (!region->lockmap) in cfi_intelext_restore_locks()
2612 for_each_clear_bit(block, region->lockmap, region->numblocks) { in cfi_intelext_restore_locks()
2613 len = region->erasesize; in cfi_intelext_restore_locks()
2614 adr = region->offset + block * len; in cfi_intelext_restore_locks()
2622 struct map_info *map = mtd->priv; in cfi_intelext_resume()
2623 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_resume()
2624 struct cfi_pri_intelext *extp = cfi->cmdset_priv; in cfi_intelext_resume()
2628 for (i=0; i<cfi->numchips; i++) { in cfi_intelext_resume()
2630 chip = &cfi->chips[i]; in cfi_intelext_resume()
2632 mutex_lock(&chip->mutex); in cfi_intelext_resume()
2635 if (chip->state == FL_PM_SUSPENDED) { in cfi_intelext_resume()
2638 map_write(map, CMD(0xFF), cfi->chips[i].start); in cfi_intelext_resume()
2639 chip->oldstate = chip->state = FL_READY; in cfi_intelext_resume()
2640 wake_up(&chip->wq); in cfi_intelext_resume()
2643 mutex_unlock(&chip->mutex); in cfi_intelext_resume()
2646 if ((mtd->flags & MTD_POWERUP_LOCK) in cfi_intelext_resume()
2647 && extp && (extp->FeatureSupport & (1 << 5))) in cfi_intelext_resume()
2653 struct map_info *map = mtd->priv; in cfi_intelext_reset()
2654 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_reset()
2657 for (i=0; i < cfi->numchips; i++) { in cfi_intelext_reset()
2658 struct flchip *chip = &cfi->chips[i]; in cfi_intelext_reset()
2661 and switch to array mode so any bootloader in in cfi_intelext_reset()
2663 mutex_lock(&chip->mutex); in cfi_intelext_reset()
2664 ret = get_chip(map, chip, chip->start, FL_SHUTDOWN); in cfi_intelext_reset()
2666 map_write(map, CMD(0xff), chip->start); in cfi_intelext_reset()
2667 chip->state = FL_SHUTDOWN; in cfi_intelext_reset()
2668 put_chip(map, chip, chip->start); in cfi_intelext_reset()
2670 mutex_unlock(&chip->mutex); in cfi_intelext_reset()
2688 struct map_info *map = mtd->priv; in cfi_intelext_destroy()
2689 struct cfi_private *cfi = map->fldrv_priv; in cfi_intelext_destroy()
2693 unregister_reboot_notifier(&mtd->reboot_notifier); in cfi_intelext_destroy()
2694 kfree(cfi->cmdset_priv); in cfi_intelext_destroy()
2695 kfree(cfi->cfiq); in cfi_intelext_destroy()
2696 kfree(cfi->chips[0].priv); in cfi_intelext_destroy()
2698 for (i = 0; i < mtd->numeraseregions; i++) { in cfi_intelext_destroy()
2699 region = &mtd->eraseregions[i]; in cfi_intelext_destroy()
2700 kfree(region->lockmap); in cfi_intelext_destroy()
2702 kfree(mtd->eraseregions); in cfi_intelext_destroy()