0001
0002
0003
0004
0005
0006
0007 #include <asm/io.h>
0008 #include <asm/core_tsunami.h>
0009 #include <linux/init.h>
0010 #include <linux/mtd/map.h>
0011 #include <linux/mtd/mtd.h>
0012
0013 #define FLASH_ENABLE_PORT 0x00C00001
0014 #define FLASH_ENABLE_BYTE 0x01
0015 #define FLASH_DISABLE_BYTE 0x00
0016
0017 #define MAX_TIG_FLASH_SIZE (12*1024*1024)
0018 static inline map_word tsunami_flash_read8(struct map_info *map, unsigned long offset)
0019 {
0020 map_word val;
0021 val.x[0] = tsunami_tig_readb(offset);
0022 return val;
0023 }
0024
0025 static void tsunami_flash_write8(struct map_info *map, map_word value, unsigned long offset)
0026 {
0027 tsunami_tig_writeb(value.x[0], offset);
0028 }
0029
0030 static void tsunami_flash_copy_from(
0031 struct map_info *map, void *addr, unsigned long offset, ssize_t len)
0032 {
0033 unsigned char *dest;
0034 dest = addr;
0035 while(len && (offset < MAX_TIG_FLASH_SIZE)) {
0036 *dest = tsunami_tig_readb(offset);
0037 offset++;
0038 dest++;
0039 len--;
0040 }
0041 }
0042
0043 static void tsunami_flash_copy_to(
0044 struct map_info *map, unsigned long offset,
0045 const void *addr, ssize_t len)
0046 {
0047 const unsigned char *src;
0048 src = addr;
0049 while(len && (offset < MAX_TIG_FLASH_SIZE)) {
0050 tsunami_tig_writeb(*src, offset);
0051 offset++;
0052 src++;
0053 len--;
0054 }
0055 }
0056
0057
0058
0059
0060
0061
0062 static struct map_info tsunami_flash_map = {
0063 .name = "flash chip on the Tsunami TIG bus",
0064 .size = MAX_TIG_FLASH_SIZE,
0065 .phys = NO_XIP,
0066 .bankwidth = 1,
0067 .read = tsunami_flash_read8,
0068 .copy_from = tsunami_flash_copy_from,
0069 .write = tsunami_flash_write8,
0070 .copy_to = tsunami_flash_copy_to,
0071 };
0072
0073 static struct mtd_info *tsunami_flash_mtd;
0074
0075 static void __exit cleanup_tsunami_flash(void)
0076 {
0077 struct mtd_info *mtd;
0078 mtd = tsunami_flash_mtd;
0079 if (mtd) {
0080 mtd_device_unregister(mtd);
0081 map_destroy(mtd);
0082 }
0083 tsunami_flash_mtd = 0;
0084 }
0085
0086 static const char * const rom_probe_types[] = {
0087 "cfi_probe", "jedec_probe", "map_rom", NULL };
0088
0089 static int __init init_tsunami_flash(void)
0090 {
0091 const char * const *type;
0092
0093 tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT);
0094
0095 tsunami_flash_mtd = 0;
0096 type = rom_probe_types;
0097 for(; !tsunami_flash_mtd && *type; type++) {
0098 tsunami_flash_mtd = do_map_probe(*type, &tsunami_flash_map);
0099 }
0100 if (tsunami_flash_mtd) {
0101 tsunami_flash_mtd->owner = THIS_MODULE;
0102 mtd_device_register(tsunami_flash_mtd, NULL, 0);
0103 return 0;
0104 }
0105 return -ENXIO;
0106 }
0107
0108 module_init(init_tsunami_flash);
0109 module_exit(cleanup_tsunami_flash);