Commit ab5cfd2a authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.infradead.org/mtd-2.6

* git://git.infradead.org/mtd-2.6:
  [MTD] Use SEEK_{SET,CUR,END} instead of hardcoded values in mtdchar lseek()
  MTD: Fix bug in fixup_convert_atmel_pri
  [JFFS2][SUMMARY] Fix a summary collecting bug.
  [PATCH] [MTD] DEVICES: Fill more device IDs in the structure of m25p80
  MTD: Add lock/unlock operations for Atmel AT49BV6416
  MTD: Convert Atmel PRI information to AMD format
  fs/jffs2/xattr.c: remove dead code
  [PATCH] [MTD] Maps: Add dependency on alternate probe methods to physmap
  [PATCH] MTD: Add Macronix MX29F040 to JEDEC
  [MTD] Fixes of performance and stability issues in CFI driver.
  block2mtd.c: Make kernel boot command line arguments work (try 4)
  [MTD NAND] Fix lookup error in nand_get_flash_type()
  remove #error on !PCI from pmc551.c
  MTD: [NAND] Fix the sharpsl driver after breakage from a core conversion
  [MTD] NAND: OOB buffer offset fixups
  make fs/jffs2/nodelist.c:jffs2_obsolete_node_frag() static
  [PATCH] [MTD] NAND: fix dead URL in Kconfig
parents 833f7329 ea59830d
...@@ -908,7 +908,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip, ...@@ -908,7 +908,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
static int __xipram xip_wait_for_operation( static int __xipram xip_wait_for_operation(
struct map_info *map, struct flchip *chip, struct map_info *map, struct flchip *chip,
unsigned long adr, int *chip_op_time ) unsigned long adr, unsigned int chip_op_time )
{ {
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
struct cfi_pri_intelext *cfip = cfi->cmdset_priv; struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
...@@ -917,7 +917,7 @@ static int __xipram xip_wait_for_operation( ...@@ -917,7 +917,7 @@ static int __xipram xip_wait_for_operation(
flstate_t oldstate, newstate; flstate_t oldstate, newstate;
start = xip_currtime(); start = xip_currtime();
usec = *chip_op_time * 8; usec = chip_op_time * 8;
if (usec == 0) if (usec == 0)
usec = 500000; usec = 500000;
done = 0; done = 0;
...@@ -1027,8 +1027,8 @@ static int __xipram xip_wait_for_operation( ...@@ -1027,8 +1027,8 @@ static int __xipram xip_wait_for_operation(
#define XIP_INVAL_CACHED_RANGE(map, from, size) \ #define XIP_INVAL_CACHED_RANGE(map, from, size) \
INVALIDATE_CACHED_RANGE(map, from, size) INVALIDATE_CACHED_RANGE(map, from, size)
#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, p_usec) \ #define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \
xip_wait_for_operation(map, chip, cmd_adr, p_usec) xip_wait_for_operation(map, chip, cmd_adr, usec)
#else #else
...@@ -1040,64 +1040,64 @@ static int __xipram xip_wait_for_operation( ...@@ -1040,64 +1040,64 @@ static int __xipram xip_wait_for_operation(
static int inval_cache_and_wait_for_operation( static int inval_cache_and_wait_for_operation(
struct map_info *map, struct flchip *chip, struct map_info *map, struct flchip *chip,
unsigned long cmd_adr, unsigned long inval_adr, int inval_len, unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
int *chip_op_time ) unsigned int chip_op_time)
{ {
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
map_word status, status_OK = CMD(0x80); map_word status, status_OK = CMD(0x80);
int z, chip_state = chip->state; int chip_state = chip->state;
unsigned long timeo; unsigned int timeo, sleep_time;
spin_unlock(chip->mutex); spin_unlock(chip->mutex);
if (inval_len) if (inval_len)
INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len); INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
if (*chip_op_time)
cfi_udelay(*chip_op_time);
spin_lock(chip->mutex); spin_lock(chip->mutex);
timeo = *chip_op_time * 8 * HZ / 1000000; /* set our timeout to 8 times the expected delay */
if (timeo < HZ/2) timeo = chip_op_time * 8;
timeo = HZ/2; if (!timeo)
timeo += jiffies; timeo = 500000;
sleep_time = chip_op_time / 2;
z = 0;
for (;;) { for (;;) {
if (chip->state != chip_state) {
/* Someone's suspended the operation: sleep */
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
timeo = jiffies + (HZ / 2); /* FIXME */
spin_lock(chip->mutex);
continue;
}
status = map_read(map, cmd_adr); status = map_read(map, cmd_adr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
/* OK Still waiting */ if (!timeo) {
if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), cmd_adr); map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS; chip->state = FL_STATUS;
return -ETIME; return -ETIME;
} }
/* Latency issues. Drop the lock, wait a while and retry */ /* OK Still waiting. Drop the lock, wait a while and retry. */
z++;
spin_unlock(chip->mutex); spin_unlock(chip->mutex);
cfi_udelay(1); if (sleep_time >= 1000000/HZ) {
spin_lock(chip->mutex); /*
* Half of the normal delay still remaining
* can be performed with a sleeping delay instead
* of busy waiting.
*/
msleep(sleep_time/1000);
timeo -= sleep_time;
sleep_time = 1000000/HZ;
} else {
udelay(1);
cond_resched();
timeo--;
} }
spin_lock(chip->mutex);
if (!z) { if (chip->state != chip_state) {
if (!--(*chip_op_time)) /* Someone's suspended the operation: sleep */
*chip_op_time = 1; DECLARE_WAITQUEUE(wait, current);
} else if (z > 1) set_current_state(TASK_UNINTERRUPTIBLE);
++(*chip_op_time); add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
spin_lock(chip->mutex);
}
}
/* Done and happy. */ /* Done and happy. */
chip->state = FL_STATUS; chip->state = FL_STATUS;
...@@ -1107,8 +1107,7 @@ static int inval_cache_and_wait_for_operation( ...@@ -1107,8 +1107,7 @@ static int inval_cache_and_wait_for_operation(
#endif #endif
#define WAIT_TIMEOUT(map, chip, adr, udelay) \ #define WAIT_TIMEOUT(map, chip, adr, udelay) \
({ int __udelay = (udelay); \ INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay);
INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, &__udelay); })
static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
...@@ -1332,7 +1331,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, ...@@ -1332,7 +1331,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
ret = INVAL_CACHE_AND_WAIT(map, chip, adr, ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, map_bankwidth(map), adr, map_bankwidth(map),
&chip->word_write_time); chip->word_write_time);
if (ret) { if (ret) {
xip_enable(map, chip, adr); xip_enable(map, chip, adr);
printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
...@@ -1569,7 +1568,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, ...@@ -1569,7 +1568,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
adr, len, adr, len,
&chip->buffer_write_time); chip->buffer_write_time);
if (ret) { if (ret) {
map_write(map, CMD(0x70), cmd_adr); map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS; chip->state = FL_STATUS;
...@@ -1704,7 +1703,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, ...@@ -1704,7 +1703,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
ret = INVAL_CACHE_AND_WAIT(map, chip, adr, ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, len, adr, len,
&chip->erase_time); chip->erase_time);
if (ret) { if (ret) {
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS; chip->state = FL_STATUS;
......
...@@ -45,9 +45,11 @@ ...@@ -45,9 +45,11 @@
#define MAX_WORD_RETRIES 3 #define MAX_WORD_RETRIES 3
#define MANUFACTURER_AMD 0x0001 #define MANUFACTURER_AMD 0x0001
#define MANUFACTURER_ATMEL 0x001F
#define MANUFACTURER_SST 0x00BF #define MANUFACTURER_SST 0x00BF
#define SST49LF004B 0x0060 #define SST49LF004B 0x0060
#define SST49LF008A 0x005a #define SST49LF008A 0x005a
#define AT49BV6416 0x00d6
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
...@@ -68,6 +70,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr ...@@ -68,6 +70,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr); static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr);
#include "fwh_lock.h" #include "fwh_lock.h"
static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
static struct mtd_chip_driver cfi_amdstd_chipdrv = { static struct mtd_chip_driver cfi_amdstd_chipdrv = {
.probe = NULL, /* Not usable directly */ .probe = NULL, /* Not usable directly */
.destroy = cfi_amdstd_destroy, .destroy = cfi_amdstd_destroy,
...@@ -161,6 +166,26 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) ...@@ -161,6 +166,26 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
} }
} }
/* Atmel chips don't use the same PRI format as AMD chips */
static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
struct cfi_pri_atmel atmel_pri;
memcpy(&atmel_pri, extp, sizeof(atmel_pri));
memset((char *)extp + 5, 0, sizeof(*extp) - 5);
if (atmel_pri.Features & 0x02)
extp->EraseSuspend = 2;
if (atmel_pri.BottomBoot)
extp->TopBottom = 2;
else
extp->TopBottom = 3;
}
static void fixup_use_secsi(struct mtd_info *mtd, void *param) static void fixup_use_secsi(struct mtd_info *mtd, void *param)
{ {
/* Setup for chips with a secsi area */ /* Setup for chips with a secsi area */
...@@ -179,6 +204,16 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param) ...@@ -179,6 +204,16 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param)
} }
/*
* Some Atmel chips (e.g. the AT49BV6416) power-up with all sectors
* locked by default.
*/
static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param)
{
mtd->lock = cfi_atmel_lock;
mtd->unlock = cfi_atmel_unlock;
}
static struct cfi_fixup cfi_fixup_table[] = { static struct cfi_fixup cfi_fixup_table[] = {
#ifdef AMD_BOOTLOC_BUG #ifdef AMD_BOOTLOC_BUG
{ CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL },
...@@ -192,6 +227,7 @@ static struct cfi_fixup cfi_fixup_table[] = { ...@@ -192,6 +227,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
#if !FORCE_WORD_WRITE #if !FORCE_WORD_WRITE
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
#endif #endif
{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static struct cfi_fixup jedec_fixup_table[] = { static struct cfi_fixup jedec_fixup_table[] = {
...@@ -207,6 +243,7 @@ static struct cfi_fixup fixup_table[] = { ...@@ -207,6 +243,7 @@ static struct cfi_fixup fixup_table[] = {
* we know that is the case. * we know that is the case.
*/ */
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL }, { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL },
{ CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock, NULL },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
...@@ -1607,6 +1644,80 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr) ...@@ -1607,6 +1644,80 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
return 0; return 0;
} }
static int do_atmel_lock(struct map_info *map, struct flchip *chip,
unsigned long adr, int len, void *thunk)
{
struct cfi_private *cfi = map->fldrv_priv;
int ret;
spin_lock(chip->mutex);
ret = get_chip(map, chip, adr + chip->start, FL_LOCKING);
if (ret)
goto out_unlock;
chip->state = FL_LOCKING;
DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n",
__func__, adr, len);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi,
cfi->device_type, NULL);
cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi,
cfi->device_type, NULL);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi,
cfi->device_type, NULL);
map_write(map, CMD(0x40), chip->start + adr);
chip->state = FL_READY;
put_chip(map, chip, adr + chip->start);
ret = 0;
out_unlock:
spin_unlock(chip->mutex);
return ret;
}
static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
unsigned long adr, int len, void *thunk)
{
struct cfi_private *cfi = map->fldrv_priv;
int ret;
spin_lock(chip->mutex);
ret = get_chip(map, chip, adr + chip->start, FL_UNLOCKING);
if (ret)
goto out_unlock;
chip->state = FL_UNLOCKING;
DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n",
__func__, adr, len);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
cfi->device_type, NULL);
map_write(map, CMD(0x70), adr);
chip->state = FL_READY;
put_chip(map, chip, adr + chip->start);
ret = 0;
out_unlock:
spin_unlock(chip->mutex);
return ret;
}
static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
return cfi_varsize_frob(mtd, do_atmel_lock, ofs, len, NULL);
}
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
return cfi_varsize_frob(mtd, do_atmel_unlock, ofs, len, NULL);
}
static void cfi_amdstd_sync (struct mtd_info *mtd) static void cfi_amdstd_sync (struct mtd_info *mtd)
{ {
......
...@@ -111,6 +111,7 @@ ...@@ -111,6 +111,7 @@
#define MX29LV040C 0x004F #define MX29LV040C 0x004F
#define MX29LV160T 0x22C4 #define MX29LV160T 0x22C4
#define MX29LV160B 0x2249 #define MX29LV160B 0x2249
#define MX29F040 0x00A4
#define MX29F016 0x00AD #define MX29F016 0x00AD
#define MX29F002T 0x00B0 #define MX29F002T 0x00B0
#define MX29F004T 0x0045 #define MX29F004T 0x0045
...@@ -1170,6 +1171,19 @@ static const struct amd_flash_info jedec_table[] = { ...@@ -1170,6 +1171,19 @@ static const struct amd_flash_info jedec_table[] = {
ERASEINFO(0x08000,1), ERASEINFO(0x08000,1),
ERASEINFO(0x10000,31) ERASEINFO(0x10000,31)
} }
}, {
.mfr_id = MANUFACTURER_MACRONIX,
.dev_id = MX29F040,
.name = "Macronix MX29F040",
.uaddr = {
[0] = MTD_UADDR_0x0555_0x02AA /* x8 */
},
.DevSize = SIZE_512KiB,
.CmdSet = P_ID_AMD_STD,
.NumEraseRegions= 1,
.regions = {
ERASEINFO(0x10000,8),
}
}, { }, {
.mfr_id = MANUFACTURER_MACRONIX, .mfr_id = MANUFACTURER_MACRONIX,
.dev_id = MX29F016, .dev_id = MX29F016,
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/mount.h>
#define VERSION "$Revision: 1.30 $" #define VERSION "$Revision: 1.30 $"
...@@ -236,6 +237,8 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, ...@@ -236,6 +237,8 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
} }
return 0; return 0;
} }
static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf) size_t *retlen, const u_char *buf)
{ {
...@@ -299,6 +302,19 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) ...@@ -299,6 +302,19 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
/* Get a handle on the device */ /* Get a handle on the device */
bdev = open_bdev_excl(devname, O_RDWR, NULL); bdev = open_bdev_excl(devname, O_RDWR, NULL);
#ifndef MODULE
if (IS_ERR(bdev)) {
/* We might not have rootfs mounted at this point. Try
to resolve the device name by other means. */
dev_t dev = name_to_dev_t(devname);
if (dev != 0) {
bdev = open_by_devnum(dev, FMODE_WRITE | FMODE_READ);
}
}
#endif
if (IS_ERR(bdev)) { if (IS_ERR(bdev)) {
ERROR("error: cannot open device %s", devname); ERROR("error: cannot open device %s", devname);
goto devinit_err; goto devinit_err;
...@@ -393,26 +409,6 @@ static int parse_num(size_t *num, const char *token) ...@@ -393,26 +409,6 @@ static int parse_num(size_t *num, const char *token)
} }
static int parse_name(char **pname, const char *token, size_t limit)
{
size_t len;
char *name;
len = strlen(token) + 1;
if (len > limit)
return -ENOSPC;
name = kmalloc(len, GFP_KERNEL);
if (!name)
return -ENOMEM;
strcpy(name, token);
*pname = name;
return 0;
}
static inline void kill_final_newline(char *str) static inline void kill_final_newline(char *str)
{ {
char *newline = strrchr(str, '\n'); char *newline = strrchr(str, '\n');
...@@ -426,9 +422,15 @@ static inline void kill_final_newline(char *str) ...@@ -426,9 +422,15 @@ static inline void kill_final_newline(char *str)
return 0; \ return 0; \
} while (0) } while (0)
static int block2mtd_setup(const char *val, struct kernel_param *kp) #ifndef MODULE
static int block2mtd_init_called = 0;
static __initdata char block2mtd_paramline[80 + 12]; /* 80 for device, 12 for erase size */
#endif
static int block2mtd_setup2(const char *val)
{ {
char buf[80+12]; /* 80 for device, 12 for erase size */ char buf[80 + 12]; /* 80 for device, 12 for erase size */
char *str = buf; char *str = buf;
char *token[2]; char *token[2];
char *name; char *name;
...@@ -450,13 +452,9 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp) ...@@ -450,13 +452,9 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
if (!token[0]) if (!token[0])
parse_err("no argument"); parse_err("no argument");
ret = parse_name(&name, token[0], 80); name = token[0];
if (ret == -ENOMEM) if (strlen(name) + 1 > 80)
parse_err("out of memory"); parse_err("device name too long");
if (ret == -ENOSPC)
parse_err("name too long");
if (ret)
return 0;
if (token[1]) { if (token[1]) {
ret = parse_num(&erase_size, token[1]); ret = parse_num(&erase_size, token[1]);
...@@ -472,13 +470,48 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp) ...@@ -472,13 +470,48 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
} }
static int block2mtd_setup(const char *val, struct kernel_param *kp)
{
#ifdef MODULE
return block2mtd_setup2(val);
#else
/* If more parameters are later passed in via
/sys/module/block2mtd/parameters/block2mtd
and block2mtd_init() has already been called,
we can parse the argument now. */
if (block2mtd_init_called)
return block2mtd_setup2(val);
/* During early boot stage, we only save the parameters
here. We must parse them later: if the param passed
from kernel boot command line, block2mtd_setup() is
called so early that it is not possible to resolve
the device (even kmalloc() fails). Deter that work to
block2mtd_setup2(). */
strlcpy(block2mtd_paramline, val, sizeof(block2mtd_paramline));
return 0;
#endif
}
module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200);
MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\""); MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\"");
static int __init block2mtd_init(void) static int __init block2mtd_init(void)
{ {
int ret = 0;
INFO("version " VERSION); INFO("version " VERSION);
return 0;
#ifndef MODULE
if (strlen(block2mtd_paramline))
ret = block2mtd_setup2(block2mtd_paramline);
block2mtd_init_called = 1;
#endif
return ret;
} }
......
...@@ -406,13 +406,13 @@ struct flash_info { ...@@ -406,13 +406,13 @@ struct flash_info {
static struct flash_info __devinitdata m25p_data [] = { static struct flash_info __devinitdata m25p_data [] = {
/* REVISIT: fill in JEDEC ids, for parts that have them */ /* REVISIT: fill in JEDEC ids, for parts that have them */
{ "m25p05", 0x05, 0x0000, 32 * 1024, 2 }, { "m25p05", 0x05, 0x2010, 32 * 1024, 2 },
{ "m25p10", 0x10, 0x0000, 32 * 1024, 4 }, { "m25p10", 0x10, 0x2011, 32 * 1024, 4 },
{ "m25p20", 0x11, 0x0000, 64 * 1024, 4 }, { "m25p20", 0x11, 0x2012, 64 * 1024, 4 },
{ "m25p40", 0x12, 0x0000, 64 * 1024, 8 }, { "m25p40", 0x12, 0x2013, 64 * 1024, 8 },
{ "m25p80", 0x13, 0x0000, 64 * 1024, 16 }, { "m25p80", 0x13, 0x0000, 64 * 1024, 16 },
{ "m25p16", 0x14, 0x0000, 64 * 1024, 32 }, { "m25p16", 0x14, 0x2015, 64 * 1024, 32 },
{ "m25p32", 0x15, 0x0000, 64 * 1024, 64 }, { "m25p32", 0x15, 0x2016, 64 * 1024, 64 },
{ "m25p64", 0x16, 0x2017, 64 * 1024, 128 }, { "m25p64", 0x16, 0x2017, 64 * 1024, 128 },
}; };
......
...@@ -99,10 +99,6 @@ ...@@ -99,10 +99,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <linux/pci.h> #include <linux/pci.h>
#ifndef CONFIG_PCI
#error Enable PCI in your kernel config
#endif
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/pmc551.h> #include <linux/mtd/pmc551.h>
#include <linux/mtd/compatmac.h> #include <linux/mtd/compatmac.h>
......
...@@ -13,13 +13,13 @@ config MTD_COMPLEX_MAPPINGS ...@@ -13,13 +13,13 @@ config MTD_COMPLEX_MAPPINGS
config MTD_PHYSMAP config MTD_PHYSMAP
tristate "CFI Flash device in physical memory map" tristate "CFI Flash device in physical memory map"
depends on MTD_CFI depends on MTD_CFI || MTD_JEDECPROBE || MTD_ROM
help help
This provides a 'mapping' driver which allows the CFI probe and This provides a 'mapping' driver which allows the NOR Flash and
command set driver code to communicate with flash chips which ROM driver code to communicate with chips which are mapped
are mapped physically into the CPU's memory. You will need to physically into the CPU's memory. You will need to configure
configure the physical address and size of the flash chips on the physical address and size of the flash chips on your
your particular board as well as the bus width, either statically particular board as well as the bus width, either statically
with config options or at run-time. with config options or at run-time.
config MTD_PHYSMAP_START config MTD_PHYSMAP_START
......
...@@ -62,15 +62,12 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) ...@@ -62,15 +62,12 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
struct mtd_info *mtd = mfi->mtd; struct mtd_info *mtd = mfi->mtd;
switch (orig) { switch (orig) {
case 0: case SEEK_SET:
/* SEEK_SET */
break; break;
case 1: case SEEK_CUR:
/* SEEK_CUR */
offset += file->f_pos; offset += file->f_pos;
break; break;
case 2: case SEEK_END:
/* SEEK_END */
offset += mtd->size; offset += mtd->size;
break; break;
default: default:
......
...@@ -11,7 +11,7 @@ config MTD_NAND ...@@ -11,7 +11,7 @@ config MTD_NAND
help help
This enables support for accessing all type of NAND flash This enables support for accessing all type of NAND flash
devices. For further information see devices. For further information see
<http://www.linux-mtd.infradead.org/tech/nand.html>. <http://www.linux-mtd.infradead.org/doc/nand.html>.
config MTD_NAND_VERIFY_WRITE config MTD_NAND_VERIFY_WRITE
bool "Verify NAND page writes" bool "Verify NAND page writes"
......
...@@ -2224,7 +2224,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, ...@@ -2224,7 +2224,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
} }
/* Try to identify manufacturer */ /* Try to identify manufacturer */
for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_id++) { for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {
if (nand_manuf_ids[maf_idx].id == *maf_id) if (nand_manuf_ids[maf_idx].id == *maf_id)
break; break;
} }
......
...@@ -78,7 +78,7 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = { ...@@ -78,7 +78,7 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = {
/* /*
* hardware specific access to control-lines * hardware specific access to control-lines
* ctrl: * ctrl:
* NAND_CNE: bit 0 -> bit 0 & 4 * NAND_CNE: bit 0 -> ! bit 0 & 4
* NAND_CLE: bit 1 -> bit 1 * NAND_CLE: bit 1 -> bit 1
* NAND_ALE: bit 2 -> bit 2 * NAND_ALE: bit 2 -> bit 2
* *
...@@ -92,7 +92,10 @@ static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd, ...@@ -92,7 +92,10 @@ static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd,
unsigned char bits = ctrl & 0x07; unsigned char bits = ctrl & 0x07;
bits |= (ctrl & 0x01) << 4; bits |= (ctrl & 0x01) << 4;
writeb((readb(FLASHCTL) & 0x17) | bits, FLASHCTL);
bits ^= 0x11;
writeb((readb(FLASHCTL) & ~0x17) | bits, FLASHCTL);
} }
if (cmd != NAND_CMD_NONE) if (cmd != NAND_CMD_NONE)
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include "nodelist.h" #include "nodelist.h"
static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c,
struct jffs2_node_frag *this);
void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list) void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list)
{ {
struct jffs2_full_dirent **prev = list; struct jffs2_full_dirent **prev = list;
...@@ -87,7 +90,8 @@ void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint ...@@ -87,7 +90,8 @@ void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint
} }
} }
void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this) static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c,
struct jffs2_node_frag *this)
{ {
if (this->node) { if (this->node) {
this->node->frags--; this->node->frags--;
......
...@@ -334,7 +334,6 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete); ...@@ -334,7 +334,6 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete);
struct rb_node *rb_next(struct rb_node *); struct rb_node *rb_next(struct rb_node *);
struct rb_node *rb_prev(struct rb_node *); struct rb_node *rb_prev(struct rb_node *);
void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root);
void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this);
int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size);
int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn); int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn);
......
...@@ -1215,7 +1215,6 @@ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xatt ...@@ -1215,7 +1215,6 @@ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xatt
rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE); rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE);
if (rc) { if (rc) {
JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen); JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen);
rc = rc ? rc : -EBADFD;
goto out; goto out;
} }
rc = save_xattr_datum(c, xd); rc = save_xattr_datum(c, xd);
......
...@@ -199,6 +199,18 @@ struct cfi_pri_amdstd { ...@@ -199,6 +199,18 @@ struct cfi_pri_amdstd {
uint8_t TopBottom; uint8_t TopBottom;
} __attribute__((packed)); } __attribute__((packed));
/* Vendor-Specific PRI for Atmel chips (command set 0x0002) */
struct cfi_pri_atmel {
uint8_t pri[3];
uint8_t MajorVersion;
uint8_t MinorVersion;
uint8_t Features;
uint8_t BottomBoot;
uint8_t BurstMode;
uint8_t PageMode;
} __attribute__((packed));
struct cfi_pri_query { struct cfi_pri_query {
uint8_t NumFields; uint8_t NumFields;
uint32_t ProtField[1]; /* Not host ordered */ uint32_t ProtField[1]; /* Not host ordered */
...@@ -464,6 +476,7 @@ struct cfi_fixup { ...@@ -464,6 +476,7 @@ struct cfi_fixup {
#define CFI_ID_ANY 0xffff #define CFI_ID_ANY 0xffff
#define CFI_MFR_AMD 0x0001 #define CFI_MFR_AMD 0x0001
#define CFI_MFR_ATMEL 0x001F
#define CFI_MFR_ST 0x0020 /* STMicroelectronics */ #define CFI_MFR_ST 0x0020 /* STMicroelectronics */
void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups); void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment