static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private **);
static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char **mtdbuf);
-static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
- size_t len);
+ size_t *retlen, void **virt, resource_size_t *phys);
+static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
/*
* Some chips power-up with all sectors locked by default.
*/
-static void fixup_use_powerup_lock(struct mtd_info *mtd, void *param)
+static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param)
{
- printk(KERN_INFO "Using auto-unlock on power-up/resume\n" );
- mtd->flags |= MTD_STUPID_LOCK;
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
+
+ if (cfip->FeatureSupport&32) {
+ printk(KERN_INFO "Using auto-unlock on power-up/resume\n" );
+ mtd->flags |= MTD_POWERUP_LOCK;
+ }
}
static struct cfi_fixup cfi_fixup_table[] = {
#endif
{ CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL },
{ CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL },
- { MANUFACTURER_INTEL, 0x891c, fixup_use_powerup_lock, NULL, },
+ { MANUFACTURER_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, },
{ 0, 0, NULL, NULL }
};
if (extp_size > 4096) {
printk(KERN_ERR
"%s: cfi_pri_intelext is too fat\n",
- __FUNCTION__);
+ __func__);
return NULL;
}
goto again;
sizeof(struct cfi_intelext_blockinfo);
}
+ if (!numparts)
+ numparts = 1;
+
/* Programming Region info */
if (extp->MinorVersion >= '4') {
struct cfi_intelext_programming_regioninfo *prinfo;
if ((1 << partshift) < mtd->erasesize) {
printk( KERN_ERR
"%s: bad number of hw partitions (%d)\n",
- __FUNCTION__, numparts);
+ __func__, numparts);
return -EINVAL;
}
/* Someone else might have been playing with it. */
return -EAGAIN;
}
-
+ /* Fall through */
case FL_READY:
case FL_CFI_QUERY:
case FL_JEDEC_QUERY:
chip->state = FL_READY;
return 0;
+ case FL_SHUTDOWN:
+ /* The machine is rebooting now,so no one can get chip anymore */
+ return -EIO;
case FL_POINT:
/* Only if there's no operation suspended... */
if (mode == FL_READY && chip->oldstate == FL_READY)
return 0;
-
- case FL_SHUTDOWN:
- /* The machine is rebooting now,so no one can get chip anymore */
- return -EIO;
+ /* Fall through */
default:
sleep:
set_current_state(TASK_UNINTERRUPTIBLE);
chip->state = newstate;
map_write(map, CMD(0xff), adr);
(void) map_read(map, adr);
- asm volatile (".rep 8; nop; .endr");
+ xip_iprefetch();
local_irq_enable();
spin_unlock(chip->mutex);
- asm volatile (".rep 8; nop; .endr");
+ xip_iprefetch();
cond_resched();
/*
return ret;
}
-static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
+static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, void **virt, resource_size_t *phys)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
chipnum = (from >> cfi->chipshift);
ofs = from - (chipnum << cfi->chipshift);
- *mtdbuf = (void *)map->virt + cfi->chips[chipnum].start + ofs;
+ *virt = map->virt + cfi->chips[chipnum].start + ofs;
*retlen = 0;
+ if (phys)
+ *phys = map->phys + cfi->chips[chipnum].start + ofs;
while (len) {
unsigned long thislen;
return 0;
}
-static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
int ret, wbufsize, word_gap, words;
const struct kvec *vec;
unsigned long vec_seek;
+ unsigned long initial_adr;
+ int initial_len = len;
wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
adr += chip->start;
+ initial_adr = adr;
cmd_adr = adr & ~(wbufsize-1);
/* Let's determine this according to the interleave only once */
return ret;
}
- XIP_INVAL_CACHED_RANGE(map, adr, len);
+ XIP_INVAL_CACHED_RANGE(map, initial_adr, initial_len);
ENABLE_VPP(map);
xip_disable(map, chip, cmd_adr);
chip->state = FL_WRITING;
ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
- adr, len,
+ initial_adr, initial_len,
chip->buffer_write_time);
if (ret) {
map_write(map, CMD(0x70), cmd_adr);
#ifdef DEBUG_LOCK_BITS
printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
- __FUNCTION__, ofs, len);
+ __func__, ofs, len);
cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
ofs, len, NULL);
#endif
#ifdef DEBUG_LOCK_BITS
printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
- __FUNCTION__, ret);
+ __func__, ret);
cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
ofs, len, NULL);
#endif
#ifdef DEBUG_LOCK_BITS
printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
- __FUNCTION__, ofs, len);
+ __func__, ofs, len);
cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
ofs, len, NULL);
#endif
#ifdef DEBUG_LOCK_BITS
printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
- __FUNCTION__, ret);
+ __func__, ret);
cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
ofs, len, NULL);
#endif
struct flchip *chip;
int ret = 0;
- if ((mtd->flags & MTD_STUPID_LOCK)
+ if ((mtd->flags & MTD_POWERUP_LOCK)
&& extp && (extp->FeatureSupport & (1 << 5)))
cfi_intelext_save_locks(mtd);
spin_unlock(chip->mutex);
}
- if ((mtd->flags & MTD_STUPID_LOCK)
+ if ((mtd->flags & MTD_POWERUP_LOCK)
&& extp && (extp->FeatureSupport & (1 << 5)))
cfi_intelext_restore_locks(mtd);
}