1 /* sun_uflash.c - Driver for user-programmable flash on
2 * Sun Microsystems SME boardsets.
4 * This driver does NOT provide access to the OBP-flash for
5 * safety reasons-- use <linux>/drivers/sbus/char/flash.c instead.
7 * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
10 #include <linux/kernel.h>
11 #include <linux/module.h>
13 #include <linux/errno.h>
14 #include <linux/init.h>
15 #include <linux/ioport.h>
17 #include <linux/of_device.h>
18 #include <linux/slab.h>
20 #include <asm/uaccess.h>
23 #include <linux/mtd/mtd.h>
24 #include <linux/mtd/map.h>
26 #define UFLASH_OBPNAME "flashprom"
27 #define DRIVER_NAME "sun_uflash"
28 #define PFX DRIVER_NAME ": "
30 #define UFLASH_WINDOW_SIZE 0x200000
31 #define UFLASH_BUSWIDTH 1 /* EBus is 8-bit */
33 MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
34 MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets");
35 MODULE_SUPPORTED_DEVICE(DRIVER_NAME
);
36 MODULE_LICENSE("GPL");
37 MODULE_VERSION("2.1");
40 const char *name
; /* device name */
41 struct map_info map
; /* mtd map info */
42 struct mtd_info
*mtd
; /* mtd info */
45 struct map_info uflash_map_templ
= {
46 .name
= "SUNW,???-????",
47 .size
= UFLASH_WINDOW_SIZE
,
48 .bankwidth
= UFLASH_BUSWIDTH
,
51 int uflash_devinit(struct of_device
*op
, struct device_node
*dp
)
53 struct uflash_dev
*up
;
55 if (op
->resource
[1].flags
) {
56 /* Non-CFI userflash device-- once I find one we
57 * can work on supporting it.
59 printk(KERN_ERR PFX
"Unsupported device at %s, 0x%llx\n",
60 dp
->full_name
, (unsigned long long)op
->resource
[0].start
);
65 up
= kzalloc(sizeof(struct uflash_dev
), GFP_KERNEL
);
67 printk(KERN_ERR PFX
"Cannot allocate struct uflash_dev\n");
71 /* copy defaults and tweak parameters */
72 memcpy(&up
->map
, &uflash_map_templ
, sizeof(uflash_map_templ
));
74 up
->map
.size
= resource_size(&op
->resource
[0]);
76 up
->name
= of_get_property(dp
, "model", NULL
);
77 if (up
->name
&& 0 < strlen(up
->name
))
78 up
->map
.name
= (char *)up
->name
;
80 up
->map
.phys
= op
->resource
[0].start
;
82 up
->map
.virt
= of_ioremap(&op
->resource
[0], 0, up
->map
.size
,
85 printk(KERN_ERR PFX
"Failed to map device.\n");
91 simple_map_init(&up
->map
);
93 /* MTD registration */
94 up
->mtd
= do_map_probe("cfi_probe", &up
->map
);
96 of_iounmap(&op
->resource
[0], up
->map
.virt
, up
->map
.size
);
102 up
->mtd
->owner
= THIS_MODULE
;
104 add_mtd_device(up
->mtd
);
106 dev_set_drvdata(&op
->dev
, up
);
111 static int __devinit
uflash_probe(struct of_device
*op
, const struct of_device_id
*match
)
113 struct device_node
*dp
= op
->dev
.of_node
;
115 /* Flashprom must have the "user" property in order to
116 * be used by this driver.
118 if (!of_find_property(dp
, "user", NULL
))
121 return uflash_devinit(op
, dp
);
124 static int __devexit
uflash_remove(struct of_device
*op
)
126 struct uflash_dev
*up
= dev_get_drvdata(&op
->dev
);
129 del_mtd_device(up
->mtd
);
130 map_destroy(up
->mtd
);
133 of_iounmap(&op
->resource
[0], up
->map
.virt
, up
->map
.size
);
142 static const struct of_device_id uflash_match
[] = {
144 .name
= UFLASH_OBPNAME
,
149 MODULE_DEVICE_TABLE(of
, uflash_match
);
151 static struct of_platform_driver uflash_driver
= {
154 .owner
= THIS_MODULE
,
155 .of_match_table
= uflash_match
,
157 .probe
= uflash_probe
,
158 .remove
= __devexit_p(uflash_remove
),
161 static int __init
uflash_init(void)
163 return of_register_platform_driver(&uflash_driver
);
166 static void __exit
uflash_exit(void)
168 of_unregister_platform_driver(&uflash_driver
);
171 module_init(uflash_init
);
172 module_exit(uflash_exit
);