Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: [MTD] [MAPS] Remove MODULE_DEVICE_TABLE() from ck804rom driver. [JFFS2] fix mount crash caused by removed nodes [JFFS2] force the jffs2 GC daemon to behave a bit better [MTD] [MAPS] blackfin async requires complex mappings [MTD] [MAPS] blackfin: fix memory leak in error path [MTD] [MAPS] physmap: fix wrong free and del_mtd_{partition,device} [MTD] slram: Handle negative devlength correctly [MTD] map_rom has NULL erase pointer [MTD] [LPDDR] qinfo_probe depends on lpddr
This commit is contained in:
commit
221be177e6
|
@ -19,6 +19,7 @@ static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
|
||||||
static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
|
static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
|
||||||
static void maprom_nop (struct mtd_info *);
|
static void maprom_nop (struct mtd_info *);
|
||||||
static struct mtd_info *map_rom_probe(struct map_info *map);
|
static struct mtd_info *map_rom_probe(struct map_info *map);
|
||||||
|
static int maprom_erase (struct mtd_info *mtd, struct erase_info *info);
|
||||||
|
|
||||||
static struct mtd_chip_driver maprom_chipdrv = {
|
static struct mtd_chip_driver maprom_chipdrv = {
|
||||||
.probe = map_rom_probe,
|
.probe = map_rom_probe,
|
||||||
|
@ -42,6 +43,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
|
||||||
mtd->read = maprom_read;
|
mtd->read = maprom_read;
|
||||||
mtd->write = maprom_write;
|
mtd->write = maprom_write;
|
||||||
mtd->sync = maprom_nop;
|
mtd->sync = maprom_nop;
|
||||||
|
mtd->erase = maprom_erase;
|
||||||
mtd->flags = MTD_CAP_ROM;
|
mtd->flags = MTD_CAP_ROM;
|
||||||
mtd->erasesize = map->size;
|
mtd->erasesize = map->size;
|
||||||
mtd->writesize = 1;
|
mtd->writesize = 1;
|
||||||
|
@ -71,6 +73,12 @@ static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *re
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int maprom_erase (struct mtd_info *mtd, struct erase_info *info)
|
||||||
|
{
|
||||||
|
/* We do our best 8) */
|
||||||
|
return -EROFS;
|
||||||
|
}
|
||||||
|
|
||||||
static int __init map_rom_init(void)
|
static int __init map_rom_init(void)
|
||||||
{
|
{
|
||||||
register_mtd_chip_driver(&maprom_chipdrv);
|
register_mtd_chip_driver(&maprom_chipdrv);
|
||||||
|
|
|
@ -267,22 +267,28 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
|
||||||
if (*(szlength) != '+') {
|
if (*(szlength) != '+') {
|
||||||
devlength = simple_strtoul(szlength, &buffer, 0);
|
devlength = simple_strtoul(szlength, &buffer, 0);
|
||||||
devlength = handle_unit(devlength, buffer) - devstart;
|
devlength = handle_unit(devlength, buffer) - devstart;
|
||||||
|
if (devlength < devstart)
|
||||||
|
goto err_out;
|
||||||
|
|
||||||
|
devlength -= devstart;
|
||||||
} else {
|
} else {
|
||||||
devlength = simple_strtoul(szlength + 1, &buffer, 0);
|
devlength = simple_strtoul(szlength + 1, &buffer, 0);
|
||||||
devlength = handle_unit(devlength, buffer);
|
devlength = handle_unit(devlength, buffer);
|
||||||
}
|
}
|
||||||
T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
|
T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
|
||||||
devname, devstart, devlength);
|
devname, devstart, devlength);
|
||||||
if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
|
if (devlength % SLRAM_BLK_SZ != 0)
|
||||||
E("slram: Illegal start / length parameter.\n");
|
goto err_out;
|
||||||
return(-EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((devstart = register_device(devname, devstart, devlength))){
|
if ((devstart = register_device(devname, devstart, devlength))){
|
||||||
unregister_devices();
|
unregister_devices();
|
||||||
return((int)devstart);
|
return((int)devstart);
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
E("slram: Illegal length parameter.\n");
|
||||||
|
return(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MODULE
|
#ifndef MODULE
|
||||||
|
|
|
@ -12,6 +12,7 @@ config MTD_LPDDR
|
||||||
DDR memories, intended for battery-operated systems.
|
DDR memories, intended for battery-operated systems.
|
||||||
|
|
||||||
config MTD_QINFO_PROBE
|
config MTD_QINFO_PROBE
|
||||||
|
depends on MTD_LPDDR
|
||||||
tristate "Detect flash chips by QINFO probe"
|
tristate "Detect flash chips by QINFO probe"
|
||||||
help
|
help
|
||||||
Device Information for LPDDR chips is offered through the Overlay
|
Device Information for LPDDR chips is offered through the Overlay
|
||||||
|
|
|
@ -491,7 +491,7 @@ config MTD_PCMCIA_ANONYMOUS
|
||||||
|
|
||||||
config MTD_BFIN_ASYNC
|
config MTD_BFIN_ASYNC
|
||||||
tristate "Blackfin BF533-STAMP Flash Chip Support"
|
tristate "Blackfin BF533-STAMP Flash Chip Support"
|
||||||
depends on BFIN533_STAMP && MTD_CFI
|
depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS
|
||||||
select MTD_PARTITIONS
|
select MTD_PARTITIONS
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
|
|
|
@ -152,14 +152,18 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) {
|
if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) {
|
||||||
pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin);
|
pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin);
|
||||||
|
kfree(state);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
gpio_direction_output(state->enet_flash_pin, 1);
|
gpio_direction_output(state->enet_flash_pin, 1);
|
||||||
|
|
||||||
pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8);
|
pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8);
|
||||||
state->mtd = do_map_probe(memory->name, &state->map);
|
state->mtd = do_map_probe(memory->name, &state->map);
|
||||||
if (!state->mtd)
|
if (!state->mtd) {
|
||||||
|
gpio_free(state->enet_flash_pin);
|
||||||
|
kfree(state);
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MTD_PARTITIONS
|
#ifdef CONFIG_MTD_PARTITIONS
|
||||||
ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0);
|
ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0);
|
||||||
|
|
|
@ -342,9 +342,9 @@ static struct pci_device_id ck804xrom_pci_tbl[] = {
|
||||||
{ 0, }
|
{ 0, }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl);
|
MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl);
|
||||||
|
|
||||||
#if 0
|
|
||||||
static struct pci_driver ck804xrom_driver = {
|
static struct pci_driver ck804xrom_driver = {
|
||||||
.name = MOD_NAME,
|
.name = MOD_NAME,
|
||||||
.id_table = ck804xrom_pci_tbl,
|
.id_table = ck804xrom_pci_tbl,
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct physmap_flash_info {
|
||||||
struct map_info map[MAX_RESOURCES];
|
struct map_info map[MAX_RESOURCES];
|
||||||
#ifdef CONFIG_MTD_PARTITIONS
|
#ifdef CONFIG_MTD_PARTITIONS
|
||||||
int nr_parts;
|
int nr_parts;
|
||||||
|
struct mtd_partition *parts;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,26 +46,27 @@ static int physmap_flash_remove(struct platform_device *dev)
|
||||||
|
|
||||||
physmap_data = dev->dev.platform_data;
|
physmap_data = dev->dev.platform_data;
|
||||||
|
|
||||||
#ifdef CONFIG_MTD_CONCAT
|
#ifdef CONFIG_MTD_PARTITIONS
|
||||||
if (info->cmtd != info->mtd[0]) {
|
if (info->nr_parts) {
|
||||||
|
del_mtd_partitions(info->cmtd);
|
||||||
|
kfree(info->parts);
|
||||||
|
} else if (physmap_data->nr_parts)
|
||||||
|
del_mtd_partitions(info->cmtd);
|
||||||
|
else
|
||||||
del_mtd_device(info->cmtd);
|
del_mtd_device(info->cmtd);
|
||||||
|
#else
|
||||||
|
del_mtd_device(info->cmtd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTD_CONCAT
|
||||||
|
if (info->cmtd != info->mtd[0])
|
||||||
mtd_concat_destroy(info->cmtd);
|
mtd_concat_destroy(info->cmtd);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < MAX_RESOURCES; i++) {
|
for (i = 0; i < MAX_RESOURCES; i++) {
|
||||||
if (info->mtd[i] != NULL) {
|
if (info->mtd[i] != NULL)
|
||||||
#ifdef CONFIG_MTD_PARTITIONS
|
|
||||||
if (info->nr_parts || physmap_data->nr_parts)
|
|
||||||
del_mtd_partitions(info->mtd[i]);
|
|
||||||
else
|
|
||||||
del_mtd_device(info->mtd[i]);
|
|
||||||
#else
|
|
||||||
del_mtd_device(info->mtd[i]);
|
|
||||||
#endif
|
|
||||||
map_destroy(info->mtd[i]);
|
map_destroy(info->mtd[i]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,9 +88,6 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int i;
|
int i;
|
||||||
int devices_found = 0;
|
int devices_found = 0;
|
||||||
#ifdef CONFIG_MTD_PARTITIONS
|
|
||||||
struct mtd_partition *parts;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
physmap_data = dev->dev.platform_data;
|
physmap_data = dev->dev.platform_data;
|
||||||
if (physmap_data == NULL)
|
if (physmap_data == NULL)
|
||||||
|
@ -167,10 +166,11 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
#ifdef CONFIG_MTD_PARTITIONS
|
#ifdef CONFIG_MTD_PARTITIONS
|
||||||
err = parse_mtd_partitions(info->cmtd, part_probe_types, &parts, 0);
|
err = parse_mtd_partitions(info->cmtd, part_probe_types,
|
||||||
|
&info->parts, 0);
|
||||||
if (err > 0) {
|
if (err > 0) {
|
||||||
add_mtd_partitions(info->cmtd, parts, err);
|
add_mtd_partitions(info->cmtd, info->parts, err);
|
||||||
kfree(parts);
|
info->nr_parts = err;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,13 +95,17 @@ static int jffs2_garbage_collect_thread(void *_c)
|
||||||
spin_unlock(&c->erase_completion_lock);
|
spin_unlock(&c->erase_completion_lock);
|
||||||
|
|
||||||
|
|
||||||
/* This thread is purely an optimisation. But if it runs when
|
/* Problem - immediately after bootup, the GCD spends a lot
|
||||||
other things could be running, it actually makes things a
|
* of time in places like jffs2_kill_fragtree(); so much so
|
||||||
lot worse. Use yield() and put it at the back of the runqueue
|
* that userspace processes (like gdm and X) are starved
|
||||||
every time. Especially during boot, pulling an inode in
|
* despite plenty of cond_resched()s and renicing. Yield()
|
||||||
with read_inode() is much preferable to having the GC thread
|
* doesn't help, either (presumably because userspace and GCD
|
||||||
get there first. */
|
* are generally competing for a higher latency resource -
|
||||||
yield();
|
* disk).
|
||||||
|
* This forces the GCD to slow the hell down. Pulling an
|
||||||
|
* inode in with read_inode() is much preferable to having
|
||||||
|
* the GC thread get there first. */
|
||||||
|
schedule_timeout_interruptible(msecs_to_jiffies(50));
|
||||||
|
|
||||||
/* Put_super will send a SIGKILL and then wait on the sem.
|
/* Put_super will send a SIGKILL and then wait on the sem.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -220,7 +220,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
|
||||||
struct jffs2_tmp_dnode_info *tn)
|
struct jffs2_tmp_dnode_info *tn)
|
||||||
{
|
{
|
||||||
uint32_t fn_end = tn->fn->ofs + tn->fn->size;
|
uint32_t fn_end = tn->fn->ofs + tn->fn->size;
|
||||||
struct jffs2_tmp_dnode_info *this;
|
struct jffs2_tmp_dnode_info *this, *ptn;
|
||||||
|
|
||||||
dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw));
|
dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw));
|
||||||
|
|
||||||
|
@ -251,11 +251,18 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
|
||||||
if (this) {
|
if (this) {
|
||||||
/* If the node is coincident with another at a lower address,
|
/* If the node is coincident with another at a lower address,
|
||||||
back up until the other node is found. It may be relevant */
|
back up until the other node is found. It may be relevant */
|
||||||
while (this->overlapped)
|
while (this->overlapped) {
|
||||||
this = tn_prev(this);
|
ptn = tn_prev(this);
|
||||||
|
if (!ptn) {
|
||||||
/* First node should never be marked overlapped */
|
/*
|
||||||
BUG_ON(!this);
|
* We killed a node which set the overlapped
|
||||||
|
* flags during the scan. Fix it up.
|
||||||
|
*/
|
||||||
|
this->overlapped = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this = ptn;
|
||||||
|
}
|
||||||
dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole");
|
dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +367,17 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
|
||||||
}
|
}
|
||||||
if (!this->overlapped)
|
if (!this->overlapped)
|
||||||
break;
|
break;
|
||||||
this = tn_prev(this);
|
|
||||||
|
ptn = tn_prev(this);
|
||||||
|
if (!ptn) {
|
||||||
|
/*
|
||||||
|
* We killed a node which set the overlapped
|
||||||
|
* flags during the scan. Fix it up.
|
||||||
|
*/
|
||||||
|
this->overlapped = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this = ptn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,8 +473,15 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c,
|
||||||
eat_last(&rii->tn_root, &last->rb);
|
eat_last(&rii->tn_root, &last->rb);
|
||||||
ver_insert(&ver_root, last);
|
ver_insert(&ver_root, last);
|
||||||
|
|
||||||
if (unlikely(last->overlapped))
|
if (unlikely(last->overlapped)) {
|
||||||
|
if (pen)
|
||||||
continue;
|
continue;
|
||||||
|
/*
|
||||||
|
* We killed a node which set the overlapped
|
||||||
|
* flags during the scan. Fix it up.
|
||||||
|
*/
|
||||||
|
last->overlapped = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now we have a bunch of nodes in reverse version
|
/* Now we have a bunch of nodes in reverse version
|
||||||
order, in the tree at ver_root. Most of the time,
|
order, in the tree at ver_root. Most of the time,
|
||||||
|
|
Loading…
Reference in New Issue