summaryrefslogtreecommitdiffstats
path: root/linux-2.4.x/drivers/mtd/maps/mphysmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-2.4.x/drivers/mtd/maps/mphysmap.c')
-rw-r--r--linux-2.4.x/drivers/mtd/maps/mphysmap.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/linux-2.4.x/drivers/mtd/maps/mphysmap.c b/linux-2.4.x/drivers/mtd/maps/mphysmap.c
new file mode 100644
index 0000000..05969ec
--- /dev/null
+++ b/linux-2.4.x/drivers/mtd/maps/mphysmap.c
@@ -0,0 +1,186 @@
+/*
+ * $Id: mphysmap.c,v 1.4 2005/11/07 11:14:27 gleixner Exp $
+ *
+ * Several mappings of NOR chips
+ *
+ * Copyright (c) 2001-2005 Jörn Engel <joern@wh.fh-wedelde>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
+static struct map_info mphysmap_static_maps[] = {
+#if CONFIG_MTD_MULTI_PHYSMAP_1_WIDTH
+ {
+ .name = CONFIG_MTD_MULTI_PHYSMAP_1_NAME,
+ .phys = CONFIG_MTD_MULTI_PHYSMAP_1_START,
+ .size = CONFIG_MTD_MULTI_PHYSMAP_1_LEN,
+ .bankwidth = CONFIG_MTD_MULTI_PHYSMAP_1_WIDTH,
+ },
+#endif
+#if CONFIG_MTD_MULTI_PHYSMAP_2_WIDTH
+ {
+ .name = CONFIG_MTD_MULTI_PHYSMAP_2_NAME,
+ .phys = CONFIG_MTD_MULTI_PHYSMAP_2_START,
+ .size = CONFIG_MTD_MULTI_PHYSMAP_2_LEN,
+ .bankwidth = CONFIG_MTD_MULTI_PHYSMAP_2_WIDTH,
+ },
+#endif
+#if CONFIG_MTD_MULTI_PHYSMAP_3_WIDTH
+ {
+ .name = CONFIG_MTD_MULTI_PHYSMAP_3_NAME,
+ .phys = CONFIG_MTD_MULTI_PHYSMAP_3_START,
+ .size = CONFIG_MTD_MULTI_PHYSMAP_3_LEN,
+ .bankwidth = CONFIG_MTD_MULTI_PHYSMAP_3_WIDTH,
+ },
+#endif
+#if CONFIG_MTD_MULTI_PHYSMAP_4_WIDTH
+ {
+ .name = CONFIG_MTD_MULTI_PHYSMAP_4_NAME,
+ .phys = CONFIG_MTD_MULTI_PHYSMAP_4_START,
+ .size = CONFIG_MTD_MULTI_PHYSMAP_4_LEN,
+ .bankwidth = CONFIG_MTD_MULTI_PHYSMAP_4_WIDTH,
+ },
+#endif
+};
+
+DECLARE_MUTEX(map_mutex);
+
+
+static int mphysmap_map_device(struct map_info *map)
+{
+ static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };
+ const char **type;
+ struct mtd_info* mtd;
+#ifdef CONFIG_MTD_PARTITIONS
+ struct mtd_partition* mtd_parts;
+ int mtd_parts_nb;
+ static const char *part_probes[] __initdata = {
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ "cmdlinepart",
+#endif
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+ "RedBoot",
+#endif
+ NULL};
+#endif
+ map->virt = ioremap(map->phys, map->size);
+ if (!map->virt)
+ return -EIO;
+
+ simple_map_init(map);
+ mtd = NULL;
+ type = rom_probe_types;
+ for(; !mtd && *type; type++) {
+ mtd = do_map_probe(*type, map);
+ }
+
+ if (!mtd) {
+ iounmap(map->virt);
+ return -ENXIO;
+ }
+
+ map->map_priv_1 = (unsigned long)mtd;
+ mtd->owner = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ mtd_parts_nb = parse_mtd_partitions(mtd, part_probes,
+ &mtd_parts, 0);
+ if (mtd_parts_nb > 0)
+ {
+ add_mtd_partitions (mtd, mtd_parts, mtd_parts_nb);
+ map->map_priv_2=(unsigned long)mtd_parts;
+ }
+ else
+ {
+ add_mtd_device(mtd);
+ map->map_priv_2=(unsigned long)NULL;
+ };
+#else
+ add_mtd_device(mtd);
+#endif
+ return 0;
+}
+
+
+static void mphysmap_unmap_device(struct map_info *map)
+{
+ struct mtd_info* mtd = (struct mtd_info*)map->map_priv_1;
+#ifdef CONFIG_MTD_PARTITIONS
+ struct mtd_partition* mtd_parts=(struct mtd_partition*)map->map_priv_2;
+#endif
+ BUG_ON(!mtd);
+ if (!map->virt)
+ return;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ if (mtd_parts)
+ {
+ del_mtd_partitions(mtd);
+ kfree(mtd_parts);
+ }
+ else
+ del_mtd_device(mtd);
+#else
+ del_mtd_device(mtd);
+#endif
+ map_destroy(mtd);
+ iounmap(map->virt);
+
+ map->map_priv_1 = 0;
+ map->map_priv_2 = 0;
+ map->virt = NULL;
+}
+
+
+
+
+static int __init mphysmap_init(void)
+{
+ int i;
+ down(&map_mutex);
+ for (i=0;
+ i<sizeof(mphysmap_static_maps)/sizeof(mphysmap_static_maps[0]);
+ i++)
+ {
+ if (strcmp(mphysmap_static_maps[i].name,"")!=0 &&
+ mphysmap_static_maps[i].size!=0 &&
+ mphysmap_static_maps[i].bankwidth!=0)
+ {
+ mphysmap_map_device(&mphysmap_static_maps[i]);
+ };
+ };
+ up(&map_mutex);
+ return 0;
+}
+
+
+static void __exit mphysmap_exit(void)
+{
+ int i;
+ down(&map_mutex);
+ for (i=0;
+ i<sizeof(mphysmap_static_maps)/sizeof(mphysmap_static_maps[0]);
+ i++)
+ {
+ if (strcmp(mphysmap_static_maps[i].name,"")!=0 &&
+ mphysmap_static_maps[i].size!=0 &&
+ mphysmap_static_maps[i].bankwidth!=0)
+ {
+ mphysmap_unmap_device(&mphysmap_static_maps[i]);
+ };
+ };
+ up(&map_mutex);
+}
+
+
+module_init(mphysmap_init);
+module_exit(mphysmap_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jörn Engel <joern@wh.fh-wedelde>");
+MODULE_DESCRIPTION("Generic configurable extensible MTD map driver");