Commit f3033b3c authored by Russell King's avatar Russell King

[MTD] sa1100: add container structure for one logical flash device.

parent 07ca9d40
...@@ -925,7 +925,12 @@ struct sa_subdev_info { ...@@ -925,7 +925,12 @@ struct sa_subdev_info {
#define NR_SUBMTD 4 #define NR_SUBMTD 4
static struct sa_subdev_info info[NR_SUBMTD]; struct sa_info {
struct mtd_partition *parts;
struct mtd_info *mtd;
int num_subdev;
struct sa_subdev_info subdev[NR_SUBMTD];
};
static void sa1100_destroy_subdev(struct sa_subdev_info *subdev) static void sa1100_destroy_subdev(struct sa_subdev_info *subdev)
{ {
...@@ -1002,38 +1007,36 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev) ...@@ -1002,38 +1007,36 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev)
return ret; return ret;
} }
static struct mtd_partition *parsed_parts; static void sa1100_destroy(struct sa_info *info)
static void sa1100_destroy(struct mtd_info *mtd)
{ {
int i; int i;
if (mtd) { if (info->mtd) {
del_mtd_partitions(mtd); del_mtd_partitions(info->mtd);
#ifdef CONFIG_MTD_CONCAT #ifdef CONFIG_MTD_CONCAT
if (mtd != sa[i].mtd) if (info->mtd != info->subdev[0].mtd)
mtd_concat_destroy(mtd); mtd_concat_destroy(info->mtd);
#endif #endif
} }
if (parsed_parts) if (info->parts)
kfree(parsed_parts); kfree(info->parts);
for (i = NR_SUBMTD; i >= 0; i--) for (i = info->num_subdev - 1; i >= 0; i--)
sa1100_destroy_subdev(&sa[i]); sa1100_destroy_subdev(&info->subdev[i]);
} }
static int __init sa1100_setup_mtd(struct sa_subdev_info *sa, int nr, struct mtd_info **rmtd) static int __init sa1100_setup_mtd(struct sa_info *info, int nr)
{ {
struct mtd_info *cdev[nr]; struct mtd_info *cdev[nr];
int i, found = 0, ret = 0; int i, ret = 0;
/* /*
* Claim and then map the memory regions. * Claim and then map the memory regions.
*/ */
for (i = 0; i < nr; i++) { for (i = 0; i < nr; i++) {
struct sa_subdev_info *subdev = &sa[i]; struct sa_subdev_info *subdev = &info->subdev[i];
if (subdev->base == (unsigned long)-1) if (subdev->base == (unsigned long)-1)
break; break;
...@@ -1045,27 +1048,33 @@ static int __init sa1100_setup_mtd(struct sa_subdev_info *sa, int nr, struct mtd ...@@ -1045,27 +1048,33 @@ static int __init sa1100_setup_mtd(struct sa_subdev_info *sa, int nr, struct mtd
break; break;
cdev[i] = subdev->mtd; cdev[i] = subdev->mtd;
found += 1;
} }
info->num_subdev = i;
/* /*
* If we found one device, don't bother with concat support. * ENXIO is special. It means we didn't find a chip when we probed.
* If we found multiple devices, use concat if we have it
* available, otherwise fail.
*/ */
if (ret == 0 || ret == -ENXIO) { if (ret != 0 && !(ret == -ENXIO && info->num_subdev > 0))
if (found == 1) { goto err;
*rmtd = cdev[0];
/*
* If we found one device, don't bother with concat support. If
* we found multiple devices, use concat if we have it available,
* otherwise fail. Either way, it'll be called "sa1100".
*/
if (info->num_subdev == 1) {
strcpy(info->subdev[0].name, "sa1100");
info->mtd = info->subdev[0].mtd;
ret = 0; ret = 0;
} else if (found > 1) { } else if (info->num_subdev > 1) {
/* /*
* We detected multiple devices. Concatenate * We detected multiple devices. Concatenate them together.
* them together.
*/ */
#ifdef CONFIG_MTD_CONCAT #ifdef CONFIG_MTD_CONCAT
*rmtd = mtd_concat_create(cdev, found, info->mtd = mtd_concat_create(cdev, info->num_subdev,
"sa1100"); "sa1100");
if (*rmtd == NULL) if (info->mtd == NULL)
ret = -ENXIO; ret = -ENXIO;
#else #else
printk(KERN_ERR "SA1100 flash: multiple devices " printk(KERN_ERR "SA1100 flash: multiple devices "
...@@ -1073,18 +1082,16 @@ static int __init sa1100_setup_mtd(struct sa_subdev_info *sa, int nr, struct mtd ...@@ -1073,18 +1082,16 @@ static int __init sa1100_setup_mtd(struct sa_subdev_info *sa, int nr, struct mtd
ret = -ENXIO; ret = -ENXIO;
#endif #endif
} }
}
/* if (ret == 0)
* If we failed, clean up. return 0;
*/
if (ret)
sa1100_destroy(NULL);
err:
sa1100_destroy(info);
return ret; return ret;
} }
static int __init sa1100_locate_flash(void) static int __init sa1100_locate_flash(struct sa_info *info)
{ {
int i, nr = -ENODEV; int i, nr = -ENODEV;
...@@ -1262,65 +1269,61 @@ static int __init sa1100_locate_flash(void) ...@@ -1262,65 +1269,61 @@ static int __init sa1100_locate_flash(void)
const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
static void __init sa1100_locate_partitions(struct mtd_info *mtd) static void __init sa1100_locate_partitions(struct sa_info *info)
{ {
struct mtd_partition *parts;
const char *part_type = NULL; const char *part_type = NULL;
int nr_parts = 0; int nr_parts = 0;
do {
/* /*
* Partition selection stuff. * Partition selection stuff.
*/ */
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
nr_parts = parse_mtd_partitions(mtd, part_probes, &parsed_parts, 0); nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0);
if (nr_parts > 0) { if (nr_parts > 0) {
info->parts = parts;
part_type = "dynamic"; part_type = "dynamic";
break; } else
}
#endif #endif
#ifdef CONFIG_MTD_SA1100_STATICMAP {
nr_parts = sa1100_static_partitions(&parsed_parts); nr_parts = sa1100_static_partitions(&parts);
if (nr_parts > 0) {
part_type = "static"; part_type = "static";
break;
} }
#endif
} while (0);
if (nr_parts == 0) { if (nr_parts == 0) {
printk(KERN_NOTICE "SA1100 flash: no partition info " printk(KERN_NOTICE "SA1100 flash: no partition info "
"available, registering whole flash\n"); "available, registering whole flash\n");
add_mtd_device(mtd); add_mtd_device(info->mtd);
} else { } else {
printk(KERN_NOTICE "SA1100 flash: using %s partition " printk(KERN_NOTICE "SA1100 flash: using %s partition "
"definition\n", part_type); "definition\n", part_type);
add_mtd_partitions(mtd, parsed_parts, nr_parts); add_mtd_partitions(info->mtd, parts, nr_parts);
} }
/* Always succeeds. */ /* Always succeeds. */
} }
static struct mtd_info *mymtd; static struct sa_info sa_info;
static int __init sa1100_mtd_probe(struct device *dev) static int __init sa1100_mtd_probe(struct device *dev)
{ {
int err; int err;
int nr; int nr;
nr = sa1100_locate_flash(); nr = sa1100_locate_flash(&sa_info);
if (nr < 0) if (nr < 0)
return nr; return nr;
err = sa1100_setup_mtd(info, nr, &mymtd); err = sa1100_setup_mtd(&sa_info, nr);
if (err == 0) if (err == 0)
sa1100_locate_partitions(mymtd); sa1100_locate_partitions(&sa_info);
return err; return err;
} }
static int __exit sa1100_mtd_remove(struct device *dev) static int __exit sa1100_mtd_remove(struct device *dev)
{ {
sa1100_destroy(mymtd); sa1100_destroy(&sa_info);
return 0; return 0;
} }
......
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