aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/chips/cfi_cmdset_0001.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/chips/cfi_cmdset_0001.c')
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 2f19fa78d24a..3aa3dca56ae6 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -526,7 +526,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
526 struct cfi_pri_intelext *extp = cfi->cmdset_priv; 526 struct cfi_pri_intelext *extp = cfi->cmdset_priv;
527 527
528 /* 528 /*
529 * Probing of multi-partition flash ships. 529 * Probing of multi-partition flash chips.
530 * 530 *
531 * To support multiple partitions when available, we simply arrange 531 * To support multiple partitions when available, we simply arrange
532 * for each of them to have their own flchip structure even if they 532 * for each of them to have their own flchip structure even if they
@@ -653,7 +653,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
653 resettime: 653 resettime:
654 timeo = jiffies + HZ; 654 timeo = jiffies + HZ;
655 retry: 655 retry:
656 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE)) { 656 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
657 /* 657 /*
658 * OK. We have possibility for contension on the write/erase 658 * OK. We have possibility for contension on the write/erase
659 * operations which are global to the real chip and not per 659 * operations which are global to the real chip and not per
@@ -798,6 +798,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
798 if (mode == FL_READY && chip->oldstate == FL_READY) 798 if (mode == FL_READY && chip->oldstate == FL_READY)
799 return 0; 799 return 0;
800 800
801 case FL_SHUTDOWN:
802 /* The machine is rebooting now,so no one can get chip anymore */
803 return -EIO;
801 default: 804 default:
802 sleep: 805 sleep:
803 set_current_state(TASK_UNINTERRUPTIBLE); 806 set_current_state(TASK_UNINTERRUPTIBLE);
@@ -1166,28 +1169,34 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
1166{ 1169{
1167 struct map_info *map = mtd->priv; 1170 struct map_info *map = mtd->priv;
1168 struct cfi_private *cfi = map->fldrv_priv; 1171 struct cfi_private *cfi = map->fldrv_priv;
1169 unsigned long ofs; 1172 unsigned long ofs, last_end = 0;
1170 int chipnum; 1173 int chipnum;
1171 int ret = 0; 1174 int ret = 0;
1172 1175
1173 if (!map->virt || (from + len > mtd->size)) 1176 if (!map->virt || (from + len > mtd->size))
1174 return -EINVAL; 1177 return -EINVAL;
1175 1178
1176 *mtdbuf = (void *)map->virt + from;
1177 *retlen = 0;
1178
1179 /* Now lock the chip(s) to POINT state */ 1179 /* Now lock the chip(s) to POINT state */
1180 1180
1181 /* ofs: offset within the first chip that the first read should start */ 1181 /* ofs: offset within the first chip that the first read should start */
1182 chipnum = (from >> cfi->chipshift); 1182 chipnum = (from >> cfi->chipshift);
1183 ofs = from - (chipnum << cfi->chipshift); 1183 ofs = from - (chipnum << cfi->chipshift);
1184 1184
1185 *mtdbuf = (void *)map->virt + cfi->chips[chipnum].start + ofs;
1186 *retlen = 0;
1187
1185 while (len) { 1188 while (len) {
1186 unsigned long thislen; 1189 unsigned long thislen;
1187 1190
1188 if (chipnum >= cfi->numchips) 1191 if (chipnum >= cfi->numchips)
1189 break; 1192 break;
1190 1193
1194 /* We cannot point across chips that are virtually disjoint */
1195 if (!last_end)
1196 last_end = cfi->chips[chipnum].start;
1197 else if (cfi->chips[chipnum].start != last_end)
1198 break;
1199
1191 if ((len + ofs -1) >> cfi->chipshift) 1200 if ((len + ofs -1) >> cfi->chipshift)
1192 thislen = (1<<cfi->chipshift) - ofs; 1201 thislen = (1<<cfi->chipshift) - ofs;
1193 else 1202 else
@@ -1201,6 +1210,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
1201 len -= thislen; 1210 len -= thislen;
1202 1211
1203 ofs = 0; 1212 ofs = 0;
1213 last_end += 1 << cfi->chipshift;
1204 chipnum++; 1214 chipnum++;
1205 } 1215 }
1206 return 0; 1216 return 0;
@@ -1780,7 +1790,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1780 return ret; 1790 return ret;
1781} 1791}
1782 1792
1783int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) 1793static int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1784{ 1794{
1785 unsigned long ofs, len; 1795 unsigned long ofs, len;
1786 int ret; 1796 int ret;
@@ -1930,7 +1940,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1930 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", 1940 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
1931 __FUNCTION__, ofs, len); 1941 __FUNCTION__, ofs, len);
1932 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1942 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1933 ofs, len, 0); 1943 ofs, len, NULL);
1934#endif 1944#endif
1935 1945
1936 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 1946 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
@@ -1940,7 +1950,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1940 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 1950 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1941 __FUNCTION__, ret); 1951 __FUNCTION__, ret);
1942 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1952 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1943 ofs, len, 0); 1953 ofs, len, NULL);
1944#endif 1954#endif
1945 1955
1946 return ret; 1956 return ret;
@@ -1954,7 +1964,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1954 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", 1964 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
1955 __FUNCTION__, ofs, len); 1965 __FUNCTION__, ofs, len);
1956 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1966 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1957 ofs, len, 0); 1967 ofs, len, NULL);
1958#endif 1968#endif
1959 1969
1960 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 1970 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
@@ -1964,7 +1974,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1964 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 1974 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1965 __FUNCTION__, ret); 1975 __FUNCTION__, ret);
1966 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1976 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1967 ofs, len, 0); 1977 ofs, len, NULL);
1968#endif 1978#endif
1969 1979
1970 return ret; 1980 return ret;
@@ -2255,7 +2265,7 @@ static void cfi_intelext_save_locks(struct mtd_info *mtd)
2255 adr = region->offset + block * len; 2265 adr = region->offset + block * len;
2256 2266
2257 status = cfi_varsize_frob(mtd, 2267 status = cfi_varsize_frob(mtd,
2258 do_getlockstatus_oneblock, adr, len, 0); 2268 do_getlockstatus_oneblock, adr, len, NULL);
2259 if (status) 2269 if (status)
2260 set_bit(block, region->lockmap); 2270 set_bit(block, region->lockmap);
2261 else 2271 else
@@ -2402,10 +2412,10 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
2402 and switch to array mode so any bootloader in 2412 and switch to array mode so any bootloader in
2403 flash is accessible for soft reboot. */ 2413 flash is accessible for soft reboot. */
2404 spin_lock(chip->mutex); 2414 spin_lock(chip->mutex);
2405 ret = get_chip(map, chip, chip->start, FL_SYNCING); 2415 ret = get_chip(map, chip, chip->start, FL_SHUTDOWN);
2406 if (!ret) { 2416 if (!ret) {
2407 map_write(map, CMD(0xff), chip->start); 2417 map_write(map, CMD(0xff), chip->start);
2408 chip->state = FL_READY; 2418 chip->state = FL_SHUTDOWN;
2409 } 2419 }
2410 spin_unlock(chip->mutex); 2420 spin_unlock(chip->mutex);
2411 } 2421 }