blob: f49ebc3c4606c89dbc60605cbbf31dd33a6bf93f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Adrian Bunk2b9175c2005-11-29 14:49:38 +00002 * $Id: physmap.c,v 1.39 2005/11/29 14:49:36 gleixner Exp $
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
4 * Normal mappings of chips in physical memory
5 *
6 * Copyright (C) 2003 MontaVista Software Inc.
7 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
8 *
9 * 031022 - [jsun] add run-time configure and partition setup
10 */
11
12#include <linux/module.h>
13#include <linux/types.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <asm/io.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/map.h>
20#include <linux/config.h>
21#include <linux/mtd/partitions.h>
Adrian Bunk2b9175c2005-11-29 14:49:38 +000022#include <linux/mtd/physmap.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023
24static struct mtd_info *mymtd;
25
26struct map_info physmap_map = {
27 .name = "phys_mapped_flash",
28 .phys = CONFIG_MTD_PHYSMAP_START,
29 .size = CONFIG_MTD_PHYSMAP_LEN,
30 .bankwidth = CONFIG_MTD_PHYSMAP_BANKWIDTH,
31};
32
33#ifdef CONFIG_MTD_PARTITIONS
34static struct mtd_partition *mtd_parts;
35static int mtd_parts_nb;
36
37static int num_physmap_partitions;
38static struct mtd_partition *physmap_partitions;
39
40static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL};
41
42void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
43{
44 physmap_partitions=parts;
45 num_physmap_partitions=num_parts;
46}
47#endif /* CONFIG_MTD_PARTITIONS */
48
49static int __init init_physmap(void)
50{
51 static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };
52 const char **type;
53
54 printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys);
55 physmap_map.virt = ioremap(physmap_map.phys, physmap_map.size);
56
57 if (!physmap_map.virt) {
58 printk("Failed to ioremap\n");
59 return -EIO;
60 }
61
62 simple_map_init(&physmap_map);
63
64 mymtd = NULL;
65 type = rom_probe_types;
66 for(; !mymtd && *type; type++) {
67 mymtd = do_map_probe(*type, &physmap_map);
68 }
69 if (mymtd) {
70 mymtd->owner = THIS_MODULE;
71
72#ifdef CONFIG_MTD_PARTITIONS
Thomas Gleixner69f34c92005-11-07 11:15:40 +000073 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes,
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 &mtd_parts, 0);
75
76 if (mtd_parts_nb > 0)
77 {
78 add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb);
79 return 0;
80 }
81
Thomas Gleixner69f34c92005-11-07 11:15:40 +000082 if (num_physmap_partitions != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 {
Thomas Gleixner69f34c92005-11-07 11:15:40 +000084 printk(KERN_NOTICE
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 "Using physmap partition definition\n");
86 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions);
87 return 0;
88 }
89
90#endif
91 add_mtd_device(mymtd);
92
93 return 0;
94 }
95
96 iounmap(physmap_map.virt);
97 return -ENXIO;
98}
99
100static void __exit cleanup_physmap(void)
101{
102#ifdef CONFIG_MTD_PARTITIONS
103 if (mtd_parts_nb) {
104 del_mtd_partitions(mymtd);
105 kfree(mtd_parts);
106 } else if (num_physmap_partitions) {
107 del_mtd_partitions(mymtd);
108 } else {
109 del_mtd_device(mymtd);
110 }
111#else
112 del_mtd_device(mymtd);
113#endif
114 map_destroy(mymtd);
115
116 iounmap(physmap_map.virt);
117 physmap_map.virt = NULL;
118}
119
120module_init(init_physmap);
121module_exit(cleanup_physmap);
122
123
124MODULE_LICENSE("GPL");
125MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
126MODULE_DESCRIPTION("Generic configurable MTD map driver");