OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [mtd/] [maps/] [sun_uflash.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* $Id: sun_uflash.c,v 1.1.1.1 2004-04-15 01:51:54 phoenix Exp $
2
 *
3
 * sun_uflash - Driver implementation for user-programmable flash
4
 * present on many Sun Microsystems SME boardsets.
5
 *
6
 * This driver does NOT provide access to the OBP-flash for
7
 * safety reasons-- use <linux>/drivers/sbus/char/flash.c instead.
8
 *
9
 * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
10
 *
11
 */
12
 
13
#include <linux/kernel.h>
14
#include <linux/module.h>
15
#include <linux/version.h>
16
#include <linux/fs.h>
17
#include <linux/errno.h>
18
#include <linux/init.h>
19
#include <linux/ioport.h>
20
#include <asm/ebus.h>
21
#include <asm/oplib.h>
22
#include <asm/uaccess.h>
23
#include <asm/io.h>
24
 
25
#include <linux/mtd/mtd.h>
26
#include <linux/mtd/map.h>
27
 
28
#define UFLASH_OBPNAME  "flashprom"
29
#define UFLASH_DEVNAME  "userflash"
30
 
31
#define UFLASH_WINDOW_SIZE      0x200000
32
#define UFLASH_BUSWIDTH         1                       /* EBus is 8-bit */
33
 
34
MODULE_AUTHOR
35
        ("Eric Brower <ebrower@usa.net>");
36
MODULE_DESCRIPTION
37
        ("User-programmable flash device on Sun Microsystems boardsets");
38
MODULE_SUPPORTED_DEVICE
39
        ("userflash");
40
MODULE_LICENSE
41
        ("GPL");
42
 
43
static LIST_HEAD(device_list);
44
struct uflash_dev {
45
        char *                  name;   /* device name */
46
        struct map_info         map;    /* mtd map info */
47
        struct mtd_info *       mtd;    /* mtd info */
48
        struct list_head        list;
49
};
50
 
51
__u8 uflash_read8(struct map_info *map, unsigned long ofs)
52
{
53
        return(__raw_readb(map->map_priv_1 + ofs));
54
}
55
 
56
__u16 uflash_read16(struct map_info *map, unsigned long ofs)
57
{
58
        return(__raw_readw(map->map_priv_1 + ofs));
59
}
60
 
61
__u32 uflash_read32(struct map_info *map, unsigned long ofs)
62
{
63
        return(__raw_readl(map->map_priv_1 + ofs));
64
}
65
 
66
void uflash_copy_from(struct map_info *map, void *to, unsigned long from,
67
                      ssize_t len)
68
{
69
        memcpy_fromio(to, map->map_priv_1 + from, len);
70
}
71
 
72
void uflash_write8(struct map_info *map, __u8 d, unsigned long adr)
73
{
74
        __raw_writeb(d, map->map_priv_1 + adr);
75
}
76
 
77
void uflash_write16(struct map_info *map, __u16 d, unsigned long adr)
78
{
79
        __raw_writew(d, map->map_priv_1 + adr);
80
}
81
 
82
void uflash_write32(struct map_info *map, __u32 d, unsigned long adr)
83
{
84
        __raw_writel(d, map->map_priv_1 + adr);
85
}
86
 
87
void uflash_copy_to(struct map_info *map, unsigned long to, const void *from,
88
                    ssize_t len)
89
{
90
        memcpy_toio(map->map_priv_1 + to, from, len);
91
}
92
 
93
struct map_info uflash_map_templ = {
94
                name:           "SUNW,???-????",
95
                size:           UFLASH_WINDOW_SIZE,
96
                buswidth:       UFLASH_BUSWIDTH,
97
                read8:          uflash_read8,
98
                read16:         uflash_read16,
99
                read32:         uflash_read32,
100
                copy_from:      uflash_copy_from,
101
                write8:         uflash_write8,
102
                write16:        uflash_write16,
103
                write32:        uflash_write32,
104
                copy_to:        uflash_copy_to
105
};
106
 
107
int uflash_devinit(struct linux_ebus_device* edev)
108
{
109
        int iTmp, nregs;
110
        struct linux_prom_registers regs[2];
111
        struct uflash_dev *pdev;
112
 
113
        iTmp = prom_getproperty(
114
                edev->prom_node, "reg", (void *)regs, sizeof(regs));
115
        if ((iTmp % sizeof(regs[0])) != 0) {
116
                printk("%s: Strange reg property size %d\n",
117
                        UFLASH_DEVNAME, iTmp);
118
                return -ENODEV;
119
        }
120
 
121
        nregs = iTmp / sizeof(regs[0]);
122
 
123
        if (nregs != 1) {
124
                /* Non-CFI userflash device-- once I find one we
125
                 * can work on supporting it.
126
                 */
127
                printk("%s: unsupported device at 0x%lx (%d regs): " \
128
                        "email ebrower@usa.net\n",
129
                        UFLASH_DEVNAME, edev->resource[0].start, nregs);
130
                return -ENODEV;
131
        }
132
 
133
        if(0 == (pdev = kmalloc(sizeof(struct uflash_dev), GFP_KERNEL))) {
134
                printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME);
135
                return(-ENOMEM);
136
        }
137
 
138
        /* copy defaults and tweak parameters */
139
        memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ));
140
        pdev->map.size = regs[0].reg_size;
141
 
142
        iTmp = prom_getproplen(edev->prom_node, "model");
143
        pdev->name = kmalloc(iTmp, GFP_KERNEL);
144
        prom_getstring(edev->prom_node, "model", pdev->name, iTmp);
145
        if(0 != pdev->name && 0 < strlen(pdev->name)) {
146
                pdev->map.name = pdev->name;
147
        }
148
 
149
        pdev->map.map_priv_1 =
150
                (unsigned long)ioremap_nocache(edev->resource[0].start, pdev->map.size);
151
        if(0 == pdev->map.map_priv_1) {
152
                printk("%s: failed to map device\n", __FUNCTION__);
153
                kfree(pdev->name);
154
                kfree(pdev);
155
                return(-1);
156
        }
157
 
158
        /* MTD registration */
159
        pdev->mtd = do_map_probe("cfi_probe", &pdev->map);
160
        if(0 == pdev->mtd) {
161
                iounmap((void *)pdev->map.map_priv_1);
162
                kfree(pdev->name);
163
                kfree(pdev);
164
                return(-ENXIO);
165
        }
166
 
167
        list_add(&pdev->list, &device_list);
168
 
169
        pdev->mtd->module = THIS_MODULE;
170
 
171
        add_mtd_device(pdev->mtd);
172
        return(0);
173
}
174
 
175
static int __init uflash_init(void)
176
{
177
        struct linux_ebus *ebus = NULL;
178
        struct linux_ebus_device *edev = NULL;
179
 
180
        for_each_ebus(ebus) {
181
                for_each_ebusdev(edev, ebus) {
182
                        if (!strcmp(edev->prom_name, UFLASH_OBPNAME)) {
183
                                if(0 > prom_getproplen(edev->prom_node, "user")) {
184
                                        DEBUG(2, "%s: ignoring device at 0x%lx\n",
185
                                                        UFLASH_DEVNAME, edev->resource[0].start);
186
                                } else {
187
                                        uflash_devinit(edev);
188
                                }
189
                        }
190
                }
191
        }
192
 
193
        if(list_empty(&device_list)) {
194
                printk("%s: unable to locate device\n", UFLASH_DEVNAME);
195
                return -ENODEV;
196
        }
197
        return(0);
198
}
199
 
200
static void __exit uflash_cleanup(void)
201
{
202
        struct list_head *udevlist;
203
        struct uflash_dev *udev;
204
 
205
        list_for_each(udevlist, &device_list) {
206
                udev = list_entry(udevlist, struct uflash_dev, list);
207
                DEBUG(2, "%s: removing device %s\n",
208
                        UFLASH_DEVNAME, udev->name);
209
 
210
                if(0 != udev->mtd) {
211
                        del_mtd_device(udev->mtd);
212
                        map_destroy(udev->mtd);
213
                }
214
                if(0 != udev->map.map_priv_1) {
215
                        iounmap((void*)udev->map.map_priv_1);
216
                        udev->map.map_priv_1 = 0;
217
                }
218
                if(0 != udev->name) {
219
                        kfree(udev->name);
220
                }
221
                kfree(udev);
222
        }
223
}
224
 
225
module_init(uflash_init);
226
module_exit(uflash_cleanup);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.