aboutsummaryrefslogtreecommitdiff
path: root/drivers/mtd/maps/physmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/maps/physmap.c')
-rw-r--r--drivers/mtd/maps/physmap.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index abc562653b3..f73cd461257 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -27,6 +27,8 @@ struct physmap_flash_info {
struct mtd_info *mtd[MAX_RESOURCES];
struct mtd_info *cmtd;
struct map_info map[MAX_RESOURCES];
+ spinlock_t vpp_lock;
+ int vpp_refcnt;
};
static int physmap_flash_remove(struct platform_device *dev)
@@ -38,9 +40,8 @@ static int physmap_flash_remove(struct platform_device *dev)
info = platform_get_drvdata(dev);
if (info == NULL)
return 0;
- platform_set_drvdata(dev, NULL);
- physmap_data = dev->dev.platform_data;
+ physmap_data = dev_get_platdata(&dev->dev);
if (info->cmtd) {
mtd_device_unregister(info->cmtd);
@@ -63,34 +64,45 @@ static void physmap_set_vpp(struct map_info *map, int state)
{
struct platform_device *pdev;
struct physmap_flash_data *physmap_data;
+ struct physmap_flash_info *info;
+ unsigned long flags;
pdev = (struct platform_device *)map->map_priv_1;
- physmap_data = pdev->dev.platform_data;
+ physmap_data = dev_get_platdata(&pdev->dev);
+
+ if (!physmap_data->set_vpp)
+ return;
+
+ info = platform_get_drvdata(pdev);
- if (physmap_data->set_vpp)
- physmap_data->set_vpp(pdev, state);
+ spin_lock_irqsave(&info->vpp_lock, flags);
+ if (state) {
+ if (++info->vpp_refcnt == 1) /* first nested 'on' */
+ physmap_data->set_vpp(pdev, 1);
+ } else {
+ if (--info->vpp_refcnt == 0) /* last nested 'off' */
+ physmap_data->set_vpp(pdev, 0);
+ }
+ spin_unlock_irqrestore(&info->vpp_lock, flags);
}
-static const char *rom_probe_types[] = {
- "cfi_probe",
- "jedec_probe",
- "qinfo_probe",
- "map_rom",
- NULL };
-static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "afs",
- NULL };
+static const char * const rom_probe_types[] = {
+ "cfi_probe", "jedec_probe", "qinfo_probe", "map_rom", NULL };
+
+static const char * const part_probe_types[] = {
+ "cmdlinepart", "RedBoot", "afs", NULL };
static int physmap_flash_probe(struct platform_device *dev)
{
struct physmap_flash_data *physmap_data;
struct physmap_flash_info *info;
- const char **probe_type;
- const char **part_types;
+ const char * const *probe_type;
+ const char * const *part_types;
int err = 0;
int i;
int devices_found = 0;
- physmap_data = dev->dev.platform_data;
+ physmap_data = dev_get_platdata(&dev->dev);
if (physmap_data == NULL)
return -ENODEV;
@@ -172,9 +184,11 @@ static int physmap_flash_probe(struct platform_device *dev)
if (err)
goto err_out;
+ spin_lock_init(&info->vpp_lock);
+
part_types = physmap_data->part_probe_types ? : part_probe_types;
- mtd_device_parse_register(info->cmtd, part_types, 0,
+ mtd_device_parse_register(info->cmtd, part_types, NULL,
physmap_data->parts, physmap_data->nr_parts);
return 0;