mtd: maps: physmap: Remove the MAX_RESOURCES limitation
Remove the MAX_RESOURCES limitation by dynamically allocating the ->mtds[] and ->maps[] at probe time based on the number of iomem resources attached to the platform device. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Reviewed-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
ea5bc54b12
commit
51b436a242
|
@ -22,12 +22,11 @@
|
||||||
#include <linux/mtd/concat.h>
|
#include <linux/mtd/concat.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
|
||||||
#define MAX_RESOURCES 4
|
|
||||||
|
|
||||||
struct physmap_flash_info {
|
struct physmap_flash_info {
|
||||||
struct mtd_info *mtds[MAX_RESOURCES];
|
unsigned int nmaps;
|
||||||
|
struct mtd_info **mtds;
|
||||||
struct mtd_info *cmtd;
|
struct mtd_info *cmtd;
|
||||||
struct map_info maps[MAX_RESOURCES];
|
struct map_info *maps;
|
||||||
spinlock_t vpp_lock;
|
spinlock_t vpp_lock;
|
||||||
int vpp_refcnt;
|
int vpp_refcnt;
|
||||||
};
|
};
|
||||||
|
@ -50,7 +49,7 @@ static int physmap_flash_remove(struct platform_device *dev)
|
||||||
mtd_concat_destroy(info->cmtd);
|
mtd_concat_destroy(info->cmtd);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAX_RESOURCES; i++) {
|
for (i = 0; i < info->nmaps; i++) {
|
||||||
if (info->mtds[i] != NULL)
|
if (info->mtds[i] != NULL)
|
||||||
map_destroy(info->mtds[i]);
|
map_destroy(info->mtds[i]);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +100,6 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||||
const char * const *part_types;
|
const char * const *part_types;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int i;
|
int i;
|
||||||
int devices_found = 0;
|
|
||||||
|
|
||||||
physmap_data = dev_get_platdata(&dev->dev);
|
physmap_data = dev_get_platdata(&dev->dev);
|
||||||
if (physmap_data == NULL)
|
if (physmap_data == NULL)
|
||||||
|
@ -114,6 +112,24 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (platform_get_resource(dev, IORESOURCE_MEM, info->nmaps))
|
||||||
|
info->nmaps++;
|
||||||
|
|
||||||
|
if (!info->nmaps)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
info->maps = devm_kzalloc(&dev->dev,
|
||||||
|
sizeof(*info->maps) * info->nmaps,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!info->maps)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
info->mtds = devm_kzalloc(&dev->dev,
|
||||||
|
sizeof(*info->mtds) * info->nmaps,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!info->mtds)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
if (physmap_data->init) {
|
if (physmap_data->init) {
|
||||||
err = physmap_data->init(dev);
|
err = physmap_data->init(dev);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -122,13 +138,10 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||||
|
|
||||||
platform_set_drvdata(dev, info);
|
platform_set_drvdata(dev, info);
|
||||||
|
|
||||||
for (i = 0; i < MAX_RESOURCES; i++) {
|
for (i = 0; i < info->nmaps; i++) {
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
|
||||||
res = platform_get_resource(dev, IORESOURCE_MEM, i);
|
res = platform_get_resource(dev, IORESOURCE_MEM, i);
|
||||||
if (!res)
|
|
||||||
break;
|
|
||||||
|
|
||||||
info->maps[i].virt = devm_ioremap_resource(&dev->dev, res);
|
info->maps[i].virt = devm_ioremap_resource(&dev->dev, res);
|
||||||
if (IS_ERR(info->maps[i].virt)) {
|
if (IS_ERR(info->maps[i].virt)) {
|
||||||
err = PTR_ERR(info->maps[i].virt);
|
err = PTR_ERR(info->maps[i].virt);
|
||||||
|
@ -159,21 +172,18 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||||
dev_err(&dev->dev, "map_probe failed\n");
|
dev_err(&dev->dev, "map_probe failed\n");
|
||||||
err = -ENXIO;
|
err = -ENXIO;
|
||||||
goto err_out;
|
goto err_out;
|
||||||
} else {
|
|
||||||
devices_found++;
|
|
||||||
}
|
}
|
||||||
info->mtds[i]->dev.parent = &dev->dev;
|
info->mtds[i]->dev.parent = &dev->dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!devices_found) {
|
if (info->nmaps == 1) {
|
||||||
err = -ENODEV;
|
|
||||||
} else if (devices_found == 1) {
|
|
||||||
info->cmtd = info->mtds[0];
|
info->cmtd = info->mtds[0];
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We detected multiple devices. Concatenate them together.
|
* We detected multiple devices. Concatenate them together.
|
||||||
*/
|
*/
|
||||||
info->cmtd = mtd_concat_create(info->mtds, devices_found, dev_name(&dev->dev));
|
info->cmtd = mtd_concat_create(info->mtds, info->nmaps,
|
||||||
|
dev_name(&dev->dev));
|
||||||
if (info->cmtd == NULL)
|
if (info->cmtd == NULL)
|
||||||
err = -ENXIO;
|
err = -ENXIO;
|
||||||
}
|
}
|
||||||
|
@ -199,7 +209,7 @@ static void physmap_flash_shutdown(struct platform_device *dev)
|
||||||
struct physmap_flash_info *info = platform_get_drvdata(dev);
|
struct physmap_flash_info *info = platform_get_drvdata(dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_RESOURCES && info->mtds[i]; i++)
|
for (i = 0; i < info->nmaps && info->mtds[i]; i++)
|
||||||
if (mtd_suspend(info->mtds[i]) == 0)
|
if (mtd_suspend(info->mtds[i]) == 0)
|
||||||
mtd_resume(info->mtds[i]);
|
mtd_resume(info->mtds[i]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue