Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 84301
b: refs/heads/master
c: df66e71
h: refs/heads/master
i:
  84299: 540ac20
v: v3
  • Loading branch information
Stefan Roese authored and David Woodhouse committed Feb 3, 2008
1 parent dfb614a commit 0fd8304
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 59 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1c45f60406e61a06631416264e49eb5afd9fc324
refs/heads/master: df66e7167ac756baf14d2b8ea7a2cfa056600a93
162 changes: 104 additions & 58 deletions trunk/drivers/mtd/maps/physmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,27 @@
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/concat.h>
#include <asm/io.h>

#define MAX_RESOURCES 4

struct physmap_flash_info {
struct mtd_info *mtd;
struct map_info map;
struct mtd_info *mtd[MAX_RESOURCES];
struct mtd_info *cmtd;
struct map_info map[MAX_RESOURCES];
struct resource *res;
#ifdef CONFIG_MTD_PARTITIONS
int nr_parts;
struct mtd_partition *parts;
#endif
};


static int physmap_flash_remove(struct platform_device *dev)
{
struct physmap_flash_info *info;
struct physmap_flash_data *physmap_data;
int i;

info = platform_get_drvdata(dev);
if (info == NULL)
Expand All @@ -45,24 +49,33 @@ static int physmap_flash_remove(struct platform_device *dev)

physmap_data = dev->dev.platform_data;

if (info->mtd != NULL) {
#ifdef CONFIG_MTD_CONCAT
if (info->cmtd != info->mtd[0]) {
del_mtd_device(info->cmtd);
mtd_concat_destroy(info->cmtd);
}
#endif

for (i = 0; i < MAX_RESOURCES; i++) {
if (info->mtd[i] != NULL) {
#ifdef CONFIG_MTD_PARTITIONS
if (info->nr_parts) {
del_mtd_partitions(info->mtd);
kfree(info->parts);
} else if (physmap_data->nr_parts) {
del_mtd_partitions(info->mtd);
} else {
del_mtd_device(info->mtd);
}
if (info->nr_parts) {
del_mtd_partitions(info->mtd[i]);
kfree(info->parts);
} else if (physmap_data->nr_parts) {
del_mtd_partitions(info->mtd[i]);
} else {
del_mtd_device(info->mtd[i]);
}
#else
del_mtd_device(info->mtd);
del_mtd_device(info->mtd[i]);
#endif
map_destroy(info->mtd);
}
map_destroy(info->mtd[i]);
}

if (info->map.virt != NULL)
iounmap(info->map.virt);
if (info->map[i].virt != NULL)
iounmap(info->map[i].virt);
}

if (info->res != NULL) {
release_resource(info->res);
Expand All @@ -82,16 +95,14 @@ static int physmap_flash_probe(struct platform_device *dev)
struct physmap_flash_data *physmap_data;
struct physmap_flash_info *info;
const char **probe_type;
int err;
int err = 0;
int i;
int devices_found = 0;

physmap_data = dev->dev.platform_data;
if (physmap_data == NULL)
return -ENODEV;

printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
(unsigned long long)(dev->resource->end - dev->resource->start + 1),
(unsigned long long)dev->resource->start);

info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);
if (info == NULL) {
err = -ENOMEM;
Expand All @@ -100,56 +111,83 @@ static int physmap_flash_probe(struct platform_device *dev)

platform_set_drvdata(dev, info);

info->res = request_mem_region(dev->resource->start,
dev->resource->end - dev->resource->start + 1,
dev->dev.bus_id);
if (info->res == NULL) {
dev_err(&dev->dev, "Could not reserve memory region\n");
err = -ENOMEM;
goto err_out;
}
for (i = 0; i < dev->num_resources; i++) {
printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
(unsigned long long)(dev->resource[i].end - dev->resource[i].start + 1),
(unsigned long long)dev->resource[i].start);

info->res = request_mem_region(dev->resource[i].start,
dev->resource[i].end - dev->resource[i].start + 1,
dev->dev.bus_id);
if (info->res == NULL) {
dev_err(&dev->dev, "Could not reserve memory region\n");
err = -ENOMEM;
goto err_out;
}

info->map.name = dev->dev.bus_id;
info->map.phys = dev->resource->start;
info->map.size = dev->resource->end - dev->resource->start + 1;
info->map.bankwidth = physmap_data->width;
info->map.set_vpp = physmap_data->set_vpp;
info->map[i].name = dev->dev.bus_id;
info->map[i].phys = dev->resource[i].start;
info->map[i].size = dev->resource[i].end - dev->resource[i].start + 1;
info->map[i].bankwidth = physmap_data->width;
info->map[i].set_vpp = physmap_data->set_vpp;

info->map[i].virt = ioremap(info->map[i].phys, info->map[i].size);
if (info->map[i].virt == NULL) {
dev_err(&dev->dev, "Failed to ioremap flash region\n");
err = EIO;
goto err_out;
}

info->map.virt = ioremap(info->map.phys, info->map.size);
if (info->map.virt == NULL) {
dev_err(&dev->dev, "Failed to ioremap flash region\n");
err = EIO;
goto err_out;
}
simple_map_init(&info->map[i]);

simple_map_init(&info->map);
probe_type = rom_probe_types;
for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++)
info->mtd[i] = do_map_probe(*probe_type, &info->map[i]);
if (info->mtd[i] == NULL) {
dev_err(&dev->dev, "map_probe failed\n");
err = -ENXIO;
goto err_out;
} else {
devices_found++;
}
info->mtd[i]->owner = THIS_MODULE;
}

probe_type = rom_probe_types;
for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
info->mtd = do_map_probe(*probe_type, &info->map);
if (info->mtd == NULL) {
dev_err(&dev->dev, "map_probe failed\n");
if (devices_found == 1) {
info->cmtd = info->mtd[0];
} else if (devices_found > 1) {
/*
* We detected multiple devices. Concatenate them together.
*/
#ifdef CONFIG_MTD_CONCAT
info->cmtd = mtd_concat_create(info->mtd, devices_found, dev->dev.bus_id);
if (info->cmtd == NULL)
err = -ENXIO;
#else
printk(KERN_ERR "physmap-flash: multiple devices "
"found but MTD concat support disabled.\n");
err = -ENXIO;
goto err_out;
#endif
}
info->mtd->owner = THIS_MODULE;
if (err)
goto err_out;

#ifdef CONFIG_MTD_PARTITIONS
err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0);
err = parse_mtd_partitions(info->cmtd, part_probe_types, &info->parts, 0);
if (err > 0) {
add_mtd_partitions(info->mtd, info->parts, err);
add_mtd_partitions(info->cmtd, info->parts, err);
return 0;
}

if (physmap_data->nr_parts) {
printk(KERN_NOTICE "Using physmap partition information\n");
add_mtd_partitions(info->mtd, physmap_data->parts,
physmap_data->nr_parts);
add_mtd_partitions(info->cmtd, physmap_data->parts,
physmap_data->nr_parts);
return 0;
}
#endif

add_mtd_device(info->mtd);
add_mtd_device(info->cmtd);
return 0;

err_out:
Expand All @@ -162,26 +200,34 @@ static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state
{
struct physmap_flash_info *info = platform_get_drvdata(dev);
int ret = 0;
int i;

if (info)
ret = info->mtd->suspend(info->mtd);
for (i = 0; i < MAX_RESOURCES; i++)
ret |= info->mtd[i].suspend(info->mtd[i]);

return ret;
}

static int physmap_flash_resume(struct platform_device *dev)
{
struct physmap_flash_info *info = platform_get_drvdata(dev);
int i;

if (info)
info->mtd->resume(info->mtd);
for (i = 0; i < MAX_RESOURCES; i++)
info->mtd[i].resume(info->mtd[i]);
return 0;
}

static void physmap_flash_shutdown(struct platform_device *dev)
{
struct physmap_flash_info *info = platform_get_drvdata(dev);
if (info && info->mtd->suspend(info->mtd) == 0)
info->mtd->resume(info->mtd);
int i;

for (i = 0; i < MAX_RESOURCES; i++)
if (info && info->mtd[i].suspend(info->mtd[i]) == 0)
info->mtd[i].resume(info->mtd[i]);
}
#endif

Expand Down

0 comments on commit 0fd8304

Please sign in to comment.