Version:  2.0.40 2.2.26 2.4.37 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17

Linux/drivers/mtd/maps/sun_uflash.c

  1 /* sun_uflash.c - Driver for user-programmable flash on
  2  *                Sun Microsystems SME boardsets.
  3  *
  4  * This driver does NOT provide access to the OBP-flash for
  5  * safety reasons-- use <linux>/drivers/sbus/char/flash.c instead.
  6  *
  7  * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
  8  */
  9 
 10 #include <linux/kernel.h>
 11 #include <linux/module.h>
 12 #include <linux/fs.h>
 13 #include <linux/errno.h>
 14 #include <linux/ioport.h>
 15 #include <linux/of.h>
 16 #include <linux/of_device.h>
 17 #include <linux/slab.h>
 18 #include <asm/prom.h>
 19 #include <asm/uaccess.h>
 20 #include <asm/io.h>
 21 
 22 #include <linux/mtd/mtd.h>
 23 #include <linux/mtd/map.h>
 24 
 25 #define UFLASH_OBPNAME  "flashprom"
 26 #define DRIVER_NAME     "sun_uflash"
 27 #define PFX             DRIVER_NAME ": "
 28 
 29 #define UFLASH_WINDOW_SIZE      0x200000
 30 #define UFLASH_BUSWIDTH         1                       /* EBus is 8-bit */
 31 
 32 MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
 33 MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets");
 34 MODULE_SUPPORTED_DEVICE(DRIVER_NAME);
 35 MODULE_LICENSE("GPL");
 36 MODULE_VERSION("2.1");
 37 
 38 struct uflash_dev {
 39         const char              *name;  /* device name */
 40         struct map_info         map;    /* mtd map info */
 41         struct mtd_info         *mtd;   /* mtd info */
 42 };
 43 
 44 struct map_info uflash_map_templ = {
 45         .name =         "SUNW,???-????",
 46         .size =         UFLASH_WINDOW_SIZE,
 47         .bankwidth =    UFLASH_BUSWIDTH,
 48 };
 49 
 50 int uflash_devinit(struct platform_device *op, struct device_node *dp)
 51 {
 52         struct uflash_dev *up;
 53 
 54         if (op->resource[1].flags) {
 55                 /* Non-CFI userflash device-- once I find one we
 56                  * can work on supporting it.
 57                  */
 58                 printk(KERN_ERR PFX "Unsupported device at %s, 0x%llx\n",
 59                        dp->full_name, (unsigned long long)op->resource[0].start);
 60 
 61                 return -ENODEV;
 62         }
 63 
 64         up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL);
 65         if (!up) {
 66                 printk(KERN_ERR PFX "Cannot allocate struct uflash_dev\n");
 67                 return -ENOMEM;
 68         }
 69 
 70         /* copy defaults and tweak parameters */
 71         memcpy(&up->map, &uflash_map_templ, sizeof(uflash_map_templ));
 72 
 73         up->map.size = resource_size(&op->resource[0]);
 74 
 75         up->name = of_get_property(dp, "model", NULL);
 76         if (up->name && 0 < strlen(up->name))
 77                 up->map.name = up->name;
 78 
 79         up->map.phys = op->resource[0].start;
 80 
 81         up->map.virt = of_ioremap(&op->resource[0], 0, up->map.size,
 82                                   DRIVER_NAME);
 83         if (!up->map.virt) {
 84                 printk(KERN_ERR PFX "Failed to map device.\n");
 85                 kfree(up);
 86 
 87                 return -EINVAL;
 88         }
 89 
 90         simple_map_init(&up->map);
 91 
 92         /* MTD registration */
 93         up->mtd = do_map_probe("cfi_probe", &up->map);
 94         if (!up->mtd) {
 95                 of_iounmap(&op->resource[0], up->map.virt, up->map.size);
 96                 kfree(up);
 97 
 98                 return -ENXIO;
 99         }
100 
101         up->mtd->owner = THIS_MODULE;
102 
103         mtd_device_register(up->mtd, NULL, 0);
104 
105         dev_set_drvdata(&op->dev, up);
106 
107         return 0;
108 }
109 
110 static int uflash_probe(struct platform_device *op)
111 {
112         struct device_node *dp = op->dev.of_node;
113 
114         /* Flashprom must have the "user" property in order to
115          * be used by this driver.
116          */
117         if (!of_find_property(dp, "user", NULL))
118                 return -ENODEV;
119 
120         return uflash_devinit(op, dp);
121 }
122 
123 static int uflash_remove(struct platform_device *op)
124 {
125         struct uflash_dev *up = dev_get_drvdata(&op->dev);
126 
127         if (up->mtd) {
128                 mtd_device_unregister(up->mtd);
129                 map_destroy(up->mtd);
130         }
131         if (up->map.virt) {
132                 of_iounmap(&op->resource[0], up->map.virt, up->map.size);
133                 up->map.virt = NULL;
134         }
135 
136         kfree(up);
137 
138         return 0;
139 }
140 
141 static const struct of_device_id uflash_match[] = {
142         {
143                 .name = UFLASH_OBPNAME,
144         },
145         {},
146 };
147 
148 MODULE_DEVICE_TABLE(of, uflash_match);
149 
150 static struct platform_driver uflash_driver = {
151         .driver = {
152                 .name = DRIVER_NAME,
153                 .owner = THIS_MODULE,
154                 .of_match_table = uflash_match,
155         },
156         .probe          = uflash_probe,
157         .remove         = uflash_remove,
158 };
159 
160 module_platform_driver(uflash_driver);
161 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us