diff options
Diffstat (limited to 'drivers/mtd/maps/tsunami_flash.c')
-rw-r--r-- | drivers/mtd/maps/tsunami_flash.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/drivers/mtd/maps/tsunami_flash.c b/drivers/mtd/maps/tsunami_flash.c new file mode 100644 index 000000000000..170d71239e5e --- /dev/null +++ b/drivers/mtd/maps/tsunami_flash.c | |||
@@ -0,0 +1,108 @@ | |||
1 | /* | ||
2 | * tsunami_flash.c | ||
3 | * | ||
4 | * flash chip on alpha ds10... | ||
5 | * $Id: tsunami_flash.c,v 1.9 2004/07/14 09:52:55 dwmw2 Exp $ | ||
6 | */ | ||
7 | #include <asm/io.h> | ||
8 | #include <asm/core_tsunami.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/mtd/map.h> | ||
11 | #include <linux/mtd/mtd.h> | ||
12 | |||
13 | #define FLASH_ENABLE_PORT 0x00C00001 | ||
14 | #define FLASH_ENABLE_BYTE 0x01 | ||
15 | #define FLASH_DISABLE_BYTE 0x00 | ||
16 | |||
17 | #define MAX_TIG_FLASH_SIZE (12*1024*1024) | ||
18 | static inline map_word tsunami_flash_read8(struct map_info *map, unsigned long offset) | ||
19 | { | ||
20 | map_word val; | ||
21 | val.x[0] = tsunami_tig_readb(offset); | ||
22 | return val; | ||
23 | } | ||
24 | |||
25 | static void tsunami_flash_write8(struct map_info *map, map_word value, unsigned long offset) | ||
26 | { | ||
27 | tsunami_tig_writeb(value.x[0], offset); | ||
28 | } | ||
29 | |||
30 | static void tsunami_flash_copy_from( | ||
31 | struct map_info *map, void *addr, unsigned long offset, ssize_t len) | ||
32 | { | ||
33 | unsigned char *dest; | ||
34 | dest = addr; | ||
35 | while(len && (offset < MAX_TIG_FLASH_SIZE)) { | ||
36 | *dest = tsunami_tig_readb(offset); | ||
37 | offset++; | ||
38 | dest++; | ||
39 | len--; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | static void tsunami_flash_copy_to( | ||
44 | struct map_info *map, unsigned long offset, | ||
45 | const void *addr, ssize_t len) | ||
46 | { | ||
47 | const unsigned char *src; | ||
48 | src = addr; | ||
49 | while(len && (offset < MAX_TIG_FLASH_SIZE)) { | ||
50 | tsunami_tig_writeb(*src, offset); | ||
51 | offset++; | ||
52 | src++; | ||
53 | len--; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * Deliberately don't provide operations wider than 8 bits. I don't | ||
59 | * have then and it scares me to think how you could mess up if | ||
60 | * you tried to use them. Buswidth is correctly so I'm safe. | ||
61 | */ | ||
62 | static struct map_info tsunami_flash_map = { | ||
63 | .name = "flash chip on the Tsunami TIG bus", | ||
64 | .size = MAX_TIG_FLASH_SIZE, | ||
65 | .phys = NO_XIP; | ||
66 | .bankwidth = 1, | ||
67 | .read = tsunami_flash_read8, | ||
68 | .copy_from = tsunami_flash_copy_from, | ||
69 | .write = tsunami_flash_write8, | ||
70 | .copy_to = tsunami_flash_copy_to, | ||
71 | }; | ||
72 | |||
73 | static struct mtd_info *tsunami_flash_mtd; | ||
74 | |||
75 | static void __exit cleanup_tsunami_flash(void) | ||
76 | { | ||
77 | struct mtd_info *mtd; | ||
78 | mtd = tsunami_flash_mtd; | ||
79 | if (mtd) { | ||
80 | del_mtd_device(mtd); | ||
81 | map_destroy(mtd); | ||
82 | } | ||
83 | tsunami_flash_mtd = 0; | ||
84 | } | ||
85 | |||
86 | |||
87 | static int __init init_tsunami_flash(void) | ||
88 | { | ||
89 | static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL }; | ||
90 | char **type; | ||
91 | |||
92 | tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT); | ||
93 | |||
94 | tsunami_flash_mtd = 0; | ||
95 | type = rom_probe_types; | ||
96 | for(; !tsunami_flash_mtd && *type; type++) { | ||
97 | tsunami_flash_mtd = do_map_probe(*type, &tsunami_flash_map); | ||
98 | } | ||
99 | if (tsunami_flash_mtd) { | ||
100 | tsunami_flash_mtd->owner = THIS_MODULE; | ||
101 | add_mtd_device(tsunami_flash_mtd); | ||
102 | return 0; | ||
103 | } | ||
104 | return -ENXIO; | ||
105 | } | ||
106 | |||
107 | module_init(init_tsunami_flash); | ||
108 | module_exit(cleanup_tsunami_flash); | ||