1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
| /* * $Id: s3c2410.c,v 1.00 2006/12/05 10:18:14 gleixner Exp $ * * Handle mapping of the NOR flash on Cogent S3C2410 boards * * Copyright 2002 SYSGO Real-Time Solutions GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */
/* * Late Lee * This file is modified and the file name has changed to 's3c2440-flash.c'. * The SMDK2440 board has only one flash bank which is a 64Mbit(4Mx16) SST SST39VF6401B; * 128 x 64 KiB blocks. * * This code is GPLed. */
#include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/init.h> #include <asm/io.h> #include <linux/mtd/mtd.h> #include <linux/mtd/map.h> #include <linux/mtd/cfi.h>
#ifdef CONFIG_MTD_PARTITIONS #include <linux/mtd/partitions.h> #endif
#define WINDOW_ADDR 0x01000000 /* physical properties of flash */ #define WINDOW_SIZE 0x800000 /* 8MB */ #define BUSWIDTH 2 /* 2*8 = 16 */ #define FLASH_BLOCKSIZE_MAIN 0x10000 /* 64KB(0x10000) 128 blocks */ #define FLASH_NUMBLOCKS_MAIN 128
/* can be "cfi_probe", "jedec_probe", "map_rom", NULL }; */ #define PROBETYPES { "cfi_probe", "jedec_probe", "map_rom", NULL }
#define MSG_PREFIX "S3C2440-NOR:" /* prefix for our printk()'s */ #define MTDID "s3c2440-nor" /* for mtdparts= partitioning */
#define DEBUG_FLASH #ifdef DEBUG_FLASH #define flash_debug(fmt, args...) printk(KERN_NOTICE "## LL debug " MSG_PREFIX fmt, ##args) #else #define flash_debug(fmt, args...) #endif
static struct mtd_info *mymtd;
struct map_info s3c2440nor_map = { .name = "NOR Flash(SST39VF6401B) on S3C2440", .size = WINDOW_SIZE, .bankwidth = BUSWIDTH, .phys = WINDOW_ADDR, };
#ifdef CONFIG_MTD_PARTITIONS
/* * MTD partitioning stuff */ static struct mtd_partition static_partitions[] = { /*0: U-Boot: 0-0x30000 0x30000=192KB*/ { .name = "U-Boot", .size = 0x030000, .offset = 0x0, }, /*1: Kernel: 0x30000-0x240000 0x210000=2112KB=2.0625MB*/ { .name = "Kernel", .size = 0x210000, .offset = 0x30000, }, /*2: Rootfs(jffs2): 0x240000-0x7f0000 0x5b0000=5824KB=5.6875MB*/ { .name = "Rootfs(jffs2)", .size = 0x5b0000, .offset = 0x240000, }, /*3: U-Boot Parameters: 0x7f0000-0x800000 0x10000=64KB*/ {.name = "Parameter", .size = 0x010000, .offset = 0x7f0000, }, };
//static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; static const char *probes[] = { NULL };
#endif
static int mtd_parts_nb = 0; static struct mtd_partition *mtd_parts = 0;
int __init init_s3c2440nor(void) { static const char *rom_probe_types[] = PROBETYPES; const char **type; const char *part_type = 0;
printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", WINDOW_SIZE, WINDOW_ADDR); s3c2440nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); if (!s3c2440nor_map.virt) { printk(MSG_PREFIX "failed to ioremap\n"); return -EIO; }
simple_map_init(&s3c2440nor_map); mymtd = 0; type = rom_probe_types; for(; !mymtd && *type; type++) { mymtd = do_map_probe(*type, &s3c2440nor_map); flash_debug("func:%s[%d] mymtd:%x type:%s\n", __func__, __LINE__, mymtd, *type); }
if (mymtd) { mymtd->owner = THIS_MODULE;
#ifdef CONFIG_MTD_PARTITIONS mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID); if (mtd_parts_nb > 0) part_type = "detected";
if (mtd_parts_nb == 0){ mtd_parts = static_partitions; mtd_parts_nb = ARRAY_SIZE(static_partitions); part_type = "static"; } #endif add_mtd_device(mymtd); if (mtd_parts_nb == 0) printk(KERN_NOTICE MSG_PREFIX "no partition info available\n"); else{ printk(KERN_NOTICE MSG_PREFIX "using %s partition definition\n", part_type); add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb); } return 0; }
iounmap((void *)s3c2440nor_map.virt); return -ENXIO; }
static void __exit cleanup_s3c2440nor(void) { if (mymtd) { del_mtd_device(mymtd); map_destroy(mymtd); } if (s3c2440nor_map.virt) { iounmap((void *)s3c2440nor_map.virt); s3c2440nor_map.virt = 0; } }
module_init(init_s3c2440nor); module_exit(cleanup_s3c2440nor);
MODULE_LICENSE("GPL"); MODULE_AUTHOR("GengYaoJun "); MODULE_DESCRIPTION("Generic configurable MTD map driver");
|