summaryrefslogtreecommitdiffstats
path: root/linux-2.4.x/drivers/mtd/maps/dbox2-flash.c
blob: 2e5c30d802c2a1d4674f7980ec2c8775a8c93c0e (plain)
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
/*
 * $Id: dbox2-flash.c,v 1.4 2001/10/02 15:05:14 dwmw2 Exp $
 *
 * Nokia / Sagem D-Box 2 flash driver
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/config.h>

/* partition_info gives details on the logical partitions that the split the
 * single flash device into. If the size if zero we use up to the end of the
 * device. */
static struct mtd_partition partition_info[]= {{name: "BR bootloader",		// raw
						      size: 128 * 1024, 
						      offset: 0,                  
						      mask_flags: MTD_WRITEABLE},
                                                     {name: "PPC bootloader",		// flfs
						      size: 128 * 1024, 
						      offset: MTDPART_OFS_APPEND, 
						      mask_flags: 0},
                                                     {name: "Kernel",			// idxfs
						      size: 768 * 1024, 
						      offset: MTDPART_OFS_APPEND, 
						      mask_flags: 0},
                                                     {name: "System",			// jffs
						      size: MTDPART_SIZ_FULL, 
						      offset: MTDPART_OFS_APPEND, 
						      mask_flags: 0}};

#define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0]))

#define WINDOW_ADDR 0x10000000
#define WINDOW_SIZE 0x800000

static struct mtd_info *mymtd;

__u8 dbox2_flash_read8(struct map_info *map, unsigned long ofs)
{
	return __raw_readb(map->map_priv_1 + ofs);
}

__u16 dbox2_flash_read16(struct map_info *map, unsigned long ofs)
{
	return __raw_readw(map->map_priv_1 + ofs);
}

__u32 dbox2_flash_read32(struct map_info *map, unsigned long ofs)
{
	return __raw_readl(map->map_priv_1 + ofs);
}

void dbox2_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
{
	memcpy_fromio(to, map->map_priv_1 + from, len);
}

void dbox2_flash_write8(struct map_info *map, __u8 d, unsigned long adr)
{
	__raw_writeb(d, map->map_priv_1 + adr);
	mb();
}

void dbox2_flash_write16(struct map_info *map, __u16 d, unsigned long adr)
{
	__raw_writew(d, map->map_priv_1 + adr);
	mb();
}

void dbox2_flash_write32(struct map_info *map, __u32 d, unsigned long adr)
{
	__raw_writel(d, map->map_priv_1 + adr);
	mb();
}

void dbox2_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
{
	memcpy_toio(map->map_priv_1 + to, from, len);
}

struct map_info dbox2_flash_map = {
	name: "D-Box 2 flash memory",
	size: WINDOW_SIZE,
	buswidth: 4,
	read8: dbox2_flash_read8,
	read16: dbox2_flash_read16,
	read32: dbox2_flash_read32,
	copy_from: dbox2_flash_copy_from,
	write8: dbox2_flash_write8,
	write16: dbox2_flash_write16,
	write32: dbox2_flash_write32,
	copy_to: dbox2_flash_copy_to
};

int __init init_dbox2_flash(void)
{
       	printk(KERN_NOTICE "D-Box 2 flash driver (size->0x%X mem->0x%X)\n", WINDOW_SIZE, WINDOW_ADDR);
	dbox2_flash_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);

	if (!dbox2_flash_map.map_priv_1) {
		printk("Failed to ioremap\n");
		return -EIO;
	}

	// Probe for dual Intel 28F320 or dual AMD
	mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
	if (!mymtd) {
	    // Probe for single Intel 28F640
	    dbox2_flash_map.buswidth = 2;
	
	    mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
	}
	    
	if (mymtd) {
		mymtd->module = THIS_MODULE;

                /* Create MTD devices for each partition. */
	        add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
		
		return 0;
	}

	iounmap((void *)dbox2_flash_map.map_priv_1);
	return -ENXIO;
}

static void __exit cleanup_dbox2_flash(void)
{
	if (mymtd) {
		del_mtd_partitions(mymtd);
		map_destroy(mymtd);
	}
	if (dbox2_flash_map.map_priv_1) {
		iounmap((void *)dbox2_flash_map.map_priv_1);
		dbox2_flash_map.map_priv_1 = 0;
	}
}

module_init(init_dbox2_flash);
module_exit(cleanup_dbox2_flash);


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kári Davíđsson <kd@flaga.is>");
MODULE_DESCRIPTION("MTD map driver for Nokia/Sagem D-Box 2 board");