1/* 2 * Flash memory access on Hynix GMS30C7201/HMS30C7202 based 3 * evaluation boards 4 * 5 * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com> 6 * 2003 Thomas Gleixner <tglx@linutronix.de> 7 */ 8 9#include <linux/module.h> 10#include <linux/types.h> 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/errno.h> 14#include <linux/slab.h> 15 16#include <linux/mtd/mtd.h> 17#include <linux/mtd/map.h> 18#include <linux/mtd/partitions.h> 19#include <mach/hardware.h> 20#include <asm/io.h> 21 22static struct mtd_info *mymtd; 23 24static struct map_info h720x_map = { 25 .name = "H720X", 26 .bankwidth = 4, 27 .size = H720X_FLASH_SIZE, 28 .phys = H720X_FLASH_PHYS, 29}; 30 31static struct mtd_partition h720x_partitions[] = { 32 { 33 .name = "ArMon", 34 .size = 0x00080000, 35 .offset = 0, 36 .mask_flags = MTD_WRITEABLE 37 },{ 38 .name = "Env", 39 .size = 0x00040000, 40 .offset = 0x00080000, 41 .mask_flags = MTD_WRITEABLE 42 },{ 43 .name = "Kernel", 44 .size = 0x00180000, 45 .offset = 0x000c0000, 46 .mask_flags = MTD_WRITEABLE 47 },{ 48 .name = "Ramdisk", 49 .size = 0x00400000, 50 .offset = 0x00240000, 51 .mask_flags = MTD_WRITEABLE 52 },{ 53 .name = "jffs2", 54 .size = MTDPART_SIZ_FULL, 55 .offset = MTDPART_OFS_APPEND 56 } 57}; 58 59#define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions) 60 61static int nr_mtd_parts; 62static struct mtd_partition *mtd_parts; 63static const char *probes[] = { "cmdlinepart", NULL }; 64 65/* 66 * Initialize FLASH support 67 */ 68static int __init h720x_mtd_init(void) 69{ 70 71 char *part_type = NULL; 72 73 h720x_map.virt = ioremap(h720x_map.phys, h720x_map.size); 74 75 if (!h720x_map.virt) { 76 printk(KERN_ERR "H720x-MTD: ioremap failed\n"); 77 return -EIO; 78 } 79 80 simple_map_init(&h720x_map); 81 82 // Probe for flash bankwidth 4 83 printk (KERN_INFO "H720x-MTD probing 32bit FLASH\n"); 84 mymtd = do_map_probe("cfi_probe", &h720x_map); 85 if (!mymtd) { 86 printk (KERN_INFO "H720x-MTD probing 16bit FLASH\n"); 87 // Probe for bankwidth 2 88 h720x_map.bankwidth = 2; 89 mymtd = do_map_probe("cfi_probe", &h720x_map); 90 } 91 92 if (mymtd) { 93 mymtd->owner = THIS_MODULE; 94 95#ifdef CONFIG_MTD_PARTITIONS 96 nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0); 97 if (nr_mtd_parts > 0) 98 part_type = "command line"; 99#endif 100 if (nr_mtd_parts <= 0) { 101 mtd_parts = h720x_partitions; 102 nr_mtd_parts = NUM_PARTITIONS; 103 part_type = "builtin"; 104 } 105 printk(KERN_INFO "Using %s partition table\n", part_type); 106 add_mtd_partitions(mymtd, mtd_parts, nr_mtd_parts); 107 return 0; 108 } 109 110 iounmap((void *)h720x_map.virt); 111 return -ENXIO; 112} 113 114/* 115 * Cleanup 116 */ 117static void __exit h720x_mtd_cleanup(void) 118{ 119 120 if (mymtd) { 121 del_mtd_partitions(mymtd); 122 map_destroy(mymtd); 123 } 124 125 /* Free partition info, if commandline partition was used */ 126 if (mtd_parts && (mtd_parts != h720x_partitions)) 127 kfree (mtd_parts); 128 129 if (h720x_map.virt) { 130 iounmap((void *)h720x_map.virt); 131 h720x_map.virt = 0; 132 } 133} 134 135 136module_init(h720x_mtd_init); 137module_exit(h720x_mtd_cleanup); 138 139MODULE_LICENSE("GPL"); 140MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>"); 141MODULE_DESCRIPTION("MTD map driver for Hynix evaluation boards"); 142