1/*
2 * Flash device on lasat 100 and 200 boards
3 *
4 */
5
6#include <linux/module.h>
7#include <linux/types.h>
8#include <linux/kernel.h>
9#include <asm/io.h>
10#include <linux/mtd/mtd.h>
11#include <linux/mtd/map.h>
12#include <linux/mtd/partitions.h>
13#include <linux/config.h>
14#include <asm/lasat/lasat.h>
15#include <asm/lasat/lasat_mtd.h>
16
17static struct mtd_info *mymtd;
18
19static __u8 sp_read8(struct map_info *map, unsigned long ofs)
20{
21	return __raw_readb(map->map_priv_1 + ofs);
22}
23
24static __u16 sp_read16(struct map_info *map, unsigned long ofs)
25{
26	return __raw_readw(map->map_priv_1 + ofs);
27}
28
29static __u32 sp_read32(struct map_info *map, unsigned long ofs)
30{
31	return __raw_readl(map->map_priv_1 + ofs);
32}
33
34static void sp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
35{
36	memcpy_fromio(to, map->map_priv_1 + from, len);
37}
38
39static void sp_write8(struct map_info *map, __u8 d, unsigned long adr)
40{
41	__raw_writeb(d, map->map_priv_1 + adr);
42	mb();
43}
44
45static void sp_write16(struct map_info *map, __u16 d, unsigned long adr)
46{
47	__raw_writew(d, map->map_priv_1 + adr);
48	mb();
49}
50
51static void sp_write32(struct map_info *map, __u32 d, unsigned long adr)
52{
53	__raw_writel(d, map->map_priv_1 + adr);
54	mb();
55}
56
57static void sp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
58{
59	memcpy_toio(map->map_priv_1 + to, from, len);
60}
61
62static struct map_info sp_map = {
63	name: "SP flash",
64	buswidth: 4,
65	read8: sp_read8,
66	read16: sp_read16,
67	read32: sp_read32,
68	copy_from: sp_copy_from,
69	write8: sp_write8,
70	write16: sp_write16,
71	write32: sp_write32,
72	copy_to: sp_copy_to
73};
74
75static struct mtd_partition partition_info[LASAT_MTD_LAST];
76static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"};
77
78static int __init init_sp(void)
79{
80	int i;
81	/* this does not play well with the old flash code which
82	 * protects and uprotects the flash when necessary */
83       	printk(KERN_NOTICE "Unprotecting flash\n");
84	*lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit;
85
86	sp_map.map_priv_1 = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER);
87	sp_map.size = lasat_board_info.li_flash_size;
88
89       	printk(KERN_NOTICE "sp flash device: %lx at %lx\n",
90			sp_map.size, sp_map.map_priv_1);
91
92	for (i=0; i < LASAT_MTD_LAST; i++)
93		partition_info[i].name = lasat_mtd_partnames[i];
94
95	mymtd = do_map_probe("cfi_probe", &sp_map);
96	if (mymtd) {
97		u32 size, offset = 0;
98
99		mymtd->module = THIS_MODULE;
100
101		for (i=0; i < LASAT_MTD_LAST; i++) {
102			size = lasat_flash_partition_size(i);
103			partition_info[i].size = size;
104			partition_info[i].offset = offset;
105			offset += size;
106		}
107
108		add_mtd_partitions( mymtd, partition_info, LASAT_MTD_LAST );
109		return 0;
110	}
111
112	return -ENXIO;
113}
114
115static void __exit cleanup_sp(void)
116{
117	if (mymtd) {
118	  del_mtd_partitions(mymtd);
119	  map_destroy(mymtd);
120	}
121	if (sp_map.map_priv_1) {
122	  sp_map.map_priv_1 = 0;
123	}
124}
125
126module_init(init_sp);
127module_exit(cleanup_sp);
128
129MODULE_LICENSE("GPL");
130MODULE_AUTHOR("Brian Murphy <brian@murphy.dk>");
131MODULE_DESCRIPTION("Lasat Safepipe/Masquerade MTD map driver");
132