1 /* $Id: sun_uflash.c,v 1.13 2005/11/07 11:14:28 gleixner Exp $
3 * sun_uflash - Driver implementation for user-programmable flash
4 * present on many Sun Microsystems SME boardsets.
6 * This driver does NOT provide access to the OBP-flash for
7 * safety reasons-- use <linux>/drivers/sbus/char/flash.c instead.
9 * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
13 #include <linux/kernel.h>
14 #include <linux/module.h>
16 #include <linux/errno.h>
17 #include <linux/init.h>
18 #include <linux/ioport.h>
20 #include <asm/oplib.h>
22 #include <asm/uaccess.h>
25 #include <linux/mtd/mtd.h>
26 #include <linux/mtd/map.h>
28 #define UFLASH_OBPNAME "flashprom"
29 #define UFLASH_DEVNAME "userflash"
31 #define UFLASH_WINDOW_SIZE 0x200000
32 #define UFLASH_BUSWIDTH 1 /* EBus is 8-bit */
34 MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
35 MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets");
36 MODULE_SUPPORTED_DEVICE("userflash");
37 MODULE_LICENSE("GPL");
38 MODULE_VERSION("2.0");
40 static LIST_HEAD(device_list
);
42 char *name
; /* device name */
43 struct map_info map
; /* mtd map info */
44 struct mtd_info
*mtd
; /* mtd info */
48 struct map_info uflash_map_templ
= {
49 .name
= "SUNW,???-????",
50 .size
= UFLASH_WINDOW_SIZE
,
51 .bankwidth
= UFLASH_BUSWIDTH
,
54 int uflash_devinit(struct linux_ebus_device
*edev
, struct device_node
*dp
)
56 struct uflash_dev
*up
;
59 res
= &edev
->resource
[0];
61 if (edev
->num_addrs
!= 1) {
62 /* Non-CFI userflash device-- once I find one we
63 * can work on supporting it.
65 printk("%s: unsupported device at 0x%llx (%d regs): " \
66 "email ebrower@usa.net\n",
67 dp
->full_name
, (unsigned long long)res
->start
,
73 up
= kzalloc(sizeof(struct uflash_dev
), GFP_KERNEL
);
77 /* copy defaults and tweak parameters */
78 memcpy(&up
->map
, &uflash_map_templ
, sizeof(uflash_map_templ
));
79 up
->map
.size
= (res
->end
- res
->start
) + 1UL;
81 up
->name
= of_get_property(dp
, "model", NULL
);
82 if (up
->name
&& 0 < strlen(up
->name
))
83 up
->map
.name
= up
->name
;
85 up
->map
.phys
= res
->start
;
87 up
->map
.virt
= ioremap_nocache(res
->start
, up
->map
.size
);
89 printk("%s: Failed to map device.\n", dp
->full_name
);
95 simple_map_init(&up
->map
);
97 /* MTD registration */
98 up
->mtd
= do_map_probe("cfi_probe", &up
->map
);
100 iounmap(up
->map
.virt
);
106 up
->mtd
->owner
= THIS_MODULE
;
108 add_mtd_device(up
->mtd
);
110 dev_set_drvdata(&edev
->ofdev
.dev
, up
);
115 static int __devinit
uflash_probe(struct of_device
*dev
, const struct of_device_id
*match
)
117 struct linux_ebus_device
*edev
= to_ebus_device(&dev
->dev
);
118 struct device_node
*dp
= dev
->node
;
120 if (of_find_property(dp
, "user", NULL
))
123 return uflash_devinit(edev
, dp
);
126 static int __devexit
uflash_remove(struct of_device
*dev
)
128 struct uflash_dev
*up
= dev_get_drvdata(&dev
->dev
);
131 del_mtd_device(up
->mtd
);
132 map_destroy(up
->mtd
);
135 iounmap(up
->map
.virt
);
144 static struct of_device_id uflash_match
[] = {
146 .name
= UFLASH_OBPNAME
,
151 MODULE_DEVICE_TABLE(of
, uflash_match
);
153 static struct of_platform_driver uflash_driver
= {
154 .name
= UFLASH_DEVNAME
,
155 .match_table
= uflash_match
,
156 .probe
= uflash_probe
,
157 .remove
= __devexit_p(uflash_remove
),
160 static int __init
uflash_init(void)
162 return of_register_driver(&uflash_driver
, &ebus_bus_type
);
165 static void __exit
uflash_exit(void)
167 of_unregister_driver(&uflash_driver
);
170 module_init(uflash_init
);
171 module_exit(uflash_exit
);