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