0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <linux/module.h>
0026 #include <linux/types.h>
0027 #include <linux/kernel.h>
0028 #include <linux/init.h>
0029 #include <asm/io.h>
0030 #include <linux/mtd/mtd.h>
0031 #include <linux/mtd/map.h>
0032 #include <linux/mtd/partitions.h>
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #define FLASH_PHYS_ADDR 0x40000000
0043 #define FLASH_SIZE 0x400000
0044
0045 #define FLASH_PARTITION0_ADDR 0x00000000
0046 #define FLASH_PARTITION0_SIZE 0x00020000
0047
0048 #define FLASH_PARTITION1_ADDR 0x00020000
0049 #define FLASH_PARTITION1_SIZE 0x000A0000
0050
0051 #define FLASH_PARTITION2_ADDR 0x000C0000
0052 #define FLASH_PARTITION2_SIZE 0x00180000
0053
0054 #define FLASH_PARTITION3_ADDR 0x00240000
0055 #define FLASH_PARTITION3_SIZE 0x001C0000
0056
0057
0058 static struct map_info flagadm_map = {
0059 .name = "FlagaDM flash device",
0060 .size = FLASH_SIZE,
0061 .bankwidth = 2,
0062 };
0063
0064 static const struct mtd_partition flagadm_parts[] = {
0065 {
0066 .name = "Bootloader",
0067 .offset = FLASH_PARTITION0_ADDR,
0068 .size = FLASH_PARTITION0_SIZE
0069 },
0070 {
0071 .name = "Kernel image",
0072 .offset = FLASH_PARTITION1_ADDR,
0073 .size = FLASH_PARTITION1_SIZE
0074 },
0075 {
0076 .name = "Initial ramdisk image",
0077 .offset = FLASH_PARTITION2_ADDR,
0078 .size = FLASH_PARTITION2_SIZE
0079 },
0080 {
0081 .name = "Persistent storage",
0082 .offset = FLASH_PARTITION3_ADDR,
0083 .size = FLASH_PARTITION3_SIZE
0084 }
0085 };
0086
0087 #define PARTITION_COUNT ARRAY_SIZE(flagadm_parts)
0088
0089 static struct mtd_info *mymtd;
0090
0091 static int __init init_flagadm(void)
0092 {
0093 printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n",
0094 FLASH_SIZE, FLASH_PHYS_ADDR);
0095
0096 flagadm_map.phys = FLASH_PHYS_ADDR;
0097 flagadm_map.virt = ioremap(FLASH_PHYS_ADDR,
0098 FLASH_SIZE);
0099
0100 if (!flagadm_map.virt) {
0101 printk("Failed to ioremap\n");
0102 return -EIO;
0103 }
0104
0105 simple_map_init(&flagadm_map);
0106
0107 mymtd = do_map_probe("cfi_probe", &flagadm_map);
0108 if (mymtd) {
0109 mymtd->owner = THIS_MODULE;
0110 mtd_device_register(mymtd, flagadm_parts, PARTITION_COUNT);
0111 printk(KERN_NOTICE "FlagaDM flash device initialized\n");
0112 return 0;
0113 }
0114
0115 iounmap((void __iomem *)flagadm_map.virt);
0116 return -ENXIO;
0117 }
0118
0119 static void __exit cleanup_flagadm(void)
0120 {
0121 if (mymtd) {
0122 mtd_device_unregister(mymtd);
0123 map_destroy(mymtd);
0124 }
0125 if (flagadm_map.virt) {
0126 iounmap((void __iomem *)flagadm_map.virt);
0127 flagadm_map.virt = NULL;
0128 }
0129 }
0130
0131 module_init(init_flagadm);
0132 module_exit(cleanup_flagadm);
0133
0134
0135 MODULE_LICENSE("GPL");
0136 MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>");
0137 MODULE_DESCRIPTION("MTD map driver for Flaga digital module");